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

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

The 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 jakarta.faces.application;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.stream.Stream;

import jakarta.faces.FacesException;
import jakarta.faces.component.UIViewRoot;
import jakarta.faces.context.ExternalContext;
import jakarta.faces.context.FacesContext;
import jakarta.faces.view.ViewDeclarationLanguage;

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

/**
 * 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 jakarta.servlet apis. This allows Faces to be used on servers that do not implement the * servlet API (for example, plain CGI). *

* Examples: *

    *
  • 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 jakarta.faces.lifecycle.Lifecycle}. *

* For the official specification for this class, see Faces Specification. */ public abstract class ViewHandler { public static final String CHARACTER_ENCODING_KEY = "jakarta.faces.request.charset"; public static final String DEFAULT_FACELETS_SUFFIX = ".xhtml"; @Deprecated(since = "4.0") public static final String DEFAULT_SUFFIX = ".xhtml"; /** * Indicate the default suffixes, separated by spaces to derive the default file URI * used by Faces to create views and render pages. */ @JSFWebConfigParam(defaultValue=".xhtml", since="1.1", group="viewhandler", deprecated = true) @Deprecated(since = "4.0") public static final String DEFAULT_SUFFIX_PARAM_NAME = "jakarta.faces.DEFAULT_SUFFIX"; /** * The default extension used to handle facelets pages. */ @JSFWebConfigParam(defaultValue=".xhtml", since="2.0", group="viewhandler") public static final String FACELETS_SUFFIX_PARAM_NAME = "jakarta.faces.FACELETS_SUFFIX"; /** * Set of extensions handled by facelets, separated by ';'. */ @JSFWebConfigParam(since="2.0", group="viewhandler") public static final String FACELETS_VIEW_MAPPINGS_PARAM_NAME = "jakarta.faces.FACELETS_VIEW_MAPPINGS"; /** * Define the default buffer size value passed to ExternalContext.setResponseBufferResponse() and in a * servlet environment to HttpServletResponse.setBufferSize(). */ @JSFWebConfigParam(since = "2.0", classType = "java.lang.Integer", tags = "performance", defaultValue="1024", desc = "Define the default buffer size value passed to ExternalContext.setResponseBufferResponse() and in " + "a servlet environment to HttpServletResponse.setBufferSize()") public static final java.lang.String FACELETS_BUFFER_SIZE_PARAM_NAME = "jakarta.faces.FACELETS_BUFFER_SIZE"; /** * Set of class names, separated by ';', implementing TagDecorator interface, used to transform * a view definition in a facelet abstract syntax tree, that is used later to generate a component tree. */ @JSFWebConfigParam(since = "2.0") public static final java.lang.String FACELETS_DECORATORS_PARAM_NAME = "jakarta.faces.FACELETS_DECORATORS"; /** * Set of .taglib.xml files, separated by ';' that should be loaded by facelet engine. */ @JSFWebConfigParam(since = "2.0", desc = "Set of .taglib.xml files, separated by ';' that should be loaded by facelet engine.") public static final java.lang.String FACELETS_LIBRARIES_PARAM_NAME = "jakarta.faces.FACELETS_LIBRARIES"; /** * Define the period used to refresh the facelet abstract syntax tree from the view definition file. */ @JSFWebConfigParam(since = "2.0", defaultValue = "0, -1 in Production", classType = "java.lang.Long", tags = "performance") public static final java.lang.String FACELETS_REFRESH_PERIOD_PARAM_NAME = "jakarta.faces.FACELETS_REFRESH_PERIOD"; /** * Skip comments found on a facelet file. */ @JSFWebConfigParam(since = "2.0") public static final java.lang.String FACELETS_SKIP_COMMENTS_PARAM_NAME = "jakarta.faces.FACELETS_SKIP_COMMENTS"; /** * @since Faces 1.2 */ public String calculateCharacterEncoding(FacesContext context) { String encoding = null; ExternalContext externalContext = context.getExternalContext(); String contentType = 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 jakarta.faces.application.Application#getSupportedLocales()} defines what locales this Faces * 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(FacesContext context); /** * Return the id of an available render-kit that should be used to map the Faces 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(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 UIViewRoot createView(FacesContext context, String viewId); /** * @param context * @param input * @return * * @since 2.0 */ public String deriveViewId(FacesContext context, String input) { //The default implementation of this method simply returns rawViewId unchanged. return input; } /** * * @param context * @param rawViewId * @return * @since 2.1 */ public String deriveLogicalViewId(FacesContext context, String rawViewId) { return rawViewId; } /** * Returns a URL, suitable for encoding and rendering, that (if activated) will cause the Faces * request processing lifecycle for the specified viewId to be executed */ public abstract String getActionURL(FacesContext context, String viewId); /** * Return a Faces action URL derived from the viewId argument that is suitable to be used as * the target of a link in a Faces response. Compiliant implementations must implement this method * as specified in section Faces.7.5.2. The default implementation simply calls through to * getActionURL(jakarta.faces.context.FacesContext, java.lang.String), passing the arguments context and viewId. * * @param context * @param viewId * @param parameters * @param includeViewParams * @return * * @since 2.0 */ public String getBookmarkableURL(FacesContext context, String viewId, Map> parameters, boolean includeViewParams) { return getActionURL(context, viewId); } /** * Return the ViewDeclarationLanguage instance used for this ViewHandler instance. *

* The default implementation of this method returns null. * * @param context * @param viewId * @return * * @since 2.0 */ public ViewDeclarationLanguage getViewDeclarationLanguage(FacesContext context, String viewId) { // TODO: In some places like RestoreViewExecutor, we are calling deriveViewId // TODO: after call restoreViewSupport.calculateViewId // Maybe this method should be called from here, because it is supposed that // calculateViewId "calculates the view id!" // here we return null to support pre jsf 2.0 ViewHandlers (e.g. com.sun.facelets.FaceletViewHandler), // because they don't provide any ViewDeclarationLanguage, // but in the default implementation (ViewHandlerImpl) we return vdlFactory.getViewDeclarationLanguage(viewId) return null; } /** * Return a Faces action URL derived from the viewId argument that is suitable to be used by * the NavigationHandler to issue a redirect request to the URL using a NonFaces request. * Compiliant implementations must implement this method as specified in section Faces.7.5.2. * The default implementation simply calls through to * getActionURL(jakarta.faces.context.FacesContext, java.lang.String), passing the arguments context and viewId. * * @param context * @param viewId * @param parameters * @param includeViewParams * @return * * @since 2.0 */ public String getRedirectURL(FacesContext context, String viewId, Map> parameters, boolean includeViewParams) { return getActionURL(context, viewId); } /** * Returns a URL, suitable for encoding and rendering, that (if activated) * will retrieve the specified web application resource. */ public abstract String getResourceURL(FacesContext context, String path); /** * Initialize the view for the request processing lifecycle. *

* This method must be called at the beginning of the Restore View Phase of the Request * Processing Lifecycle. It is responsible for performing any per-request initialization * necessary to the operation of the lifycecle. *

* The default implementation must perform the following actions. If * ExternalContext.getRequestCharacterEncoding() returns null, call * calculateCharacterEncoding(jakarta.faces.context.FacesContext) and pass the result, * if non-null, into the ExternalContext.setRequestCharacterEncoding(java.lang.String) method. * If ExternalContext.getRequestCharacterEncoding() returns non-null take no action. * * @since Faces 1.2 */ public void initView(FacesContext context) throws FacesException { String encoding = this.calculateCharacterEncoding(context); if (encoding != null) { try { context.getExternalContext().setRequestCharacterEncoding(encoding); } catch (UnsupportedEncodingException uee) { throw new FacesException(uee); } } } /** * Perform whatever actions are required to render the response view to the * response object associated with the current FacesContext. *

* Otherwise, the default implementation must obtain a reference to the * ViewDeclarationLanguage for the viewId of the argument viewToRender and call its * ViewDeclarationLanguage.renderView(jakarta.faces.context.FacesContext, jakarta.faces.component.UIViewRoot) * method, returning the result and not swallowing any exceptions thrown by that method. */ public abstract void renderView(FacesContext context, UIViewRoot viewToRender) throws IOException, FacesException; /** * Perform whatever actions are required to restore the view associated with the * specified FacesContext and viewId. It may delegate to the restoreView of the * associated StateManager to do the actual work of restoring the view. If there * is no available state for the specified viewId, return null. *

* Otherwise, the default implementation must obtain a reference to the * ViewDeclarationLanguage for this viewId and call its * ViewDeclarationLanguage.restoreView(jakarta.faces.context.FacesContext, java.lang.String) * method, returning the result and not swallowing any exceptions thrown by that method. */ public abstract UIViewRoot restoreView(FacesContext context, String viewId); /** * Take any appropriate action to either immediately write out the current state information * (by calling StateManager.writeState(jakarta.faces.context.FacesContext, java.lang.Object), * or noting where state information should later be written. *

* This method must do nothing if the current request is an Ajax request. When responding * to Ajax requests, the state is obtained by calling StateManager.getViewState(jakarta.faces.context.FacesContext) * and then written into the Ajax response during * final encoding (UIViewRoot.encodeEnd(jakarta.faces.context.FacesContext). */ public abstract void writeState(FacesContext context) throws IOException; /** * @since 2.2 * @param urlPattern */ public void addProtectedView(String urlPattern) { } /** * @since 2.2 * @param urlPattern */ public boolean removeProtectedView(String urlPattern) { return false; } /** * @since 2.2 * @return */ public Set getProtectedViewsUnmodifiable() { Set set = Collections.emptySet(); return Collections.unmodifiableSet(set); } /** * Return a Faces URL that represents a websocket connection for the passed channel and channelToken * * @since 2.3 * @param context * @param channelAndToken * @return */ public abstract String getWebsocketURL(FacesContext context, String channelAndToken); /** * @since 2.3 * @param facesContext * @param path * @param options * @return */ public Stream getViews(FacesContext facesContext, String path, ViewVisitOption... options) { return getViews(facesContext, path, Integer.MAX_VALUE, options); } /** * * @since 2.3 * @param facesContext * @param path * @param maxDepth * @param options * @return */ public Stream getViews(FacesContext facesContext, String path, int maxDepth, ViewVisitOption... options) { return Stream.empty(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy