Coverage Report - javax.faces.application.ViewHandler
 
Classes in this File Line Coverage Branch Coverage Complexity
ViewHandler
0%
0/24
0%
0/16
0
 
 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 javax.faces.application;
 20  
 
 21  
 import javax.faces.FacesException;
 22  
 import javax.faces.context.ExternalContext;
 23  
 
 24  
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFWebConfigParam;
 25  
 
 26  
 import java.io.UnsupportedEncodingException;
 27  
 import java.util.Locale;
 28  
 
 29  
 /**
 30  
  * A ViewHandler manages the component-tree-creation and component-tree-rendering parts
 31  
  * of a request lifecycle (ie "create view", "restore view" and "render response").
 32  
  * <p>
 33  
  * A ViewHandler is responsible for generating the component tree when a new view is
 34  
  * requested; see method "createView".
 35  
  * <p>
 36  
  * When the user performs a "postback", ie activates a UICommand component within a view,
 37  
  * then the ViewHandler is responsible for recreating a view tree identical to the one
 38  
  * used previously to render that view; see method "restoreView".
 39  
  * <p>
 40  
  * And the ViewHandler is also responsible for rendering the final output to be sent to the
 41  
  * user by invoking the rendering methods on components; see method "renderView".
 42  
  * <p>
 43  
  * This class also isolates callers from the underlying request/response system. In particular,
 44  
  * this class does not explicitly depend upon the javax.servlet apis. This allows JSF to be
 45  
  * used on servers that do not implement the servlet API (for example, plain CGI). 
 46  
  * <p>
 47  
  * Examples:
 48  
  * <ul>
 49  
  * <li>A JSP ViewHandler exists for using "jsp" pages as the presentation technology.
 50  
  * This class then works together with a taghandler class and a jsp servlet class to
 51  
  * implement the methods on this abstract class definition.
 52  
  * <li>A Facelets ViewHandler instead uses an xml file to define the components and
 53  
  * non-component data that make up a specific view. 
 54  
  * </ul>
 55  
  * Of course there is no reason why the "template" needs to be a textual file. A view could
 56  
  * be generated based on data in a database, or many other mechanisms.
 57  
  * <p>
 58  
  * This class is expected to be invoked via the concrete implementation of 
 59  
  * {@link javax.faces.lifecycle.Lifecycle}.
 60  
  * <p>
 61  
  * For the official specification for this class, see 
 62  
  * <a href="http://java.sun.com/javaee/javaserverfaces/1.2/docs/api/index.html">JSF Specification</a>.
 63  
  *
 64  
  * @author Manfred Geiler (latest modification by $Author: lu4242 $)
 65  
  * @version $Revision: 833810 $ $Date: 2009-11-07 21:40:01 -0500 (Sat, 07 Nov 2009) $
 66  
  */
 67  0
 public abstract class ViewHandler
 68  
 {
 69  
     public static final String CHARACTER_ENCODING_KEY = "javax.faces.request.charset";
 70  
     
 71  
     /**
 72  
      * Indicate the default suffix to derive the file URI if extension mapping is used. 
 73  
      */
 74  
     @JSFWebConfigParam(defaultValue=".jsp", since="1.1")
 75  
     public static final String DEFAULT_SUFFIX_PARAM_NAME = "javax.faces.DEFAULT_SUFFIX";
 76  
     public static final String DEFAULT_SUFFIX = ".jsp";
 77  
 
 78  
     /**
 79  
      * @since JSF 1.2
 80  
      */
 81  
     public String calculateCharacterEncoding(javax.faces.context.FacesContext context)
 82  
     {
 83  0
         String _encoding = null;
 84  0
         ExternalContext externalContext = context.getExternalContext();
 85  0
         String _contentType = (String) externalContext.getRequestHeaderMap().get("Content-Type");
 86  0
         int _indexOf = _contentType == null ? -1 :_contentType.indexOf("charset");
 87  0
         if(_indexOf != -1)
 88  
         {
 89  0
             String _tempEnc =_contentType.substring(_indexOf); //charset=UTF-8 
 90  0
             _encoding = _tempEnc.substring(_tempEnc.indexOf("=")+1); //UTF-8
 91  0
             if (_encoding.length() == 0)
 92  
             {
 93  0
                 _encoding = null;
 94  
             }
 95  
         }
 96  0
         if (_encoding == null) 
 97  
         {
 98  0
             boolean _sessionAvailable = externalContext.getSession(false) != null;
 99  0
             if(_sessionAvailable)
 100  
             {
 101  0
                 Object _sessionParam = externalContext.getSessionMap().get(CHARACTER_ENCODING_KEY); 
 102  0
                 if (_sessionParam != null)
 103  
                 {
 104  0
                     _encoding = _sessionParam.toString();
 105  
                 }
 106  
             }
 107  
         }
 108  
         
 109  0
         return _encoding;
 110  
     }
 111  
     
 112  
     /**
 113  
      * Return the Locale object that should be used when rendering this view to the
 114  
      * current user.
 115  
      * <p>
 116  
      * Some request protocols allow an application user to specify what locale they prefer
 117  
      * the response to be in. For example, HTTP requests can specify the "accept-language"
 118  
      * header.
 119  
      * <p>
 120  
      * Method {@link javax.faces.application.Application#getSupportedLocales()} defines
 121  
      * what locales this JSF application is capable of supporting.
 122  
      * <p>
 123  
      * This method should match such sources of data up and return the Locale object that
 124  
      * is the best choice for rendering the current application to the current user.
 125  
      */
 126  
     public abstract Locale calculateLocale(javax.faces.context.FacesContext context);
 127  
 
 128  
     /**
 129  
      * Return the id of an available render-kit that should be used to map the JSF
 130  
      * components into user presentation.
 131  
      * <p>
 132  
      * The render-kit selected (eg html, xhtml, pdf, xul, ...) may depend upon the user,
 133  
      * properties associated with the request, etc.
 134  
      */
 135  
     public abstract String calculateRenderKitId(javax.faces.context.FacesContext context);
 136  
 
 137  
     /**
 138  
      * Build a root node for a component tree.
 139  
      * <p>
 140  
      * When a request is received, this method is called if restoreView returns null,
 141  
      * ie this is not a "postback". In this case, a root node is created and then renderView
 142  
      * is invoked. It is the responsibility of the renderView method to build the full
 143  
      * component tree (ie populate the UIViewRoot with descendant nodes).
 144  
      * <p>
 145  
      * This method is also invoked when navigation occurs from one view to another, where
 146  
      * the viewId passed is the id of the new view to be displayed. Again it is the responsibility
 147  
      * of renderView to then populate the viewroot with descendants.
 148  
      * <p>
 149  
      * The locale and renderKit settings are inherited from the current UIViewRoot that is
 150  
      * configured before this method is called. That means of course that they do NOT
 151  
      * get set for GET requests, including navigation that has the redirect flag set.
 152  
      */
 153  
     public abstract javax.faces.component.UIViewRoot createView(javax.faces.context.FacesContext context,
 154  
                                                                 String viewId);
 155  
 
 156  
     /**
 157  
      * Return a URL that a remote system can invoke in order to access the specified view.
 158  
      * <p>
 159  
      * Note that the URL a user enters and the viewId which is invoked can be
 160  
      * different. The simplest difference is a change in suffix (eg url "foo.jsf"
 161  
      * references view "foo.jsp").
 162  
      */
 163  
     public abstract String getActionURL(javax.faces.context.FacesContext context,
 164  
                                         String viewId);
 165  
 
 166  
     /**
 167  
      * Return a URL that a remote system can invoke in order to access the specified resource.
 168  
      * <p>
 169  
      * When path starts with a slash, it is relative to the webapp root. Otherwise it is
 170  
      * relative to the value returned by getActionURL.
 171  
      */
 172  
     public abstract String getResourceURL(javax.faces.context.FacesContext context,
 173  
                                           String path);
 174  
     
 175  
     /**
 176  
      * Method must be called by the JSF impl at the beginning of Phase <i>Restore View</i> of the JSF
 177  
      * lifecycle.
 178  
      * 
 179  
      * @since JSF 1.2
 180  
      */
 181  
     public void initView(javax.faces.context.FacesContext context) throws FacesException
 182  
     {
 183  0
         String _encoding = this.calculateCharacterEncoding(context);
 184  0
         if(_encoding != null)
 185  
         {
 186  
             try
 187  
             {
 188  0
                 context.getExternalContext().setRequestCharacterEncoding(_encoding);
 189  
             }
 190  0
             catch(UnsupportedEncodingException uee)
 191  
             {
 192  0
                 throw new FacesException(uee);
 193  0
             }
 194  
         }
 195  0
     }
 196  
     
 197  
     /**
 198  
      * Combine the output of all the components in the viewToRender with data from the
 199  
      * original view template (if any) and write the result to context.externalContext.response.
 200  
      * <p>
 201  
      * Component output is generated by invoking the encodeBegin, encodeChildren (optional)
 202  
      * and encodeEnd methods on relevant components in the specified view. How this is
 203  
      * interleaved with the non-component content of the view template (if any) is left
 204  
      * to the ViewHandler implementation.
 205  
      * <p>
 206  
      * The actual type of the Response object depends upon the concrete implementation of
 207  
      * this class. It will almost certainly be an OutputStream of some sort, but may be
 208  
      * specific to the particular request/response  system in use.
 209  
      * <p>
 210  
      * If the view cannot be rendered (eg due to an error in a component) then a FacesException
 211  
      * is thrown.
 212  
      * <p>
 213  
      * Note that if a "postback" has occurred but no navigation to a different view, then
 214  
      * the viewToRender will be fully populated with components already. However on direct
 215  
      * access to a new view, or when navigation has occurred, the viewToRender will just
 216  
      * contain an empty UIViewRoot object that must be populated with components from
 217  
      * the "view template". 
 218  
      */
 219  
     public abstract void renderView(javax.faces.context.FacesContext context,
 220  
                                     javax.faces.component.UIViewRoot viewToRender)
 221  
             throws java.io.IOException,
 222  
             FacesException;
 223  
 
 224  
     /**
 225  
      * Handle a "postback" request by recreating the component tree that was most recently
 226  
      * presented to the user for the specified view.
 227  
      * <p>
 228  
      * When the user performs a "postback" of a view that has previously been created, ie
 229  
      * is updating the state of an existing view tree, then the view handler must recreate
 230  
      * a view tree identical to the one used previously to render that view to the user,
 231  
      * so that the data received from the user can be compared to the old state and the
 232  
      * correct "changes" detected (well, actually only those components that respond to
 233  
      * input are actually needed before the render phase). 
 234  
      * <p>
 235  
      * The components in this tree will then be given the opportunity to examine new input
 236  
      * data provided by the user, and react in the appropriate manner for that component,
 237  
      * as specified for the JSF lifecycle.
 238  
      * <p>
 239  
      * Much of the work required by this method <i>must</i> be delegated to an instance
 240  
      * of StateManager.
 241  
      * <p>
 242  
      * If there is no record of the current user having been sent the specified view
 243  
      * (ie no saved state information available), then NULL should be returned.
 244  
      * <p>
 245  
      * Note that input data provided by the user may also be used to determine exactly
 246  
      * how to restore this view. In the case of "client side state", information
 247  
      * about the components to be restored will be available here. Even for
 248  
      * "server side state", user input may include an indicator that is used to
 249  
      * select among a number of different saved states available for this viewId and
 250  
      * this user.
 251  
      * <p>
 252  
      * Note that data received from users is inherently untrustworthy; care should be
 253  
      * taken to validate this information appropriately.
 254  
      * <p>
 255  
      * See writeState for more details. 
 256  
      */
 257  
     public abstract javax.faces.component.UIViewRoot restoreView(javax.faces.context.FacesContext context,
 258  
                                                                  String viewId);
 259  
 
 260  
     /**
 261  
      * Write sufficient information to context.externalContext.response in order to
 262  
      * be able to restore this view if the user performs a "postback" using that
 263  
      * rendered response.
 264  
      * <p>
 265  
      * For "client side state saving", sufficient information about the view
 266  
      * state should be written to allow a "restore view" operation to succeed 
 267  
      * later. This does not necessarily mean storing <i>all</i> data about the
 268  
      * current view; only data that cannot be recreated from the "template" for
 269  
      * this view needs to be saved.
 270  
      * <p>
 271  
      * For "server side state saving", this method may write out nothing. Alternately
 272  
      * it may write out a "state identifier" to identify which of multiple saved
 273  
      * user states for a particular view should be selected (or just verify that the
 274  
      * saved state does indeed correspond to the expected one).
 275  
      */
 276  
     public abstract void writeState(javax.faces.context.FacesContext context)
 277  
             throws java.io.IOException;
 278  
 }