View Javadoc
1   /*
2    * Copyright (c) 2002-2017, Mairie de Paris
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met:
8    *
9    *  1. Redistributions of source code must retain the above copyright notice
10   *     and the following disclaimer.
11   *
12   *  2. Redistributions in binary form must reproduce the above copyright notice
13   *     and the following disclaimer in the documentation and/or other materials
14   *     provided with the distribution.
15   *
16   *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
17   *     contributors may be used to endorse or promote products derived from
18   *     this software without specific prior written permission.
19   *
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   * POSSIBILITY OF SUCH DAMAGE.
31   *
32   * License 1.0
33   */
34  /*
35   * Copyright 2003,2004 The Apache Software Foundation.
36   *
37   * Licensed under the Apache License, Version 2.0 (the "License");
38   * you may not use this file except in compliance with the License.
39   * You may obtain a copy of the License at
40   *
41   *      http://www.apache.org/licenses/LICENSE-2.0
42   *
43   * Unless required by applicable law or agreed to in writing, software
44   * distributed under the License is distributed on an "AS IS" BASIS,
45   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
46   * See the License for the specific language governing permissions and
47   * limitations under the License.
48   */
49  package fr.paris.lutece.plugins.jsr168.pluto;
50  
51  import fr.paris.lutece.plugins.jsr168.pluto.core.PortletURLProviderImpl;
52  
53  import org.apache.pluto.PortletContainer;
54  import org.apache.pluto.PortletContainerServices;
55  import org.apache.pluto.core.InternalActionResponse;
56  import org.apache.pluto.factory.PortletObjectAccess;
57  import org.apache.pluto.invoker.PortletInvoker;
58  import org.apache.pluto.invoker.PortletInvokerAccess;
59  import org.apache.pluto.om.window.PortletWindow;
60  import org.apache.pluto.portalImpl.om.window.impl.PortletWindowImpl;
61  import org.apache.pluto.services.PortletContainerEnvironment;
62  import org.apache.pluto.services.information.InformationProviderAccess;
63  import org.apache.pluto.services.log.LogService;
64  import org.apache.pluto.services.log.Logger;
65  
66  import java.io.IOException;
67  
68  import java.util.Map;
69  import java.util.Properties;
70  
71  import javax.portlet.ActionRequest;
72  import javax.portlet.ActionResponse;
73  import javax.portlet.PortletException;
74  import javax.portlet.RenderRequest;
75  import javax.portlet.RenderResponse;
76  
77  import javax.servlet.ServletConfig;
78  import javax.servlet.http.HttpServletRequest;
79  import javax.servlet.http.HttpServletResponse;
80  import javax.servlet.http.HttpServletResponseWrapper;
81  
82  
83  /**
84   * Portlet Pluto container.<b>
85   *
86   * Pluto's uses of render parameters was rebuild.
87   *
88   * Based on Apache Pluto Container <code>org.apache.pluto.PortletContainerImpl</code> class.
89   */
90  public class PortletContainerImpl implements PortletContainer
91  {
92      private static String CONTAINER_SUPPORTS_BUFFERING = "portletcontainer.supportsBuffering";
93      private String uniqueContainerName;
94      private boolean initialized;
95      private boolean supportsBuffering;
96      private Logger log = null;
97  
98      /**
99           * @see org.apache.pluto.PortletContainer#init(java.lang.String, javax.servlet.ServletConfig, org.apache.pluto.services.PortletContainerEnvironment, java.util.Properties)
100          */
101     public void init( String uniqueContainerName, ServletConfig servletConfig, PortletContainerEnvironment environment,
102         Properties properties )
103     {
104         this.uniqueContainerName = uniqueContainerName;
105         PortletContainerServices.createReference( uniqueContainerName, environment );
106         initialized = true;
107 
108         // Initialize the Logger that we will use
109         // from here forward for this Container:
110         log = ( (LogService) environment.getContainerService( LogService.class ) ).getLogger( getClass(  ) );
111 
112         Boolean b = (Boolean) properties.get( CONTAINER_SUPPORTS_BUFFERING );
113 
114         if ( b == null )
115         {
116             log.warn( "org.apache.pluto.PortletContainerImpl#init(): " + "Couldn't retrieve parameter \"" +
117                 CONTAINER_SUPPORTS_BUFFERING + "\" from" +
118                 "passed properties object. Falling back to default value \"FALSE\"" );
119             supportsBuffering = false;
120         }
121         else
122         {
123             supportsBuffering = b.booleanValue(  );
124         }
125     }
126 
127     /**
128          * @see org.apache.pluto.PortletContainer#shutdown()
129          */
130     public void shutdown(  )
131     {
132         PortletContainerServices.destroyReference( uniqueContainerName );
133     }
134 
135     /**
136          * @see org.apache.pluto.PortletContainer#renderPortlet(org.apache.pluto.om.window.PortletWindow, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
137          */
138     public void renderPortlet( PortletWindow portletWindow, HttpServletRequest servletRequest,
139         HttpServletResponse servletResponse ) throws PortletException, IOException
140     {
141         PortletContainerServices.prepare( uniqueContainerName );
142 
143         PortletInvoker invoker = null;
144 
145         if ( log.isDebugEnabled(  ) )
146         {
147             log.debug( "PortletContainerImpl.portletService(" + portletWindow.getId(  ) + ") called." );
148         }
149 
150         try
151         {
152             RenderRequest renderRequest = PortletObjectAccess.getRenderRequest( portletWindow, servletRequest,
153                     servletResponse );
154 
155             RenderResponse renderResponse = PortletObjectAccess.getRenderResponse( portletWindow, servletRequest,
156                     servletResponse, supportsBuffering );
157 
158             invoker = PortletInvokerAccess.getPortletInvoker( portletWindow.getPortletEntity(  ).getPortletDefinition(  ) );
159             invoker.render( renderRequest, renderResponse );
160 
161             ( (PortletWindowImpl) portletWindow ).saveValues(  );
162         }
163         catch ( PortletException e )
164         {
165             ( (PortletWindowImpl) portletWindow ).restoreValues(  );
166             throw e;
167         }
168         catch ( IOException e )
169         {
170             ( (PortletWindowImpl) portletWindow ).restoreValues(  );
171             throw e;
172         }
173         catch ( RuntimeException e )
174         {
175             ( (PortletWindowImpl) portletWindow ).restoreValues(  );
176             throw e;
177         }
178         finally
179         {
180             PortletInvokerAccess.releasePortletInvoker( invoker );
181             PortletContainerServices.release(  );
182         }
183     }
184 
185     /**
186          * @see org.apache.pluto.PortletContainer#processPortletAction(org.apache.pluto.om.window.PortletWindow, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
187          */
188     public void processPortletAction( final PortletWindow portletWindow, final HttpServletRequest servletRequest,
189         final HttpServletResponse servletResponse ) throws PortletException, IOException
190     {
191         PortletContainerServices.prepare( uniqueContainerName );
192 
193         PortletInvoker invoker = null;
194 
195         if ( log.isDebugEnabled(  ) )
196         {
197             log.debug( "PortletContainerImpl.performPortletAction(" + portletWindow.getId(  ) + ") called." );
198         }
199 
200         InternalActionResponse innerActionResponse = null;
201         ActionRequest actionRequest = null;
202 
203         try
204         {
205             /*ActionRequest*/
206             actionRequest = PortletObjectAccess.getActionRequest( portletWindow, servletRequest, servletResponse );
207 
208             ActionResponse actionResponse = PortletObjectAccess.getActionResponse( portletWindow, servletRequest,
209                     servletResponse );
210 
211             invoker = PortletInvokerAccess.getPortletInvoker( portletWindow.getPortletEntity(  ).getPortletDefinition(  ) );
212             innerActionResponse = (InternalActionResponse) actionResponse;
213             // call action() at the portlet
214             invoker.action( actionRequest, actionResponse );
215 
216             String location = innerActionResponse.getRedirectLocation(  );
217 
218             // Action ask for a redirect... 
219             if ( location != null )
220             {
221                 sendRedirect( servletResponse, location );
222             }
223             else
224             {
225                 ( (PortletWindowImpl) portletWindow ).saveValues(  );
226 
227                 // get the changings of this portlet entity that might be set during action handling
228                 // change portlet mode
229                 if ( innerActionResponse.getChangedPortletMode(  ) != null )
230                 {
231                     InformationProviderAccess.getDynamicProvider( servletRequest )
232                                              .getPortletActionProvider( portletWindow )
233                                              .changePortletMode( innerActionResponse.getChangedPortletMode(  ) );
234                 }
235 
236                 // change window state
237                 if ( innerActionResponse.getChangedWindowState(  ) != null )
238                 {
239                     InformationProviderAccess.getDynamicProvider( servletRequest )
240                                              .getPortletActionProvider( portletWindow )
241                                              .changePortletWindowState( innerActionResponse.getChangedWindowState(  ) );
242                 }
243 
244                 // get render parameters
245                 Map renderParameter = innerActionResponse.getRenderParameters(  );
246                 log.debug( "fix params of " + portletWindow.getId(  ) + " to " + renderParameter );
247                 ( (PortletWindowImpl) portletWindow ).setRenderParameter( renderParameter );
248             }
249         }
250         catch ( PortletException e )
251         {
252             ( (PortletWindowImpl) portletWindow ).restoreValues(  );
253             throw e;
254         }
255         catch ( IOException e )
256         {
257             ( (PortletWindowImpl) portletWindow ).restoreValues(  );
258             throw e;
259         }
260         catch ( RuntimeException e )
261         {
262             ( (PortletWindowImpl) portletWindow ).restoreValues(  );
263             throw e;
264         }
265         finally
266         {
267             try
268             {
269                 String strLocation = PortletURLProviderImpl.getRedirectPortalURL( servletRequest, servletResponse );
270                 sendRedirect( servletResponse, strLocation );
271             }
272             finally
273             {
274                 PortletInvokerAccess.releasePortletInvoker( invoker );
275                 PortletContainerServices.release(  );
276             }
277         }
278     }
279 
280     /**
281          * @see org.apache.pluto.PortletContainer#portletLoad(org.apache.pluto.om.window.PortletWindow, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
282          */
283     public void portletLoad( PortletWindow portletWindow, HttpServletRequest servletRequest,
284         HttpServletResponse servletResponse ) throws PortletException
285     {
286         PortletContainerServices.prepare( uniqueContainerName );
287 
288         PortletInvoker invoker = null;
289 
290         if ( log.isDebugEnabled(  ) )
291         {
292             log.debug( "PortletContainerImpl.portletLoad(" + portletWindow.getId(  ) + ") called." );
293         }
294 
295         RenderRequest renderRequest = PortletObjectAccess.getRenderRequest( portletWindow, servletRequest,
296                 servletResponse );
297 
298         RenderResponse renderResponse = PortletObjectAccess.getRenderResponse( portletWindow, servletRequest,
299                 servletResponse, supportsBuffering );
300 
301         invoker = PortletInvokerAccess.getPortletInvoker( portletWindow.getPortletEntity(  ).getPortletDefinition(  ) );
302 
303         try
304         {
305             invoker.load( renderRequest, renderResponse );
306         }
307         finally
308         {
309             PortletInvokerAccess.releasePortletInvoker( invoker );
310             PortletContainerServices.release(  );
311         }
312     }
313 
314     /**
315          * @see org.apache.pluto.PortletContainer#isInitialized()
316          */
317     public boolean isInitialized(  )
318     {
319         return initialized;
320     }
321 
322     /**
323      * Send a redirect response to user, use true deeply defined HttpServletResponse,
324      * because response wrapped for portlets can't send redirect).
325      *
326          * @param servletResponse The current HTTP response
327          * @param location URL location to send
328          * @throws IOException for IO exceptions will sending redirect
329          */
330     private void sendRedirect( HttpServletResponse servletResponse, String location )
331         throws IOException
332     {
333         HttpServletResponse redirectResponse = servletResponse;
334 
335         while ( redirectResponse instanceof HttpServletResponseWrapper )
336         {
337             redirectResponse = (HttpServletResponse) ( (HttpServletResponseWrapper) redirectResponse ).getResponse(  );
338         }
339 
340         redirectResponse.sendRedirect( location );
341     }
342 }