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 }