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
074 .getService(
075 "tapestry.portlet.PortletApplicationInitializer",
076 PortletApplicationInitializer.class);
077
078 initializer.initialize(config);
079
080 _actionRequestServicer = (ActionRequestServicer) _registry.getService(
081 "tapestry.portlet.ActionRequestServicer",
082 ActionRequestServicer.class);
083
084 _renderRequestServicer = (RenderRequestServicer) _registry.getService(
085 "tapestry.portlet.RenderRequestServicer",
086 RenderRequestServicer.class);
087 }
088
089 /**
090 * Constructs the Registry. The Registry is constructed from the classpath, plus two optional
091 * files:
092 * <ul>
093 * <li>WEB-INF/ <em>name</em> /hivemodule.xml</li>
094 * <li>WEB-INF/hivemodule.xml</li>
095 * </ul>.
096 * <p>
097 * Where <em>name</em> is the name of the portlet.
098 */
099
100 protected Registry constructRegistry(PortletConfig config)
101 {
102 RegistryBuilder builder = new RegistryBuilder();
103
104 ClassResolver resolver = new DefaultClassResolver();
105
106 builder.addModuleDescriptorProvider(new XmlModuleDescriptorProvider(resolver));
107
108 String name = config.getPortletName();
109 WebContext context = new PortletWebContext(config.getPortletContext());
110
111 addModuleIfExists(builder, resolver, context, "/WEB-INF/" + name + "/hivemodule.xml");
112 addModuleIfExists(builder, resolver, context, "/WEB-INF/hivemodule.xml");
113
114 return builder.constructRegistry(Locale.getDefault());
115 }
116
117 /**
118 * Looks for a file in the context; if it exists, it is expected to be a HiveMind module
119 * descriptor, and is added to the builder.
120 *
121 * @since 4.0
122 */
123
124 protected void addModuleIfExists(RegistryBuilder builder, ClassResolver resolver,
125 WebContext context, String path)
126 {
127 Resource r = new WebContextResource(context, path);
128
129 if (r.getResourceURL() == null)
130 return;
131
132 builder.addModuleDescriptorProvider(new XmlModuleDescriptorProvider(resolver, r));
133 }
134
135 public void processAction(ActionRequest request, ActionResponse response)
136 throws PortletException, IOException
137 {
138 try
139 {
140 _registry.setupThread();
141
142 _actionRequestServicer.service(request, response);
143 }
144 catch (RuntimeException ex)
145 {
146 throw new PortletException(PortletMessages.errorProcessingAction(ex), ex);
147 }
148 finally
149 {
150 _registry.cleanupThread();
151 }
152 }
153
154 public void render(RenderRequest request, RenderResponse response) throws PortletException,
155 IOException
156 {
157 try
158 {
159 _registry.setupThread();
160
161 _renderRequestServicer.service(request, response);
162 }
163 catch (RuntimeException ex)
164 {
165 throw new PortletException(PortletMessages.errorProcessingRender(ex), ex);
166 }
167 finally
168 {
169 _registry.cleanupThread();
170 }
171 }
172 }