View Javadoc

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one
    3    * or more contributor license agreements.  See the NOTICE file
    4    * distributed with this work for additional information
    5    * regarding copyright ownership.  The ASF licenses this file
    6    * to you under the Apache License, Version 2.0 (the
    7    * "License"); you may not use this file except in compliance
    8    * with the License.  You may obtain a copy of the License at
    9    *
    10   *   http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   * Unless required by applicable law or agreed to in writing,
    13   * software distributed under the License is distributed on an
    14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    15   * KIND, either express or implied.  See the License for the
    16   * specific language governing permissions and limitations
    17   * under the License.
    18   */
    19  package org.apache.myfaces.orchestra.lib.jsf;
    20
    21  import java.util.Iterator;
    22  import java.util.List;
    23  import java.util.ListIterator;
    24
    25  import javax.el.ELContext;
    26  import javax.faces.application.Application;
    27  import javax.faces.application.FacesMessage;
    28  import javax.faces.component.UIViewRoot;
    29  import javax.faces.context.ExternalContext;
    30  import javax.faces.context.FacesContext;
    31  import javax.faces.context.ResponseStream;
    32  import javax.faces.context.ResponseWriter;
    33  import javax.faces.render.RenderKit;
    34
    35  import org.apache.commons.logging.Log;
    36  import org.apache.commons.logging.LogFactory;
    37  import org.apache.myfaces.orchestra.frameworkAdapter.FrameworkAdapter;
    38
    39  /**
    40   * Convenient class to wrap the current FacesContext in portlet environment.
    41   *
    42   * @since 1.4
    43   *
    44   * @author Leonardo Uribe (latest modification by $Author: lu4242 $)
    45   * @version $Revision: 798382 $ $Date: 2009-07-27 22:23:02 -0500 (lun, 27 jul 2009) $
    46   */
    47  public class _PortletFacesContextWrapper extends FacesContext
    48  {
    49      private final static String REQUEST_ADAPTER = "org.apache.myfaces.orchestra.REQUEST_ADAPTER";
    50
    51      //~ Instance fields -------------------------------------------------------
    52
    53      private final FacesContext _facesContext;
    54      private final ExternalContext externalContextDelegate;
    55      private final RequestHandler contextLockHandler;
    56      private final List _handlers;
    57      private final String _nextToken;
    58
    59      private final Log log = LogFactory
    60              .getLog(_PortletFacesContextWrapper.class);
    61
    62      //~ Constructors ----------------------------------------------------------
    63
    64      /**
    65       * The install parameter controls whether this object will be configured as
    66       * the object returned from calls to FacesContext.getCurrentInstance() or not.
    67       * <p>
    68       * When only overriding the release() method, then install=false is ok as that
    69       * is called directly by the FacesServlet on the instance returned by the
    70       * FacesContextFactory. However all other methods are invoked on the object
    71       * that is returned from FacesContext.getCurrentInstance, so install=true is
    72       * needed in order for any other method overrides to have any effect.
    73       * <p>
    74       * <b>IMPORTANT</b>: install=true should not be used until MYFACES-1820 is fixed.
    75       */
    76      public _PortletFacesContextWrapper(final FacesContext facesContext,
    77              final boolean install, boolean finit, String fnextToken, List fhandlers,
    78              final RequestHandler fcontextLockHandler )
    79      {
    80          if (log.isDebugEnabled())
    81          {
    82              log.debug("getFacesContext: running inner constructor");
    83          }
    84
    85          _facesContext = facesContext;
    86
    87          if (install)
    88          {
    89              FacesContext.setCurrentInstance(this);
    90          }
    91
    92          externalContextDelegate = new PortletExternalContextWrapper(
    93                  _facesContext.getExternalContext());
    94
    95          _handlers = fhandlers;
    96          _nextToken = fnextToken;
    97          contextLockHandler = fcontextLockHandler;
    98          if (finit)
    99          {
    100             ListIterator i = fhandlers.listIterator();
    101             try
    102             {
    103                 contextLockHandler.init(facesContext);
    104                 while (i.hasNext())
    105                 {
    106                     RequestHandler h = (RequestHandler) i.next();
    107
    108                     if (log.isDebugEnabled())
    109                     {
    110                         log.debug("Running inithandler of type "
    111                                 + h.getClass().getName());
    112                     }
    113
    114                     h.init(facesContext);
    115                 }
    116             }
    117             catch (RuntimeException e)
    118             {
    119                 log.error("Problem initialising RequestHandler", e);
    120                 _release(i);
    121                 contextLockHandler.deinit();
    122                 throw e;
    123             }
    124         }
    125         else
    126         {
    127             try
    128             {
    129                 contextLockHandler.init(facesContext);
    130             }
    131             catch (RuntimeException e)
    132             {
    133                 contextLockHandler.deinit();
    134             }
    135
    136             RequestType type = ExternalContextUtils.getRequestType(facesContext
    137                     .getExternalContext());
    138
    139             if (RequestType.RENDER.equals(type))
    140             {
    141                 String handlersKey = (String) fnextToken;
    142                 FrameworkAdapter adapter = (FrameworkAdapter) getExternalContext()
    143                         .getApplicationMap().remove(
    144                                 REQUEST_ADAPTER + handlersKey);
    145                 if (FrameworkAdapter.getCurrentInstance() == null)
    146                 {
    147                     FrameworkAdapter.setCurrentInstance(adapter);
    148                 }
    149             }
    150         }
    151     }
    152
    153     //~ Non-Final Methods -----------------------------------------------------
    154
    155     public void release()
    156     {
    157         if (log.isDebugEnabled())
    158         {
    159             log.debug("Running release");
    160         }
    161         RequestType type = ExternalContextUtils
    162                 .getRequestType(getExternalContext());
    163         if (RequestType.RENDER.equals(type) ||
    164             RequestType.EVENT.equals(type) ||
    165             RequestType.RESOURCE.equals(type) ||
    166             this.getResponseComplete())
    167         {
    168             ListIterator i = _handlers.listIterator();
    169             while (i.hasNext())
    170             {
    171                 i.next();
    172             }
    173             _release(i);
    174         }
    175         if (RequestType.ACTION.equals(type))
    176         {
    177             if (this.getResponseComplete())
    178             {
    179                 // If response is complete by some reason, we need to
    180                 // clean request handlers from application map. This is set
    181                 // before an instance of this class is created.
    182                 getExternalContext().getApplicationMap().remove(
    183                         PortletOrchestraFacesContextFactory.REQUEST_HANDLERS+_nextToken);
    184             }
    185             else
    186             {
    187                 //Pass the current FrameworkAdapter through application map,
    188                 //to remove it later when rendering
    189                 FrameworkAdapter adapter = FrameworkAdapter.getCurrentInstance();
    190                 getExternalContext().getApplicationMap().put(
    191                         REQUEST_ADAPTER + _nextToken, adapter);
    192
    193                 //Orchestra suppose the same thread handles the current request, but
    194                 //in portlets this is not necessary true. One thread could handle action
    195                 //requests and other render request. To keep code working we set it to
    196                 //null here, so other request don't mix it.
    197                 FrameworkAdapter.setCurrentInstance(null);
    198             }
    199         }
    200
    201         try
    202         {
    203             //Since in portlets the same thread does not handler both action and
    204             //render phase for the same request contextLockHandler needs to
    205             //be cleared and lock again
    206             contextLockHandler.deinit();
    207         }
    208         catch (Exception e)
    209         {
    210             log.error("Problem deinitialising RequestHandler", e);
    211         }
    212         if (log.isDebugEnabled())
    213         {
    214             log.debug("Release completed");
    215         }
    216         _facesContext.release();
    217     }
    218
    219     private void _release(ListIterator i)
    220     {
    221         while (i.hasPrevious())
    222         {
    223             try
    224             {
    225                 RequestHandler h = (RequestHandler) i.previous();
    226                 if (log.isDebugEnabled())
    227                 {
    228                     log.debug("Running deinithandler of type "
    229                             + h.getClass().getName());
    230                 }
    231                 h.deinit();
    232             }
    233             catch (Exception e)
    234             {
    235                 log.error("Problem deinitialising RequestHandler", e);
    236             }
    237         }
    238     }
    239
    240     //~ Final Methods ---------------------------------------------------------
    241
    242     public final Application getApplication()
    243     {
    244         return _facesContext.getApplication();
    245     }
    246
    247     public final Iterator getClientIdsWithMessages()
    248     {
    249         return _facesContext.getClientIdsWithMessages();
    250     }
    251
    252     public ExternalContext getExternalContext()
    253     {
    254         return externalContextDelegate == null ? _facesContext
    255                 .getExternalContext() : externalContextDelegate;
    256     }
    257
    258     public final FacesMessage.Severity getMaximumSeverity()
    259     {
    260         return _facesContext.getMaximumSeverity();
    261     }
    262
    263     public final Iterator getMessages()
    264     {
    265         return _facesContext.getMessages();
    266     }
    267
    268     public final Iterator getMessages(String clientId)
    269     {
    270         return _facesContext.getMessages(clientId);
    271     }
    272
    273     public final RenderKit getRenderKit()
    274     {
    275         return _facesContext.getRenderKit();
    276     }
    277
    278     public final boolean getRenderResponse()
    279     {
    280         return _facesContext.getRenderResponse();
    281     }
    282
    283     public final boolean getResponseComplete()
    284     {
    285         return _facesContext.getResponseComplete();
    286     }
    287
    288     public final void setResponseStream(ResponseStream responsestream)
    289     {
    290         _facesContext.setResponseStream(responsestream);
    291     }
    292
    293     public final ResponseStream getResponseStream()
    294     {
    295         return _facesContext.getResponseStream();
    296     }
    297
    298     public final void setResponseWriter(ResponseWriter responsewriter)
    299     {
    300         _facesContext.setResponseWriter(responsewriter);
    301     }
    302
    303     public final ResponseWriter getResponseWriter()
    304     {
    305         return _facesContext.getResponseWriter();
    306     }
    307
    308     public final void setViewRoot(UIViewRoot viewRoot)
    309     {
    310         _facesContext.setViewRoot(viewRoot);
    311     }
    312
    313     public final UIViewRoot getViewRoot()
    314     {
    315         return _facesContext.getViewRoot();
    316     }
    317
    318     public final void addMessage(String clientId, FacesMessage message)
    319     {
    320         _facesContext.addMessage(clientId, message);
    321     }
    322
    323     public final void renderResponse()
    324     {
    325         _facesContext.renderResponse();
    326     }
    327
    328     public final void responseComplete()
    329     {
    330         _facesContext.responseComplete();
    331     }
    332
    333     public final ELContext getELContext()
    334     {
    335         return _facesContext.getELContext();
    336     }
    337 }