All Downloads are FREE. Search and download functionalities are using the official Maven repository.

javax.faces.application.ViewHandler Maven / Gradle / Ivy

There is a newer version: 4.1.0
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package javax.faces.application;

import javax.faces.FacesException;
import javax.faces.context.ExternalContext;

import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFWebConfigParam;

import java.io.UnsupportedEncodingException;
import java.util.Locale;

/**
 * A ViewHandler manages the component-tree-creation and component-tree-rendering parts
 * of a request lifecycle (ie "create view", "restore view" and "render response").
 * 

* A ViewHandler is responsible for generating the component tree when a new view is * requested; see method "createView". *

* When the user performs a "postback", ie activates a UICommand component within a view, * then the ViewHandler is responsible for recreating a view tree identical to the one * used previously to render that view; see method "restoreView". *

* And the ViewHandler is also responsible for rendering the final output to be sent to the * user by invoking the rendering methods on components; see method "renderView". *

* This class also isolates callers from the underlying request/response system. In particular, * this class does not explicitly depend upon the javax.servlet apis. This allows JSF to be * used on servers that do not implement the servlet API (for example, plain CGI). *

* Examples: *

    *
  • A JSP ViewHandler exists for using "jsp" pages as the presentation technology. * This class then works together with a taghandler class and a jsp servlet class to * implement the methods on this abstract class definition. *
  • A Facelets ViewHandler instead uses an xml file to define the components and * non-component data that make up a specific view. *
* Of course there is no reason why the "template" needs to be a textual file. A view could * be generated based on data in a database, or many other mechanisms. *

* This class is expected to be invoked via the concrete implementation of * {@link javax.faces.lifecycle.Lifecycle}. *

* For the official specification for this class, see * JSF Specification. * * @author Manfred Geiler (latest modification by $Author: lu4242 $) * @version $Revision: 833810 $ $Date: 2009-11-07 21:40:01 -0500 (Sat, 07 Nov 2009) $ */ public abstract class ViewHandler { public static final String CHARACTER_ENCODING_KEY = "javax.faces.request.charset"; /** * Indicate the default suffix to derive the file URI if extension mapping is used. */ @JSFWebConfigParam(defaultValue=".jsp", since="1.1") public static final String DEFAULT_SUFFIX_PARAM_NAME = "javax.faces.DEFAULT_SUFFIX"; public static final String DEFAULT_SUFFIX = ".jsp"; /** * @since JSF 1.2 */ public String calculateCharacterEncoding(javax.faces.context.FacesContext context) { String _encoding = null; ExternalContext externalContext = context.getExternalContext(); String _contentType = (String) externalContext.getRequestHeaderMap().get("Content-Type"); int _indexOf = _contentType == null ? -1 :_contentType.indexOf("charset"); if(_indexOf != -1) { String _tempEnc =_contentType.substring(_indexOf); //charset=UTF-8 _encoding = _tempEnc.substring(_tempEnc.indexOf("=")+1); //UTF-8 if (_encoding.length() == 0) { _encoding = null; } } if (_encoding == null) { boolean _sessionAvailable = externalContext.getSession(false) != null; if(_sessionAvailable) { Object _sessionParam = externalContext.getSessionMap().get(CHARACTER_ENCODING_KEY); if (_sessionParam != null) { _encoding = _sessionParam.toString(); } } } return _encoding; } /** * Return the Locale object that should be used when rendering this view to the * current user. *

* Some request protocols allow an application user to specify what locale they prefer * the response to be in. For example, HTTP requests can specify the "accept-language" * header. *

* Method {@link javax.faces.application.Application#getSupportedLocales()} defines * what locales this JSF application is capable of supporting. *

* This method should match such sources of data up and return the Locale object that * is the best choice for rendering the current application to the current user. */ public abstract Locale calculateLocale(javax.faces.context.FacesContext context); /** * Return the id of an available render-kit that should be used to map the JSF * components into user presentation. *

* The render-kit selected (eg html, xhtml, pdf, xul, ...) may depend upon the user, * properties associated with the request, etc. */ public abstract String calculateRenderKitId(javax.faces.context.FacesContext context); /** * Build a root node for a component tree. *

* When a request is received, this method is called if restoreView returns null, * ie this is not a "postback". In this case, a root node is created and then renderView * is invoked. It is the responsibility of the renderView method to build the full * component tree (ie populate the UIViewRoot with descendant nodes). *

* This method is also invoked when navigation occurs from one view to another, where * the viewId passed is the id of the new view to be displayed. Again it is the responsibility * of renderView to then populate the viewroot with descendants. *

* The locale and renderKit settings are inherited from the current UIViewRoot that is * configured before this method is called. That means of course that they do NOT * get set for GET requests, including navigation that has the redirect flag set. */ public abstract javax.faces.component.UIViewRoot createView(javax.faces.context.FacesContext context, String viewId); /** * Return a URL that a remote system can invoke in order to access the specified view. *

* Note that the URL a user enters and the viewId which is invoked can be * different. The simplest difference is a change in suffix (eg url "foo.jsf" * references view "foo.jsp"). */ public abstract String getActionURL(javax.faces.context.FacesContext context, String viewId); /** * Return a URL that a remote system can invoke in order to access the specified resource. *

* When path starts with a slash, it is relative to the webapp root. Otherwise it is * relative to the value returned by getActionURL. */ public abstract String getResourceURL(javax.faces.context.FacesContext context, String path); /** * Method must be called by the JSF impl at the beginning of Phase Restore View of the JSF * lifecycle. * * @since JSF 1.2 */ public void initView(javax.faces.context.FacesContext context) throws FacesException { String _encoding = this.calculateCharacterEncoding(context); if(_encoding != null) { try { context.getExternalContext().setRequestCharacterEncoding(_encoding); } catch(UnsupportedEncodingException uee) { throw new FacesException(uee); } } } /** * Combine the output of all the components in the viewToRender with data from the * original view template (if any) and write the result to context.externalContext.response. *

* Component output is generated by invoking the encodeBegin, encodeChildren (optional) * and encodeEnd methods on relevant components in the specified view. How this is * interleaved with the non-component content of the view template (if any) is left * to the ViewHandler implementation. *

* The actual type of the Response object depends upon the concrete implementation of * this class. It will almost certainly be an OutputStream of some sort, but may be * specific to the particular request/response system in use. *

* If the view cannot be rendered (eg due to an error in a component) then a FacesException * is thrown. *

* Note that if a "postback" has occurred but no navigation to a different view, then * the viewToRender will be fully populated with components already. However on direct * access to a new view, or when navigation has occurred, the viewToRender will just * contain an empty UIViewRoot object that must be populated with components from * the "view template". */ public abstract void renderView(javax.faces.context.FacesContext context, javax.faces.component.UIViewRoot viewToRender) throws java.io.IOException, FacesException; /** * Handle a "postback" request by recreating the component tree that was most recently * presented to the user for the specified view. *

* When the user performs a "postback" of a view that has previously been created, ie * is updating the state of an existing view tree, then the view handler must recreate * a view tree identical to the one used previously to render that view to the user, * so that the data received from the user can be compared to the old state and the * correct "changes" detected (well, actually only those components that respond to * input are actually needed before the render phase). *

* The components in this tree will then be given the opportunity to examine new input * data provided by the user, and react in the appropriate manner for that component, * as specified for the JSF lifecycle. *

* Much of the work required by this method must be delegated to an instance * of StateManager. *

* If there is no record of the current user having been sent the specified view * (ie no saved state information available), then NULL should be returned. *

* Note that input data provided by the user may also be used to determine exactly * how to restore this view. In the case of "client side state", information * about the components to be restored will be available here. Even for * "server side state", user input may include an indicator that is used to * select among a number of different saved states available for this viewId and * this user. *

* Note that data received from users is inherently untrustworthy; care should be * taken to validate this information appropriately. *

* See writeState for more details. */ public abstract javax.faces.component.UIViewRoot restoreView(javax.faces.context.FacesContext context, String viewId); /** * Write sufficient information to context.externalContext.response in order to * be able to restore this view if the user performs a "postback" using that * rendered response. *

* For "client side state saving", sufficient information about the view * state should be written to allow a "restore view" operation to succeed * later. This does not necessarily mean storing all data about the * current view; only data that cannot be recreated from the "template" for * this view needs to be saved. *

* For "server side state saving", this method may write out nothing. Alternately * it may write out a "state identifier" to identify which of multiple saved * user states for a particular view should be selected (or just verify that the * saved state does indeed correspond to the expected one). */ public abstract void writeState(javax.faces.context.FacesContext context) throws java.io.IOException; }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy