001 // Copyright 2005 The Apache Software Foundation
002 //
003 // Licensed under the Apache License, Version 2.0 (the "License");
004 // you may not use this file except in compliance with the License.
005 // You may obtain a copy of the License at
006 //
007 // http://www.apache.org/licenses/LICENSE-2.0
008 //
009 // Unless required by applicable law or agreed to in writing, software
010 // distributed under the License is distributed on an "AS IS" BASIS,
011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012 // See the License for the specific language governing permissions and
013 // limitations under the License.
014
015 package org.apache.tapestry.portlet;
016
017 import java.io.IOException;
018 import java.util.Locale;
019
020 import javax.portlet.ActionRequest;
021 import javax.portlet.ActionResponse;
022 import javax.portlet.Portlet;
023 import javax.portlet.PortletConfig;
024 import javax.portlet.PortletException;
025 import javax.portlet.RenderRequest;
026 import javax.portlet.RenderResponse;
027
028 import org.apache.hivemind.ClassResolver;
029 import org.apache.hivemind.Registry;
030 import org.apache.hivemind.Resource;
031 import org.apache.hivemind.impl.DefaultClassResolver;
032 import org.apache.hivemind.impl.RegistryBuilder;
033 import org.apache.hivemind.impl.XmlModuleDescriptorProvider;
034 import org.apache.tapestry.web.WebContext;
035 import org.apache.tapestry.web.WebContextResource;
036
037 /**
038 * Portlet implementation for Tapestry Portlet applilcations. It's job is to create and manage the
039 * HiveMind registry, to use the <code>tapestry.portlet.PortletApplicationInitializer</code>
040 * service to initialize HiveMind, and the delegate requests to the
041 * <code>tapestry.portlet.ActionRequestServicer</code> and
042 * <code>tapestry.portlet.RenderRequestServicer</code> services.
043 *
044 * @author Howard M. Lewis Ship
045 * @since 4.0
046 */
047 public class ApplicationPortlet implements Portlet
048 {
049 Registry _registry;
050
051 ActionRequestServicer _actionRequestServicer;
052
053 RenderRequestServicer _renderRequestServicer;
054
055 public void destroy()
056 {
057 try
058 {
059 _registry.shutdown();
060 }
061 finally
062 {
063 _registry = null;
064 _actionRequestServicer = null;
065 _renderRequestServicer = null;
066 }
067 }
068
069 public void init(PortletConfig config) throws PortletException
070 {
071 _registry = constructRegistry(config);
072
073 PortletApplicationInitializer initializer = (PortletApplicationInitializer) _registry.getService(
074 "tapestry.portlet.PortletApplicationInitializer",
075 PortletApplicationInitializer.class);
076
077 initializer.initialize(config);
078
079 _actionRequestServicer = (ActionRequestServicer) _registry.getService(
080 "tapestry.portlet.ActionRequestServicer",
081 ActionRequestServicer.class);
082
083 _renderRequestServicer = (RenderRequestServicer) _registry.getService(
084 "tapestry.portlet.RenderRequestServicer",
085 RenderRequestServicer.class);
086 }
087
088 /**
089 * Constructs the Registry. The Registry is constructed from the classpath, plus two optional
090 * files:
091 * <ul>
092 * <li>WEB-INF/ <em>name</em> /hivemodule.xml</li>
093 * <li>WEB-INF/hivemodule.xml</li>
094 * </ul>.
095 * <p>
096 * Where <em>name</em> is the name of the portlet.
097 */
098
099 protected Registry constructRegistry(PortletConfig config)
100 {
101 RegistryBuilder builder = new RegistryBuilder();
102
103 ClassResolver resolver = new DefaultClassResolver();
104
105 builder.addModuleDescriptorProvider(new XmlModuleDescriptorProvider(resolver));
106
107 String name = config.getPortletName();
108 WebContext context = new PortletWebContext(config.getPortletContext());
109
110 addModuleIfExists(builder, resolver, context, "/WEB-INF/" + name + "/hivemodule.xml");
111 addModuleIfExists(builder, resolver, context, "/WEB-INF/hivemodule.xml");
112
113 return builder.constructRegistry(Locale.getDefault());
114 }
115
116 /**
117 * Looks for a file in the context; if it exists, it is expected to be a HiveMind module
118 * descriptor, and is added to the builder.
119 *
120 * @since 4.0
121 */
122
123 protected void addModuleIfExists(RegistryBuilder builder, ClassResolver resolver,
124 WebContext context, String path)
125 {
126 Resource r = new WebContextResource(context, path);
127
128 if (r.getResourceURL() == null)
129 return;
130
131 builder.addModuleDescriptorProvider(new XmlModuleDescriptorProvider(resolver, r));
132 }
133
134 public void processAction(ActionRequest request, ActionResponse response)
135 throws PortletException, IOException
136 {
137 try
138 {
139 _registry.setupThread();
140
141 _actionRequestServicer.service(request, response);
142 }
143 catch (RuntimeException ex)
144 {
145 throw new PortletException(PortletMessages.errorProcessingAction(ex), ex);
146 }
147 finally
148 {
149 _registry.cleanupThread();
150 }
151 }
152
153 public void render(RenderRequest request, RenderResponse response) throws PortletException,
154 IOException
155 {
156 try
157 {
158 _registry.setupThread();
159
160 _renderRequestServicer.service(request, response);
161 }
162 catch (RuntimeException ex)
163 {
164 throw new PortletException(PortletMessages.errorProcessingRender(ex), ex);
165 }
166 finally
167 {
168 _registry.cleanupThread();
169 }
170 }
171 }