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 015package org.apache.tapestry.portlet; 016 017import java.io.IOException; 018import java.util.Locale; 019 020import javax.portlet.ActionRequest; 021import javax.portlet.ActionResponse; 022import javax.portlet.Portlet; 023import javax.portlet.PortletConfig; 024import javax.portlet.PortletException; 025import javax.portlet.RenderRequest; 026import javax.portlet.RenderResponse; 027 028import org.apache.hivemind.ClassResolver; 029import org.apache.hivemind.Registry; 030import org.apache.hivemind.Resource; 031import org.apache.hivemind.impl.DefaultClassResolver; 032import org.apache.hivemind.impl.RegistryBuilder; 033import org.apache.hivemind.impl.XmlModuleDescriptorProvider; 034import org.apache.tapestry.web.WebContext; 035import 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 */ 047public 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}