View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.jetspeed.container.invoker;
18  
19  import java.io.IOException;
20  
21  import javax.portlet.ActionRequest;
22  import javax.portlet.ActionResponse;
23  import javax.portlet.PortletException;
24  import javax.portlet.PortletRequest;
25  import javax.portlet.PortletResponse;
26  import javax.portlet.RenderRequest;
27  import javax.portlet.RenderResponse;
28  import javax.portlet.UnavailableException;
29  import javax.servlet.ServletConfig;
30  import javax.servlet.ServletContext;
31  import javax.servlet.ServletRequest;
32  
33  import org.apache.commons.logging.Log;
34  import org.apache.commons.logging.LogFactory;
35  import org.apache.jetspeed.PortalReservedParameters;
36  import org.apache.jetspeed.container.ContainerConstants;
37  import org.apache.jetspeed.container.PortletRequestContext;
38  import org.apache.jetspeed.factory.PortletFactory;
39  import org.apache.jetspeed.factory.PortletInstance;
40  import org.apache.jetspeed.om.common.portlet.PortletApplication;
41  import org.apache.jetspeed.request.RequestContext;
42  import org.apache.pluto.om.portlet.PortletDefinition;
43  
44  /***
45   * LocalPortletInvoker invokes local (internal) portlet applications.
46   * Local portlet applications are stored within the Jetspeed Portlet application.
47   * They are not separate web applications; but are stored under Jetspeed's
48   * WEB-INF/apps directory.
49   * <h3>Sample Configuration</h3>
50   * <pre>
51   * <code>
52   * factory.invoker.local = org.apache.jetspeed.container.invoker.LocalPortletInvoker
53   * factory.invoker.local.pool.size = 50
54   * </code> 
55   * </pre>
56   * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
57   * @version $Id: LocalPortletInvoker.java 565870 2007-08-14 19:40:03Z taylor $
58   */
59  public class LocalPortletInvoker implements JetspeedPortletInvoker
60  {
61      private final static Log log = LogFactory.getLog(LocalPortletInvoker.class);
62  
63      protected PortletFactory portletFactory;
64      protected ServletContext jetspeedContext;
65      protected ServletConfig jetspeedConfig;
66      protected PortletDefinition portletDefinition;
67      protected boolean activated = false;
68      
69      /* (non-Javadoc)
70       * @see org.apache.jetspeed.container.invoker.JetspeedPortletInvoker#activate(PortletFactory,org.apache.pluto.om.portlet.PortletDefinition, javax.servlet.ServletConfig)
71       */
72      public void activate(PortletFactory portletFactory, PortletDefinition portletDefinition, ServletConfig servletConfig)
73      {
74          this.portletFactory = portletFactory;
75          this.jetspeedConfig = servletConfig;
76          jetspeedContext = servletConfig.getServletContext();
77          this.portletDefinition = portletDefinition;
78          activated = true;        
79      }
80  
81      /* (non-Javadoc)
82       * @see org.apache.jetspeed.container.invoker.JetspeedPortletInvoker#passivate()
83       */
84      public void passivate()
85      {
86          activated = false;    
87      }
88      
89      /* (non-Javadoc)
90       * @see org.apache.jetspeed.container.invoker.JetspeedPortletInvoker#isActivated()
91       */
92      public boolean isActivated()
93      {
94          return activated;
95      }
96      
97      public LocalPortletInvoker()
98      {
99          activated = false;
100     }
101     
102     /* (non-Javadoc)
103      * @see org.apache.pluto.invoker.PortletInvoker#action(javax.portlet.ActionRequest, javax.portlet.ActionResponse)
104      */
105     public void action(ActionRequest request, ActionResponse response)
106         throws PortletException, IOException
107     {
108         invoke(request, response, ContainerConstants.METHOD_ACTION);
109     }
110     
111     /* (non-Javadoc)
112      * @see org.apache.pluto.invoker.PortletInvoker#render(javax.portlet.RenderRequest, javax.portlet.RenderResponse)
113      */
114     public void render(RenderRequest request, RenderResponse response)
115         throws PortletException, IOException
116     {
117         invoke(request, response, ContainerConstants.METHOD_RENDER);
118     }
119     
120     /* (non-Javadoc)
121      * @see org.apache.pluto.invoker.PortletInvoker#load(javax.portlet.PortletRequest, javax.portlet.RenderResponse)
122      */
123     public void load(PortletRequest request, RenderResponse response)
124         throws PortletException
125     {
126         try
127         {
128             invoke(request, response, ContainerConstants.METHOD_NOOP);
129         }
130         catch (IOException e)
131         {
132             log.error("LocalPortletInvokerImpl.load() - Error while dispatching portlet.", e);
133             throw new PortletException(e);
134         }
135     }
136     
137     
138     /***
139      * Invokes the specific request denoted by the <code>method</code> parameter on a portlet.
140      * The portlet is invoked with a direct method call on the portlet. It is not invoked in another web application.
141      * This requires manipulation of the current thread's classpath.
142      * 
143      * @param portletRequest
144      * @param portletResponse
145      * @param methodID
146      * @throws PortletException
147      * @throws IOException
148      */
149     protected void invoke(PortletRequest portletRequest, PortletResponse portletResponse, Integer method)
150             throws PortletException, IOException
151     {
152         ClassLoader paClassLoader = portletFactory
153                 .getPortletApplicationClassLoader((PortletApplication) portletDefinition
154                         .getPortletApplicationDefinition());
155         PortletInstance portletInstance = portletFactory.getPortletInstance(jetspeedContext, portletDefinition);
156 
157         if (method == ContainerConstants.METHOD_NOOP)
158         {
159             return;
160         }
161 
162         // gather all required data from request and response
163         ServletRequest servletRequest = ((javax.servlet.http.HttpServletRequestWrapper) portletRequest).getRequest();
164 
165         ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
166         try
167         {
168             PortletRequestContext.createContext(portletDefinition, portletInstance, portletRequest, portletResponse);
169 
170             servletRequest.setAttribute(ContainerConstants.PORTLET_CONFIG, portletInstance.getConfig());
171             servletRequest.setAttribute(ContainerConstants.PORTLET_REQUEST, portletRequest);
172             servletRequest.setAttribute(ContainerConstants.PORTLET_RESPONSE, portletResponse);
173             RequestContext requestContext = (RequestContext) servletRequest
174                     .getAttribute(PortalReservedParameters.REQUEST_CONTEXT_ATTRIBUTE);
175             servletRequest
176                     .setAttribute(ContainerConstants.PORTAL_CONTEXT, requestContext.getRequest().getContextPath());
177 
178             Thread.currentThread().setContextClassLoader(paClassLoader);
179 
180             if (method == ContainerConstants.METHOD_ACTION)
181             {
182                 ActionRequest actionRequest = (ActionRequest) portletRequest;
183                 ActionResponse actionResponse = (ActionResponse) portletResponse;
184 
185                 portletInstance.processAction(actionRequest, actionResponse);
186             }
187             else if (method == ContainerConstants.METHOD_RENDER)
188             {
189                 RenderRequest renderRequest = (RenderRequest) portletRequest;
190                 RenderResponse renderResponse = (RenderResponse) portletResponse;
191                 renderResponse.setContentType(requestContext.getMimeType());
192                 portletInstance.render(renderRequest, renderResponse);
193             }
194         }
195         catch (Throwable t)
196         {
197             if ( t instanceof UnavailableException )
198             {
199                 // take it out of service
200                 try
201                 {
202                     portletInstance.destroy();
203                 }
204                 catch (Throwable ignore)
205                 {
206                     // never mind, it won't be used anymore
207                 }
208             }
209             if ( t instanceof PortletException )
210             {
211                 throw (PortletException)t;
212             }
213             if ( t instanceof IOException )
214             {
215                 throw (IOException)t;
216             }
217             else
218             {
219                 throw new PortletException(t);
220             }
221         }
222         finally
223         {
224             PortletRequestContext.clearContext();
225             servletRequest.removeAttribute(ContainerConstants.PORTLET_CONFIG);
226             servletRequest.removeAttribute(ContainerConstants.PORTLET_REQUEST);
227             servletRequest.removeAttribute(ContainerConstants.PORTLET_RESPONSE);
228             servletRequest.removeAttribute(ContainerConstants.PORTAL_CONTEXT);
229 
230             Thread.currentThread().setContextClassLoader(oldLoader);
231         }
232     }
233 
234     /* (non-Javadoc)
235      * @see org.apache.jetspeed.container.invoker.JetspeedPortletInvoker#activate(PortletFactory,org.apache.pluto.om.portlet.PortletDefinition, javax.servlet.ServletConfig, java.lang.String)
236      */
237     public void activate(PortletFactory portletFactory, PortletDefinition portletDefinition, ServletConfig servletConfig, String servletMappingName)
238     {
239         activate(portletFactory, portletDefinition, servletConfig);
240     }
241     
242 }