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.portals.bridges.jsf;
    18
    19  import java.util.ArrayList;
    20  import java.util.Collections;
    21  import java.util.Iterator;
    22  import java.util.List;
    23  import java.util.NoSuchElementException;
    24
    25  import javax.faces.FactoryFinder;
    26  import javax.faces.application.Application;
    27  import javax.faces.application.ApplicationFactory;
    28  import javax.faces.application.FacesMessage;
    29  import javax.faces.component.UIViewRoot;
    30  import javax.faces.context.ExternalContext;
    31  import javax.faces.context.FacesContext;
    32  import javax.faces.context.ResponseStream;
    33  import javax.faces.context.ResponseWriter;
    34  import javax.faces.render.RenderKit;
    35  import javax.faces.render.RenderKitFactory;
    36
    37  import javax.portlet.ActionRequest;
    38  import javax.portlet.PortletContext;
    39  import javax.portlet.PortletRequest;
    40  import javax.portlet.PortletResponse;
    41  import javax.portlet.PortletSession;
    42
    43  import org.apache.commons.logging.Log;
    44  import org.apache.commons.logging.LogFactory;
    45
    46  /***
    47   * <p>
    48   * See MyFaces project for servlet implementation.
    49   * </p>
    50   * <p>
    51   * TODO There should be a base class shared with the MyFaces
    52   * ServletFacesContextImpl.
    53   * </p>
    54   *
    55   * @author <a href="dlestrat@apache.org">David Le Strat </a>
    56   *
    57   */
    58  public class PortletFacesContextImpl extends FacesContext
    59  {
    60      /*** The logger. */
    61      private static final Log log = LogFactory.getLog(PortletFacesContextImpl.class);
    62
    63      protected static final Object NULL_DUMMY = new Object();
    64
    65      /*** The message client ids. */
    66      private List messageClientIds = null;
    67
    68      /*** The mesages. */
    69      private List messages = null;
    70
    71      /*** The application. */
    72      private Application application;
    73
    74      /*** The portlet external context. */
    75      private PortletExternalContextImpl externalContext;
    76
    77      /*** The response stream. */
    78      private ResponseStream responseStream = null;
    79
    80      /*** The response writer. */
    81      private ResponseWriter responseWriter = null;
    82
    83      /*** The severity. */
    84      private FacesMessage.Severity maximumSeverity = FacesMessage.SEVERITY_INFO;
    85
    86      /*** The view root. */
    87      private UIViewRoot viewRoot;
    88
    89      /*** The render response. */
    90      private boolean renderResponse = false;
    91
    92      /*** Whether the response is complete. */
    93      private boolean responseComplete = false;
    94
    95      /*** The render kit factory. */
    96      private RenderKitFactory renderKitFactory;
    97
    98      /*** The JSF_VIEW_ID used to maintain the state of the view action. */
    99      public static final String JSF_VIEW_ID = "jsf_viewid";
    100
    101     /***
    102      * @param portletContext The {@link PortletContext}.
    103      * @param portletRequest The {@link PortletRequest}.
    104      * @param portletResponse The {@link PortletResponse}.
    105      */
    106     public PortletFacesContextImpl(PortletContext portletContext, PortletRequest portletRequest,
    107             PortletResponse portletResponse)
    108     {
    109         this.application = ((ApplicationFactory) FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY))
    110                 .getApplication();
    111         this.renderKitFactory = (RenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
    112         this.externalContext = new PortletExternalContextImpl(portletContext, portletRequest, portletResponse);
    113         FacesContext.setCurrentInstance(this); //protected method, therefore
    114         // must be called from here
    115     }
    116
    117     public UIViewRoot resolveViewRoot(String defaultViewName, PortletRequest portletRequest)
    118     {
    119         // shoot: can't get the entity id and be portable
    120         PortletRequest request = (PortletRequest) externalContext.getRequest();
    121         String viewId = request.getParameter(JSF_VIEW_ID);
    122
    123         if (viewId == null)
    124         {
    125             viewId = defaultViewName;
    126             if (log.isDebugEnabled())
    127             {
    128                 log.debug("Request view id is null.  Using default view.");
    129             }
    130         }
    131         if (log.isDebugEnabled())
    132         {
    133             log.debug("Resolving view root - Using view id: " + viewId);
    134         }
    135
    136         String requestType = (String)portletRequest.getAttribute(FacesPortlet.REQUEST_TYPE);
    137         if (requestType != null && requestType.equals(FacesPortlet.ACTION_REQUEST))
    138         {
    139             if (log.isDebugEnabled())
    140             {
    141                 log.debug("Resolving action: " + viewId);
    142             }
    143             setViewRoot(viewRoot);
    144             portletRequest.setAttribute(FacesPortlet.REQUEST_SERVLET_PATH, viewId.replaceAll(".jsp", ".jsf"));
    145             return null;
    146         }
    147
    148         UIViewRoot viewRoot = (UIViewRoot) request.getPortletSession().getAttribute(viewId,
    149                 PortletSession.PORTLET_SCOPE);
    150         if (null == viewRoot)
    151         {
    152             if (log.isDebugEnabled())
    153             {
    154                 log.debug("Creating new view root: " + viewId);
    155             }
    156             viewRoot = application.getViewHandler().createView(this, viewId);
    157             //viewRoot = new UIViewRoot();
    158             UIViewRoot newViewRoot = new PortletUIViewRoot(viewRoot);
    159             viewRoot = newViewRoot;
    160             viewRoot.setViewId(viewId);
    161             viewRoot.setRenderKitId(RenderKitFactory.HTML_BASIC_RENDER_KIT);
    162             request.getPortletSession().setAttribute(viewId, viewRoot, PortletSession.PORTLET_SCOPE);
    163         }
    164         else
    165         {
    166             if (log.isDebugEnabled())
    167             {
    168                 log.debug("Using view root from session: " + viewId);
    169             }
    170         }
    171         setViewRoot(viewRoot);
    172         portletRequest.setAttribute(FacesPortlet.REQUEST_SERVLET_PATH, viewId.replaceAll(".jsp", ".jsf"));
    173         return viewRoot;
    174     }
    175
    176     /***
    177      * @see javax.faces.context.FacesContext#getExternalContext()
    178      */
    179     public ExternalContext getExternalContext()
    180     {
    181         return this.externalContext;
    182     }
    183
    184     /***
    185      * @see javax.faces.context.FacesContext#getMaximumSeverity()
    186      */
    187     public FacesMessage.Severity getMaximumSeverity()
    188     {
    189         return this.maximumSeverity;
    190     }
    191
    192     /***
    193      * @see javax.faces.context.FacesContext#getMessages()
    194      */
    195     public Iterator getMessages()
    196     {
    197         return (this.messages != null) ? this.messages.iterator() : Collections.EMPTY_LIST.iterator();
    198     }
    199
    200     /***
    201      * @see javax.faces.context.FacesContext#getApplication()
    202      */
    203     public Application getApplication()
    204     {
    205         return this.application;
    206     }
    207
    208     /***
    209      * @see javax.faces.context.FacesContext#getClientIdsWithMessages()
    210      */
    211     public Iterator getClientIdsWithMessages()
    212     {
    213         if (this.messages == null || this.messages.isEmpty())
    214         {
    215             return NullIterator.instance();
    216         }
    217
    218         return new Iterator()
    219         {
    220             private int next;
    221
    222             boolean nextFound;
    223
    224             public void remove()
    225             {
    226                 throw new UnsupportedOperationException(this.getClass().getName() + " UnsupportedOperationException");
    227             }
    228
    229             public boolean hasNext()
    230             {
    231                 if (!nextFound)
    232                 {
    233                     for (int len = messageClientIds.size(); next < len; next++)
    234                     {
    235                         if (messageClientIds.get(next) != NULL_DUMMY)
    236                         {
    237                             nextFound = true;
    238                             break;
    239                         }
    240                     }
    241                 }
    242                 return nextFound;
    243             }
    244
    245             public Object next()
    246             {
    247                 if (hasNext())
    248                 {
    249                     nextFound = false;
    250                     return messageClientIds.get(next++);
    251                 }
    252                 throw new NoSuchElementException();
    253             }
    254         };
    255     }
    256
    257     /***
    258      * @see javax.faces.context.FacesContext#getMessages(java.lang.String)
    259      */
    260     public Iterator getMessages(String clientId)
    261     {
    262         if (this.messages == null)
    263         {
    264             return NullIterator.instance();
    265         }
    266
    267         List lst = new ArrayList();
    268         for (int i = 0; i < this.messages.size(); i++)
    269         {
    270             Object savedClientId = this.messageClientIds.get(i);
    271             if (clientId == null)
    272             {
    273                 if (savedClientId == NULL_DUMMY)
    274                     lst.add(this.messages.get(i));
    275             }
    276             else
    277             {
    278                 if (clientId.equals(savedClientId))
    279                     lst.add(this.messages.get(i));
    280             }
    281         }
    282         return lst.iterator();
    283     }
    284
    285     /***
    286      * @see javax.faces.context.FacesContext#getRenderKit()
    287      */
    288     public RenderKit getRenderKit()
    289     {
    290         if (getViewRoot() == null)
    291         {
    292             return null;
    293         }
    294
    295         String renderKitId = getViewRoot().getRenderKitId();
    296
    297         if (renderKitId == null)
    298         {
    299             return null;
    300         }
    301
    302         return this.renderKitFactory.getRenderKit(this, renderKitId);
    303     }
    304
    305     /***
    306      * @see javax.faces.context.FacesContext#getRenderResponse()
    307      */
    308     public boolean getRenderResponse()
    309     {
    310         return this.renderResponse;
    311     }
    312
    313     /***
    314      * @see javax.faces.context.FacesContext#getResponseComplete()
    315      */
    316     public boolean getResponseComplete()
    317     {
    318         return this.responseComplete;
    319     }
    320
    321     /***
    322      * @see javax.faces.context.FacesContext#setResponseStream(javax.faces.context.ResponseStream)
    323      */
    324     public void setResponseStream(ResponseStream responseStream)
    325     {
    326         if (responseStream == null)
    327         {
    328             throw new NullPointerException("responseStream");
    329         }
    330         this.responseStream = responseStream;
    331     }
    332
    333     /***
    334      * @see javax.faces.context.FacesContext#getResponseStream()
    335      */
    336     public ResponseStream getResponseStream()
    337     {
    338         return this.responseStream;
    339     }
    340
    341     /***
    342      * @see javax.faces.context.FacesContext#setResponseWriter(javax.faces.context.ResponseWriter)
    343      */
    344     public void setResponseWriter(ResponseWriter responseWriter)
    345     {
    346         if (responseWriter == null)
    347         {
    348             throw new NullPointerException("responseWriter");
    349         }
    350         this.responseWriter = responseWriter;
    351     }
    352
    353     /***
    354      * @see javax.faces.context.FacesContext#getResponseWriter()
    355      */
    356     public ResponseWriter getResponseWriter()
    357     {
    358         return this.responseWriter;
    359     }
    360
    361     /***
    362      * @see javax.faces.context.FacesContext#setViewRoot(javax.faces.component.UIViewRoot)
    363      */
    364     public void setViewRoot(UIViewRoot viewRoot)
    365     {
    366         if (viewRoot == null)
    367         {
    368             throw new NullPointerException("viewRoot");
    369         }
    370         this.viewRoot = viewRoot;
    371     }
    372
    373     /***
    374      * @see javax.faces.context.FacesContext#getViewRoot()
    375      */
    376     public UIViewRoot getViewRoot()
    377     {
    378         return this.viewRoot;
    379     }
    380
    381     /***
    382      * @see javax.faces.context.FacesContext#addMessage(java.lang.String,
    383      *      javax.faces.application.FacesMessage)
    384      */
    385     public void addMessage(String clientId, FacesMessage message)
    386     {
    387         if (message == null)
    388         {
    389             throw new NullPointerException("message");
    390         }
    391
    392         if (this.messages == null)
    393         {
    394             this.messages = new ArrayList();
    395             this.messageClientIds = new ArrayList();
    396         }
    397         this.messages.add(message);
    398         this.messageClientIds.add((clientId != null) ? clientId : NULL_DUMMY);
    399         FacesMessage.Severity serSeverity = message.getSeverity();
    400         if (serSeverity != null && serSeverity.compareTo(this.maximumSeverity) > 0)
    401         {
    402             this.maximumSeverity = message.getSeverity();
    403         }
    404     }
    405
    406     /***
    407      * @see javax.faces.context.FacesContext#release()
    408      */
    409     public void release()
    410     {
    411         if (this.externalContext != null)
    412         {
    413             this.externalContext.release();
    414             this.externalContext = null;
    415         }
    416
    417         this.messageClientIds = null;
    418         this.messages = null;
    419         this.application = null;
    420         this.responseStream = null;
    421         this.responseWriter = null;
    422         this.viewRoot = null;
    423
    424         FacesContext.setCurrentInstance(null);
    425     }
    426
    427     /***
    428      * @see javax.faces.context.FacesContext#renderResponse()
    429      */
    430     public void renderResponse()
    431     {
    432         this.renderResponse = true;
    433     }
    434
    435     /***
    436      * @see javax.faces.context.FacesContext#responseComplete()
    437      */
    438     public void responseComplete()
    439     {
    440         this.responseComplete = true;
    441     }
    442 }