/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development * and Distribution License("CDDL") (collectively, the "License"). You * may not use this file except in compliance with the License. You can * obtain a copy of the License at * https://glassfish.java.net/public/CDDL+GPL_1_1.html * or packager/legal/LICENSE.txt. See the License for the specific * language governing permissions and limitations under the License. * * When distributing the software, include this License Header Notice in each * file and include the License file at packager/legal/LICENSE.txt. * * GPL Classpath Exception: * Oracle designates this particular file as subject to the "Classpath" * exception as provided by Oracle in the GPL Version 2 section of the License * file that accompanied this code. * * Modifications: * If applicable, add the following below the License Header, with the fields * enclosed by brackets [] replaced by your own identifying information: * "Portions Copyright [year] [name of copyright owner]" * * Contributor(s): * If you wish your version of this file to be governed by only the CDDL or * only the GPL Version 2, indicate your decision by adding "[Contributor] * elects to include this software in this distribution under the [CDDL or GPL * Version 2] license." If you don't indicate a single choice of license, a * recipient has the option to distribute your version of this file under * either the CDDL, the GPL Version 2 or to extend the choice of license to * its licensees as provided above. However, if you add GPL Version 2 code * and therefore, elected the GPL Version 2 license, then the option applies * only if the new code is made subject to such option by the copyright * holder. */ package javax.faces.application; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.Locale; import java.util.ResourceBundle; import java.util.Map; import javax.faces.FacesException; import javax.faces.component.UIComponent; import javax.faces.component.behavior.Behavior; import javax.faces.context.FacesContext; import javax.faces.convert.Converter; import javax.faces.el.MethodBinding; import javax.faces.el.PropertyResolver; import javax.faces.el.ReferenceSyntaxException; import javax.faces.el.ValueBinding; import javax.faces.el.VariableResolver; import javax.faces.event.ActionListener; import javax.el.ELContextListener; import javax.el.ExpressionFactory; import javax.el.ValueExpression; import javax.el.ELException; import javax.el.ELResolver; import javax.faces.component.search.SearchExpressionHandler; import javax.faces.component.search.SearchKeywordResolver; import javax.faces.event.SystemEvent; import javax.faces.event.SystemEventListener; import javax.faces.flow.FlowHandler; import javax.faces.validator.Validator; import javax.faces.view.ViewDeclarationLanguage; /** * <p> * <strong class="changed_modified_2_0 changed_modified_2_0_rev_a changed_modified_2_2 * changed_modified_2_3">Application</strong> represents a per-web-application singleton object * where applications based on JavaServer Faces (or implementations wishing to provide extended * functionality) can register application-wide singletons that provide functionality required by * JavaServer Faces. Default implementations of each object are provided for cases where the * application does not choose to customize the behavior. * </p> * * <p> * The instance of {@link Application} is created by calling the <code>getApplication()</code> * method of {@link ApplicationFactory}. Because this instance is shared, it must be implemented in * a thread-safe manner. * </p> * * <p> * The application also acts as a factory for several types of Objects specified in the Faces * Configuration file. Please see {@link Application#createComponent}, * {@link Application#createConverter}, and {@link Application#createValidator}. * </p> */ public abstract class Application { @SuppressWarnings({ "UnusedDeclaration" }) private Application defaultApplication; // ------------------------------------------------------------- Properties /** * <p> * <span class="changed_modified_2_2">Return</span> the default {@link ActionListener} to be * registered for all {@link javax.faces.component.ActionSource} components in this application. * If not explicitly set, a default implementation must be provided that performs the * <span class="changed_modified_2_2">functions as specified in the section titled * "ActionListener Property" in the chapter titled "Application Integration" of the spec prose * document.</span> * </p> * * <p> * Note that the specification for the default <code>ActionListener</code> contiues to call for * the use of a <strong>deprecated</strong> property (<code>action</code>) and class * (<code>MethodBinding</code>). Unfortunately, this is necessary because the default * <code>ActionListener</code> must continue to work with components that do not implement * {@link javax.faces.component.ActionSource2}, and only implement * {@link javax.faces.component.ActionSource}. * </p> * * @return the action listener. */ public abstract ActionListener getActionListener(); /** * <p> * Set the default {@link ActionListener} to be registered for all * {@link javax.faces.component.ActionSource} components. * </p> * * @param listener The new default {@link ActionListener} * * @throws NullPointerException if <code>listener</code> is <code>null</code> */ public abstract void setActionListener(ActionListener listener); /** * <p> * Return the default <code>Locale</code> for this application. If not explicitly set, * <code>null</code> is returned. * </p> * * @return the default Locale, or <code>null</code>. */ public abstract Locale getDefaultLocale(); /** * <p> * Set the default <code>Locale</code> for this application. * </p> * * @param locale The new default <code>Locale</code> * * @throws NullPointerException if <code>locale</code> is <code>null</code> */ public abstract void setDefaultLocale(Locale locale); /** * <p> * Return the <code>renderKitId</code> to be used for rendering this application. If not * explicitly set, <code>null</code> is returned. * </p> * * @return the default render kit id, or <code>null</code>. */ public abstract String getDefaultRenderKitId(); /** * <p> * Set the <code>renderKitId</code> to be used to render this application. Unless the client has * provided a custom {@link ViewHandler} that supports the use of multiple * {@link javax.faces.render.RenderKit} instances in the same application, this method must only * be called at application startup, before any Faces requests have been processed. This is a * limitation of the current Specification, and may be lifted in a future release. * </p> * * @param renderKitId the render kit id to set. */ public abstract void setDefaultRenderKitId(String renderKitId); /** * <p> * Return the fully qualified class name of the <code>ResourceBundle</code> to be used for * JavaServer Faces messages for this application. If not explicitly set, <code>null</code> is * returned. * </p> * * @return the message bundle class name, or <code>null</code>. */ public abstract String getMessageBundle(); /** * <p> * Set the fully qualified class name of the <code>ResourceBundle</code> to be used for * JavaServer Faces messages for this application. See the JavaDocs for the * <code>java.util.ResourceBundle</code> class for more information about the syntax for * resource bundle names. * </p> * * @param bundle Base name of the resource bundle to be used * * @throws NullPointerException if <code>bundle</code> is <code>null</code> */ public abstract void setMessageBundle(String bundle); /** * <p> * Return the {@link NavigationHandler} instance that will be passed the outcome returned by any * invoked application action for this web application. If not explicitly set, a default * implementation must be provided that performs the functions described in the * {@link NavigationHandler} class description. * </p> * * <div class="changed_added_2_3"> * <ul> * <li>The <code>NavigationHandler</code> implementation is declared in the application * configuration resources by giving the fully qualified class name as the value of the * <code><navigation-handler></code> element within the <code><application></code> * element.</li> * </ul> * <p> * The runtime must employ the decorator pattern as for every other pluggable artifact in JSF. * </p> * </div> * * @return the navigation handler. */ public abstract NavigationHandler getNavigationHandler(); /** * <p> * Set the {@link NavigationHandler} instance that will be passed the outcome returned by any * invoked application action for this web application. * </p> * * @param handler The new {@link NavigationHandler} instance * * @throws NullPointerException if <code>handler</code> is <code>null</code> */ public abstract void setNavigationHandler(NavigationHandler handler); /** * <p class="changed_added_2_0"> * Return the singleton, stateless, thread-safe {@link ResourceHandler} for this application. * The JSF implementation must support the following techniques for declaring an alternate * implementation of <code>ResourceHandler</code>. * </p> * <div class="changed_added_2_0"> * <ul> * <li> * <p> * The <code>ResourceHandler</code> implementation is declared in the application configuration * resources by giving the fully qualified class name as the value of the * <code><resource-handler></code> element within the <code><application></code> * element. * </p> * </li> * </ul> * <p> * In all of the above cases, the runtime must employ the decorator pattern as for every other * pluggable artifact in JSF. * </p> * * <p class="changed_added_2_0"> * A default implementation is provided that throws <code>UnsupportedOperationException</code> * so that users that decorate <code>Application</code> can continue to function * </p> * . * * * </div> * * @return the resource handler. * @since 2.0 */ public ResourceHandler getResourceHandler() { if (defaultApplication != null) { return defaultApplication.getResourceHandler(); } throw new UnsupportedOperationException(); } /** * <p class="changed_added_2_0"> * Set the {@link ResourceHandler} instance that will be utilized for rendering the markup for * resources, and for satisfying client requests to serve up resources. * </p> * <div class="changed_added_2_0"> * * @param resourceHandler The new <code>ResourceHandler</code> instance * * @throws IllegalStateException if this method is called after at least one request has been * processed by the <code>Lifecycle</code> instance for this application. * @throws NullPointerException if <code>resourceHandler</code> is <code>null</code> </div> * @since 2.0 */ public void setResourceHandler(ResourceHandler resourceHandler) { if (defaultApplication != null) { defaultApplication.setResourceHandler(resourceHandler); } else { throw new UnsupportedOperationException(); } } /** * <p> * Return a {@link PropertyResolver} instance that wraps the {@link ELResolver} instance that * Faces provides to the unified EL for the resolution of expressions that appear * programmatically in an application. * </p> * * <p> * Note that this no longer returns the default <code>PropertyResolver</code> since that class * is now a no-op that aids in allowing custom <code>PropertyResolver</code>s to affect the EL * resolution process. * </p> * * @return the property resolver. * @deprecated This has been replaced by {@link #getELResolver}. */ public abstract PropertyResolver getPropertyResolver(); /** * <p> * Set the {@link PropertyResolver} instance that will be utilized to resolve method and value * bindings. * </p> * * <p> * This method is now deprecated but the implementation must cause the argument to be set as the * head of the legacy <code>PropertyResolver</code> chain, replacing any existing value that was * set from the application configuration resources. * </p> * * <p> * It is illegal to call this method after the application has received any requests from the * client. If an attempt is made to register a listener after that time it must have no effect. * </p> * * @param resolver The new {@link PropertyResolver} instance * * @throws NullPointerException if <code>resolver</code> is <code>null</code> * * @deprecated The recommended way to affect the execution of the EL is to provide an * <code><el-resolver></code> element at the right place in the application * configuration resources which will be considered in the normal course of * expression evaluation. This method now will cause the argument * <code>resolver</code> to be wrapped inside an implementation of * {@link ELResolver} and exposed to the EL resolution system as if the user had * called {@link #addELResolver}. * * @throws IllegalStateException if called after the first request to the * {@link javax.faces.webapp.FacesServlet} has been serviced. */ public abstract void setPropertyResolver(PropertyResolver resolver); /** * <p> * Find a <code>ResourceBundle</code> as defined in the application configuration resources * under the specified name. If a <code>ResourceBundle</code> was defined for the name, return * an instance that uses the locale of the current {@link javax.faces.component.UIViewRoot}. * </p> * * <p> * The default implementation throws <code>UnsupportedOperationException</code> and is provided * for the sole purpose of not breaking existing applications that extend this class. * </p> * * @param ctx the Faces context. * @param name the name of the resource bundle. * @return the resource bundle. * @throws FacesException if a bundle was defined, but not resolvable * @throws NullPointerException if ctx == null || name == null * @since 1.2 */ public ResourceBundle getResourceBundle(FacesContext ctx, String name) { if (defaultApplication != null) { return defaultApplication.getResourceBundle(ctx, name); } throw new UnsupportedOperationException(); } /** * <p class="changed_added_2_0"> * Return the project stage for the currently running application instance. The default value is * {@link ProjectStage#Production} * </p> * * <div class="changed_added_2_0"> * <p> * The implementation of this method must perform the following algorithm or an equivalent with * the same end result to determine the value to return. * </p> * * <blockquote> * * <p> * If the value has already been determined by a previous call to this method, simply return * that value. * </p> * * <p> * Look for a <code>JNDI</code> environment entry under the key given by the value of * {@link ProjectStage#PROJECT_STAGE_JNDI_NAME} (return type of <code>java.lang.String</code>). * If found, continue with the algorithm below, otherwise, look for an entry in the * <code>initParamMap</code> of the <code>ExternalContext</code> from the current * <code>FacesContext</code> with the key given by the value of * {@link ProjectStage#PROJECT_STAGE_PARAM_NAME} * * </p> * * <p> * If a value is found, see if an enum constant can be obtained by calling * <code>ProjectStage.valueOf()</code>, passing the value from the <code>initParamMap</code>. If * this succeeds without exception, save the value and return it. * </p> * * <p> * If not found, or any of the previous attempts to discover the enum constant value have * failed, log a descriptive error message, assign the value as * <code>ProjectStage.Production</code> and return it. * </p> * * </blockquote> * * <p class="changed_added_2_0"> * A default implementation is provided that throws <code>UnsupportedOperationException</code> * so that users that decorate <code>Application</code> can continue to function * </p> * . * * </div> * * @return the project stage. * @since 2.0 */ public ProjectStage getProjectStage() { if (defaultApplication != null) { return defaultApplication.getProjectStage(); } return ProjectStage.Production; } /** * <p> * Return the {@link VariableResolver} that wraps the {@link ELResolver} instance that Faces * provides to the unified EL for the resolution of expressions that appear programmatically in * an application. The implementation of the <code>VariableResolver</code>must pass * <code>null</code> as the base argument for any methods invoked on the underlying * <code>ELResolver</code>. * </p> * * <p> * Note that this method no longer returns the default <code>VariableResolver</code>, since that * class now is a no-op that aids in allowing custom <code>VariableResolver</code>s to affect * the EL resolution process. * </p> * * @return the variable resolver. * @deprecated This has been replaced by {@link #getELResolver}. */ public abstract VariableResolver getVariableResolver(); /** * <p> * Set the {@link VariableResolver} instance that will be consulted to resolve method and value * bindings. * </p> * * <p> * This method is now deprecated but the implementation must cause the argument to be set as the * head of the legacy <code>VariableResolver</code> chain, replacing any existing value that was * set from the application configuration resources. * </p> * * <p> * It is illegal to call this method after the application has received any requests from the * client. If an attempt is made to register a listener after that time it must have no effect. * </p> * * @param resolver The new {@link VariableResolver} instance * * @throws NullPointerException if <code>resolver</code> is <code>null</code> * * @deprecated The recommended way to affect the execution of the EL is to provide an * <code><el-resolver></code> element at the * * right place in the application configuration resources which will be considered * in the normal course of expression evaluation. This method now will cause the * argument <code>resolver</code> to be wrapped inside an implementation of * {@link ELResolver} and exposed to the EL resolution system as if the user had * called {@link #addELResolver}. * * @throws IllegalStateException if called after the first request to the * {@link javax.faces.webapp.FacesServlet} has been serviced. */ public abstract void setVariableResolver(VariableResolver resolver); /** * <p> * <span class="changed_modified_2_0_rev_a">Cause</span> an the argument <code>resolver</code> * to be added to the resolver chain as specified in section JSF.5.5.1 of the JavaServer Faces * Specification. * </p> * * <p> * It is not possible to remove an <code>ELResolver</code> registered with this method, once it * has been registered. * </p> * * <p> * It is illegal to register an <code>ELResolver</code> after the application has received any * requests from the client. If an attempt is made to register a listener after that time, an * <code>IllegalStateException</code> must be thrown. This restriction is in place to allow the * JSP container to optimize for the common case where no additional <code>ELResolver</code>s * are in the chain, aside from the standard ones. It is permissible to add * <code>ELResolver</code>s before or after initialization to a <code>CompositeELResolver</code> * that is already in the chain. * </p> * * <p> * The default implementation throws <code>UnsupportedOperationException</code> and is provided * for the sole purpose of not breaking existing applications that extend {@link Application}. * </p> * * @throws IllegalStateException <span class="changed_modified_2_0_rev_a">if called after the * first request to the {@link javax.faces.webapp.FacesServlet} has been * serviced.</span> * * @param resolver the EL resolver to add. * @since 1.2 */ public void addELResolver(ELResolver resolver) { if (defaultApplication != null) { defaultApplication.addELResolver(resolver); } else { throw new UnsupportedOperationException(); } } /** * <p> * Return the singleton {@link ELResolver} instance to be used for all EL resolution. This is * actually an instance of {@link javax.el.CompositeELResolver} that must contain the following * <code>ELResolver</code> instances in the following order: * </p> * * <ol> * * <li> * <p> * <code>ELResolver</code> instances declared using the <el-resolver> element in the * application configuration resources. * </p> * </li> * * <li> * <p> * An <code>implementation</code> that wraps the head of the legacy * <code>VariableResolver</code> chain, as per section <i>VariableResolver ChainWrapper</i> in * Chapter JSF.5 in the spec document. * </p> * </li> * * <li> * <p> * An <code>implementation</code> that wraps the head of the legacy * <code>PropertyResolver</code> chain, as per section <i>PropertyResolver ChainWrapper</i> in * Chapter JSF.5 in the spec document. * </p> * </li> * * <li> * <p> * Any <code>ELResolver</code> instances added by calls to {@link #addELResolver}. * </p> * </li> * * </ol> * * <p> * The default implementation throws <code>UnsupportedOperationException</code> and is provided * for the sole purpose of not breaking existing applications that extend {@link Application}. * </p> * * @return the EL resolver. * @since 1.2 */ public ELResolver getELResolver() { if (defaultApplication != null) { return defaultApplication.getELResolver(); } throw new UnsupportedOperationException(); } /** * <p class="changed_added_2_2"> * Return the thread-safe singleton {@link FlowHandler} for this application. For * implementations declaring compliance with version 2.2 of the specification, this method must * never return {@code null}, even if the application has no flows. This is necessary to enable * dynamic flow creation during the application's lifetime. * </p> * * <div class="changed_added_2_2"> * * <p> * All implementations that declare compliance with version 2.2 of the specification must * implement this method. For the purpose of backward compatibility with environments that * extend {@code * Application} but do not override this method, an implementation is provided that returns * {@code null}. Due to the decoratable nature of {@code Application}, code calling this method * should always check for a {@code null} return. * </p> * </div> * * @return the flow handler. * @since 2.2 */ public FlowHandler getFlowHandler() { if (defaultApplication != null) { return defaultApplication.getFlowHandler(); } return null; } /** * <p class="changed_added_2_2"> * Set the {@link FlowHandler} instance used by the {@link NavigationHandler} to satisfy the * requirements of the faces flows feature. * </p> * * @param newHandler the flow handler to set. * @throws NullPointerException if newHandler is <code>null</code> * @throws IllegalStateException if this method is called after at least one request has been * processed by the {@code Lifecycle} instance for this application. * @since 2.2 */ public void setFlowHandler(FlowHandler newHandler) { if (defaultApplication != null) { defaultApplication.setFlowHandler(newHandler); } } /** * <p> * Return the {@link ViewHandler} instance that will be utilized during the <em>Restore * View</em> and <em>Render Response</em> phases of the request processing lifecycle. If not * explicitly set, a default implementation must be provided that performs the functions * described in the {@link ViewHandler} description in the JavaServer Faces Specification. * </p> * * @return the view handler. */ public abstract ViewHandler getViewHandler(); /** * <p> * Set the {@link ViewHandler} instance that will be utilized during the <em>Restore View</em> * and <em>Render Response</em> phases of the request processing lifecycle. * </p> * * @param handler The new {@link ViewHandler} instance * * @throws IllegalStateException if this method is called after at least one request has been * processed by the <code>Lifecycle</code> instance for this application. * @throws NullPointerException if <code>handler</code> is <code>null</code> */ public abstract void setViewHandler(ViewHandler handler); /** * <p> * Return the {@link StateManager} instance that will be utilized during the <em>Restore * View</em> and <em>Render Response</em> phases of the request processing lifecycle. If not * explicitly set, a default implementation must be provided that performs the functions * described in the {@link StateManager} description in the JavaServer Faces Specification. * </p> * * @return the state manager. */ public abstract StateManager getStateManager(); /** * <p> * Set the {@link StateManager} instance that will be utilized during the <em>Restore View</em> * and <em>Render Response</em> phases of the request processing lifecycle. * </p> * * @param manager The new {@link StateManager} instance * * @throws IllegalStateException if this method is called after at least one request has been * processed by the <code>Lifecycle</code> instance for this application. * @throws NullPointerException if <code>manager</code> is <code>null</code> */ public abstract void setStateManager(StateManager manager); // ------------------------------------------------------- Object Factories /** * <p> * <span class="changed_added_2_0">Register</span> a new mapping of behavior id to the name of * the corresponding {@link Behavior} class. This allows subsequent calls to * <code>createBehavior()</code> to serve as a factory for {@link Behavior} instances. * </p> * * @param behaviorId The behavior id to be registered * @param behaviorClass The fully qualified class name of the corresponding {@link Behavior} * implementation * * @throws NullPointerException if <code>behaviorId</code> or <code>behaviorClass</code> is * <code>null</code> * * @since 2.0 */ public void addBehavior(String behaviorId, String behaviorClass) { if (defaultApplication != null) { defaultApplication.addBehavior(behaviorId, behaviorClass); } } /** * <p> * <span class="changed_added_2_0">Instantiate</span> and return a new {@link Behavior} instance * of the class specified by a previous call to <code>addBehavior()</code> for the specified * behavior id. * </p> * * @param behaviorId The behavior id for which to create and return a new {@link Behavior} * instance * @return the behavior. * @throws FacesException if the {@link Behavior} cannot be created * @throws NullPointerException if <code>behaviorId</code> is <code>null</code> */ public Behavior createBehavior(String behaviorId) throws FacesException { if (defaultApplication != null) { return defaultApplication.createBehavior(behaviorId); } return null; } /** * <p> * Return an <code>Iterator</code> over the set of currently registered behavior ids for this * <code>Application</code>. * </p> * * @return an iterator with behavior ids. */ public Iterator<String> getBehaviorIds() { if (defaultApplication != null) { return defaultApplication.getBehaviorIds(); } return Collections.EMPTY_LIST.iterator(); } /** * <p> * Register a new mapping of component type to the name of the corresponding {@link UIComponent} * class. This allows subsequent calls to <code>createComponent()</code> to serve as a factory * for {@link UIComponent} instances. * </p> * * @param componentType The component type to be registered * @param componentClass The fully qualified class name of the corresponding {@link UIComponent} * implementation * * @throws NullPointerException if <code>componentType</code> or <code>componentClass</code> is * <code>null</code> */ public abstract void addComponent(String componentType, String componentClass); /** * <p> * <span class="changed_modified_2_0">Instantiate</span> and return a new {@link UIComponent} * instance of the class specified by a previous call to <code>addComponent()</code> for the * specified component type. * </p> * * <p class="changed_added_2_0"> * Before the component instance is returned, it must be inspected for the presence of a * {@link javax.faces.event.ListenerFor} (or {@link javax.faces.event.ListenersFor}) or * {@link ResourceDependency} (or {@link ResourceDependencies}) annotation. If any of these * annotations are present, the action listed in {@link javax.faces.event.ListenerFor} or * {@link ResourceDependency} must be taken on the component, before it is returned from this * method. This variant of <code>createComponent</code> must <strong>not</strong> inspect the * {@link javax.faces.render.Renderer} for the component to be returned for any of the afore * mentioned annotations. Such inspection is the province of * {@link #createComponent(ValueExpression, FacesContext, String, String)} or * {@link #createComponent(FacesContext, String, String)}. * </p> * * @param componentType The component type for which to create and return a new * {@link UIComponent} instance * @return the UI component. * @throws FacesException if a {@link UIComponent} of the specified type cannot be created * @throws NullPointerException if <code>componentType</code> is <code>null</code> */ public abstract UIComponent createComponent(String componentType) throws FacesException; /** * <p> * Wrap the argument <code>componentBinding</code> in an implementation of * {@link ValueExpression} and call through to * {@link #createComponent(javax.el.ValueExpression,javax.faces.context.FacesContext,java.lang.String)}. * </p> * * @param componentBinding {@link ValueBinding} representing a component value binding * expression (typically specified by the <code>component</code> attribute of a * custom tag) * @param context {@link FacesContext} for the current request * @param componentType Component type to create if the {@link ValueBinding} does not return a * component instance * @return the UI component. * @throws FacesException if a {@link UIComponent} cannot be created * @throws NullPointerException if any parameter is <code>null</code> * @deprecated This has been replaced by * {@link #createComponent(javax.el.ValueExpression,javax.faces.context.FacesContext,java.lang.String)}. */ public abstract UIComponent createComponent(ValueBinding componentBinding, FacesContext context, String componentType) throws FacesException; /** * <p> * <span class="changed_modified_2_0">Call</span> the <code>getValue()</code> method on the * specified {@link ValueExpression}. If it returns a {@link UIComponent} instance, return it as * the value of this method. If it does not, instantiate a new {@link UIComponent} instance of * the specified component type, pass the new component to the <code>setValue()</code> method of * the specified {@link ValueExpression}, and return it. * </p> * * <p class="changed_added_2_0"> * Before the component instance is returned, it must be inspected for the presence of a * {@link javax.faces.event.ListenerFor} (or {@link javax.faces.event.ListenersFor}) or * {@link ResourceDependency} (or {@link ResourceDependencies}) annotation. If any of these * annotations are present, the action listed in {@link javax.faces.event.ListenerFor} or * {@link ResourceDependency} must be taken on the component, before it is returned from this * method. This variant of <code>createComponent</code> must <strong>not</strong> inspect the * {@link javax.faces.render.Renderer} for the component to be returned for any of the afore * mentioned annotations. Such inspection is the province of * {@link #createComponent(ValueExpression, FacesContext, String, String)} or * {@link #createComponent(FacesContext, String, String)}. * </p> * * <p> * A default implementation is provided that throws <code>UnsupportedOperationException</code> * so that users that decorate <code>Application</code> can continue to function. * </p> * * @param componentExpression {@link ValueExpression} representing a component value expression * (typically specified by the <code>component</code> attribute of a custom tag) * @param context {@link FacesContext} for the current request * @param componentType Component type to create if the {@link ValueExpression} does not return * a component instance * @return the UI component. * @throws FacesException if a {@link UIComponent} cannot be created * @throws NullPointerException if any parameter is <code>null</code> * @since 1.2 */ public UIComponent createComponent(ValueExpression componentExpression, FacesContext context, String componentType) throws FacesException { if (defaultApplication != null) { return defaultApplication.createComponent(componentExpression, context, componentType); } throw new UnsupportedOperationException(); } /** * <p class="changed_added_2_0"> * Like {@link #createComponent(ValueExpression, FacesContext, String)} except the * <code>Renderer</code> for the component to be returned must be inspected for the annotations * mentioned in {@link #createComponent(ValueExpression, FacesContext, String)} as specified in * the documentation for that method. The <code>Renderer</code> instance to inspect must be * obtained by calling {@link FacesContext#getRenderKit} and calling * {@link javax.faces.render.RenderKit#getRenderer} on the result, passing the argument * <code>componentType</code> as the first argument and the result of calling * {@link UIComponent#getFamily} on the newly created component as the second argument. If no * such <code>Renderer</code> can be found, a message must be logged with a helpful error * message. Otherwise, {@link UIComponent#setRendererType} must be called on the newly created * <code>UIComponent</code> instance, passing the argument <code>rendererType</code> as the * argument. * </p> * * <p class="changed_added_2_0"> * A default implementation is provided that throws <code>UnsupportedOperationException</code> * so that users that decorate <code>Application</code> can continue to function. * </p> * * * @param componentExpression {@link ValueExpression} representing a component value expression * (typically specified by the <code>component</code> attribute of a custom tag) * @param context {@link FacesContext} for the current request * @param componentType Component type to create if the {@link ValueExpression} does not return * a component instance * @param rendererType The renderer-type of the <code>Renderer</code> that will render this * component. A <code>null</code> value must be accepted for this parameter. * @return the UI component. * @throws FacesException if a {@link UIComponent} cannot be created * @throws NullPointerException if any of the parameters <code>componentExpression</code>, * <code>context</code>, or <code>componentType</code> are <code>null</code> * @since 2.0 */ public UIComponent createComponent(ValueExpression componentExpression, FacesContext context, String componentType, String rendererType) { if (defaultApplication != null) { return defaultApplication.createComponent(componentExpression, context, componentType, rendererType); } throw new UnsupportedOperationException(); } /** * <p class="changed_added_2_0"> * Like {@link #createComponent(String)} except the <code>Renderer</code> for the component to * be returned must be inspected for the annotations mentioned in * {@link #createComponent(ValueExpression, FacesContext, String)} as specified in the * documentation for that method. The <code>Renderer</code> instance to inspect must be obtained * by calling {@link FacesContext#getRenderKit} and calling * {@link javax.faces.render.RenderKit#getRenderer} on the result, passing the argument * <code>componentType</code> as the first argument and the result of calling * {@link UIComponent#getFamily} on the newly created component as the second argument. If no * such <code>Renderer</code> can be found, a message must be logged with a helpful error * message. Otherwise, {@link UIComponent#setRendererType} must be called on the newly created * <code>UIComponent</code> instance, passing the argument <code>rendererType</code> as the * argument. * </p> * * <p class="changed_added_2_0"> * A default implementation is provided that throws <code>UnsupportedOperationException</code> * so that users that decorate <code>Application</code> can continue to function * </p> * . * * * @param context {@link FacesContext} for the current request * @param componentType Component type to create * @param rendererType The renderer-type of the <code>Renderer</code> that will render this * component. A <code>null</code> value must be accepted for this parameter. * @return the UI component. * @throws FacesException if a {@link UIComponent} cannot be created * @throws NullPointerException if any of the parameters <code>context</code>, or * <code>componentType</code> are <code>null</code> * @since 2.0 */ public UIComponent createComponent(FacesContext context, String componentType, String rendererType) { if (defaultApplication != null) { return defaultApplication.createComponent(context, componentType, rendererType); } throw new UnsupportedOperationException(); } /** * <p class="changed_added_2_0"> * <span class="changed_modified_2_0_rev_a">Instantiate</span> and return a new * {@link UIComponent} instance from the argument {@link Resource}. An algorithm semantically * equivalent to the following must be followed to instantiate the <code>UIComponent</code> to * return. * </p> * * <div class="changed_added_2_0"> * * <ul> * * <li> * <p> * Obtain a reference to the {@link ViewDeclarationLanguage} for this <code>Application</code> * instance by calling {@link ViewHandler#getViewDeclarationLanguage}, passing the * <code>viewId</code> found by calling {@link javax.faces.component.UIViewRoot#getViewId} on * the {@link javax.faces.component.UIViewRoot} in the argument {@link FacesContext}. * </p> * </li> * * * <li> * <p> * Obtain a reference to the <em>composite component metadata</em> for this composite component * by calling {@link ViewDeclarationLanguage#getComponentMetadata}, passing the * <code>facesContext</code> and <code>componentResource</code> arguments to this method. This * version of JSF specification uses JavaBeans as the API to the component metadata. * </p> * </li> * * <li> * <p> * Determine if the component author declared a <code><span class="changed_modified_2_0_rev_a">componentType</span></code> for this component instance by * obtaining the <code>BeanDescriptor</code> from the component metadata and calling its * <code>getValue()</code> method, passing {@link UIComponent#COMPOSITE_COMPONENT_TYPE_KEY} as * the argument. If non-<code>null</code>, the result must be a <code>ValueExpression</code> * whose value is the <code>component-type</code> of the <code>UIComponent</code> to be created * for this <code>Resource</code> component. Call through to * {@link #createComponent(java.lang.String)} to create the component. * </p> * </li> * * <li> * <p> * Otherwise, determine if a script based component for this <code>Resource</code> can be found * by calling {@link ViewDeclarationLanguage#getScriptComponentResource}. If the result is * non-<code>null</code>, and is a script written in one of the languages listed in JSF.4.3 of * the specification prose document, create a <code>UIComponent</code> instance from the script * resource. * </p> * </li> * * <li> * <p> * Otherwise, let <em>library-name</em> be the return from calling * {@link Resource#getLibraryName} on the argument <code>componentResource</code> and * <em>resource-name</em> be the return from calling {@link Resource#getResourceName} on the * argument <code>componentResource</code>. Create a fully qualified Java class name by removing * any file extension from <em>resource-name</em> and let <em>fqcn</em> be * <code><em>library-name</em> + "." + <em>resource-name</em></code>. If a class with the name of <em>fqcn</em> cannot be found, take * no action and continue to the next step. If any of <code>InstantiationException</code>, * <code>IllegalAccessException</code>, or <code>ClassCastException</code> are thrown, wrap the * exception in a <code>FacesException</code> and re-throw it. If any other exception is thrown, * log the exception and continue to the next step. * </p> * </li> * * <li> * <p> * If none of the previous steps have yielded a <code>UIComponent</code> instance, call * {@link #createComponent(java.lang.String)} passing "<code>javax.faces.NamingContainer</code>" * as the argument. * </p> * </li> * * <li> * <p> * Call {@link UIComponent#setRendererType} on the <code>UIComponent</code> instance, passing * "<code>javax.faces.Composite</code>" as the argument. * </p> * </li> * * <li> * * <p> * Store the argument <code>Resource</code> in the attributes <code>Map</code> of the * <code>UIComponent</code> under the key, {@link Resource#COMPONENT_RESOURCE_KEY}. * </p> * * </li> * * <li> * * <p> * Store <em>composite component metadata</em> in the attributes <code>Map</code> of the * <code>UIComponent</code> under the key, {@link UIComponent#BEANINFO_KEY}. * </p> * * </li> * * </ul> * * <p> * Before the component instance is returned, it must be inspected for the presence of a * {@link javax.faces.event.ListenerFor} annotation. If this annotation is present, the action * listed in {@link javax.faces.event.ListenerFor} must be taken on the component, before it is * returned from this method. * </p> * * <p> * A default implementation is provided that throws <code>UnsupportedOperationException</code> * so that users that decorate <code>Application</code> can continue to function. * </p> * * </div> * * @param context {@link FacesContext} for the current request * @param componentResource A {@link Resource} that points to a source file that provides an * implementation of a component. * @return the UI component. * @throws FacesException if a {@link UIComponent} from the {@link Resource} cannot be created * @throws NullPointerException if any parameter is <code>null</code> * @throws NullPointerException if unable, for any reason, to obtain a * <code>ViewDeclarationLanguage</code> instance as described above. * @since 2.0 */ public UIComponent createComponent(FacesContext context, Resource componentResource) { if (defaultApplication != null) { return defaultApplication.createComponent(context, componentResource); } throw new UnsupportedOperationException(); } /** * <p> * Return an <code>Iterator</code> over the set of currently defined component types for this * <code>Application</code>. * </p> * * @return an iterator with component types. */ public abstract Iterator<String> getComponentTypes(); /** * <p> * Register a new mapping of converter id to the name of the corresponding {@link Converter} * class. This allows subsequent calls to <code>createConverter()</code> to serve as a factory * for {@link Converter} instances. * </p> * * @param converterId The converter id to be registered * @param converterClass The fully qualified class name of the corresponding {@link Converter} * implementation * * @throws NullPointerException if <code>converterId</code> or <code>converterClass</code> is * <code>null</code> */ public abstract void addConverter(String converterId, String converterClass); /** * <p> * Register a new converter class that is capable of performing conversions for the specified * target class. * </p> * * @param targetClass The class for which this converter is registered * @param converterClass The fully qualified class name of the corresponding {@link Converter} * implementation * * @throws NullPointerException if <code>targetClass</code> or <code>converterClass</code> is * <code>null</code> */ public abstract void addConverter(Class<?> targetClass, String converterClass); /** * <p> * <span class="changed_modified_2_0">Instantiate</span> and return a new {@link Converter} * instance of the class specified by a previous call to <code>addConverter()</code> for the * specified converter id. * </p> * * <p class="changed_added_2_0"> * If the <code>toLowerCase()</code> of the <code>String</code> represenation of the value of * the "<code>javax.faces.DATETIMECONVERTER_DEFAULT_TIMEZONE_IS_SYSTEM_TIMEZONE</code>" * application configuration parameter is "<code>true</code>" (without the quotes) and the * <code>Converter</code> instance to be returned is an instance of * {@link javax.faces.convert.DateTimeConverter}, * {@link javax.faces.convert.DateTimeConverter#setTimeZone} must be called, passing the return * from <code>TimeZone.getDefault()</code>. * </p> * * <p class="changed_added_2_0"> * The argument <code>converter</code> must be inspected for the presence of the * {@link javax.faces.application.ResourceDependency} annotation. If the * <code>ResourceDependency</code> annotation is present, the action described in * <code>ResourceDependency</code> must be taken. If the <code>ResourceDependency</code> * annotation is not present, the argument <code>converter</code> must be inspected for the * presence of the {@link javax.faces.application.ResourceDependencies} annotation. If the * <code>ResourceDependencies</code> annotation is present, the action described in * <code>ResourceDependencies</code> must be taken. * </p> * * @param converterId The converter id for which to create and return a new {@link Converter} * instance * @return the converter. * @throws FacesException if the {@link Converter} cannot be created * @throws NullPointerException if <code>converterId</code> is <code>null</code> */ public abstract Converter createConverter(String converterId); /** * <p> * <span class="changed_modified_2_0">Instantiate</span> and return a new {@link Converter} * instance of the class that has registered itself as capable of performing conversions for * objects of the specified type. If no such {@link Converter} class can be identified, return * <code>null</code>. * </p> * * <p> * To locate an appropriate {@link Converter} class, the following algorithm is performed, * stopping as soon as an appropriate {@link Converter} class is found: * </p> * <ul> * <li>Locate a {@link Converter} registered for the target class itself.</li> * <li>Locate a {@link Converter} registered for interfaces that are implemented by the target * class (directly or indirectly).</li> * <li>Locate a {@link Converter} registered for the superclass (if any) of the target class, * recursively working up the inheritance hierarchy.</li> * </ul> * * <p> * If the <code>Converter</code> has a single argument constructor that accepts a * <code>Class</code>, instantiate the <code>Converter</code> using that constructor, passing * the argument <code>targetClass</code> as the sole argument. Otherwise, simply use the * zero-argument constructor. * </p> * * <p class="changed_added_2_0"> * If the <code>toLowerCase()</code> of the <code>String</code> represenation of the value of * the "<code>javax.faces.DATETIMECONVERTER_DEFAULT_TIMEZONE_IS_SYSTEM_TIMEZONE</code>" * application configuration parameter is "<code>true</code>" (without the quotes) and the * <code>Converter</code> instance to be returned is an instance of * {@link javax.faces.convert.DateTimeConverter}, * {@link javax.faces.convert.DateTimeConverter#setTimeZone} must be called, passing the return * from <code>TimeZone.getDefault()</code>. * </p> * * @param targetClass Target class for which to return a {@link Converter} * @return the converter. * @throws FacesException if the {@link Converter} cannot be created * @throws NullPointerException if <code>targetClass</code> is <code>null</code> */ public abstract Converter createConverter(Class<?> targetClass); /** * <p> * Return an <code>Iterator</code> over the set of currently registered converter ids for this * <code>Application</code>. * </p> * * @return an iterator with converter ids. */ public abstract Iterator<String> getConverterIds(); /** * <p> * Return an <code>Iterator</code> over the set of <code>Class</code> instances for which * {@link Converter} classes have been explicitly registered. * </p> * * @return an iterator with converter types. */ public abstract Iterator<Class<?>> getConverterTypes(); /** * <p class="changed_added_2_0"> * Register a validator by its id that is applied to all <code>UIInput</code> components in a * view. The validator to most often serve this role is the <code>BeanValidator</code>. The * usage contract for this method assumes that the validator has been registered using the * normal “by-id” registration mechanism. * </p> * * <p> * An implementation is provided that takes no action so that users that decorate the * <code>Application</code> continue to work. * * @param validatorId the validator id. * @since 2.0 */ public void addDefaultValidatorId(String validatorId) { if (defaultApplication != null) { defaultApplication.addDefaultValidatorId(validatorId); } } /** * <p class="changed_added_2_0"> * Return an immutable <code>Map</code> over the set of currently registered default validator * IDs and their class name for this <code>Application</code>. * </p> * * <p> * An implementation is provided that returns <code>Collections.emptyMap</code> so that users * that decorate the <code>Application</code> continue to work. * * @return a map of default validator information. * @since 2.0 */ public Map<String, String> getDefaultValidatorInfo() { if (defaultApplication != null) { return defaultApplication.getDefaultValidatorInfo(); } return Collections.emptyMap(); } /** * <p> * Return the {@link ExpressionFactory} instance for this application. This instance is used by * the convenience method {@link #evaluateExpressionGet}. * </p> * * <p> * The implementation must return the <code>ExpressionFactory</code> from the JSP container by * calling * <code>JspFactory.getDefaultFactory().getJspApplicationContext(servletContext).getExpressionFactory()</code>. * </p> * * <p> * An implementation is provided that throws <code>UnsupportedOperationException</code> so that * users that decorate the <code>Application</code> continue to work. * * @return the expression factory. * @since 1.2 */ public ExpressionFactory getExpressionFactory() { if (defaultApplication != null) { return defaultApplication.getExpressionFactory(); } throw new UnsupportedOperationException(); } /** * <p> * Get a value by evaluating an expression. * </p> * * <p> * Call {@link #getExpressionFactory} then call {@link ExpressionFactory#createValueExpression} * passing the argument <code>expression</code> and <code>expectedType</code>. Call * {@link FacesContext#getELContext} and pass it to {@link ValueExpression#getValue}, returning * the result. * </p> * * <p> * An implementation is provided that throws <code>UnsupportedOperationException</code> so that * users that decorate the <code>Application</code> continue to work. * * @param <T> the return type. * @param context the Faces context. * @param expression the expression. * @param expectedType the expected type. * @return the result of the evaluation. */ public <T> T evaluateExpressionGet(FacesContext context, String expression, Class<? extends T> expectedType) throws ELException { if (defaultApplication != null) { return defaultApplication.evaluateExpressionGet(context, expression, expectedType); } throw new UnsupportedOperationException(); } /** * <p> * Call {@link #getExpressionFactory} then call * {@link ExpressionFactory#createMethodExpression}, passing the given arguments, and wrap the * result in a <code>MethodBinding</code> implementation, returning it. * </p> * * @param ref Method binding expression for which to return a {@link MethodBinding} instance * @param params Parameter signatures that must be compatible with those of the method to be * invoked, or a zero-length array or <code>null</code> for a method that takes no * parameters * @return the method binding. * @throws NullPointerException if <code>ref</code> is <code>null</code> * @throws ReferenceSyntaxException if the specified <code>ref</code> has invalid syntax * @deprecated This has been replaced by calling {@link #getExpressionFactory} then * {@link ExpressionFactory#createMethodExpression}. */ public abstract MethodBinding createMethodBinding(String ref, Class<?> params[]) throws ReferenceSyntaxException; /** * <p> * Return an <code>Iterator</code> over the supported <code>Locale</code>s for this appication. * </p> * * @return an iterator of the supported locales. */ public abstract Iterator<Locale> getSupportedLocales(); /** * <p> * Set the <code>Locale</code> instances representing the supported <code>Locale</code>s for * this application. * </p> * * @param locales The set of supported <code>Locale</code>s for this application * * @throws NullPointerException if the argument <code>newLocales</code> is <code>null</code>. * */ public abstract void setSupportedLocales(Collection<Locale> locales); /** * <p> * Provide a way for Faces applications to register an <code>ELContextListener</code> that will * be notified on creation of <code>ELContext</code> instances. This listener will be called * once per request. * </p> * * <p> * An implementation is provided that throws <code>UnsupportedOperationException</code> so that * users that decorate the <code>Application</code> continue to work. * * @param listener the EL context listener to add. * @since 1.2 */ public void addELContextListener(ELContextListener listener) { if (defaultApplication != null) { defaultApplication.addELContextListener(listener); } else { throw new UnsupportedOperationException(); } } /** * <p> * Remove the argument <code>listener</code> from the list of {@link ELContextListener}s. If * <code>listener</code> is null, no exception is thrown and no action is performed. If * <code>listener</code> is not in the list, no exception is thrown and no action is performed. * </p> * * <p> * An implementation is provided that throws <code>UnsupportedOperationException</code> so that * users that decorate the <code>Application</code> continue to work. * * @param listener the EL context listener to remove. * @since 1.2 */ public void removeELContextListener(ELContextListener listener) { if (defaultApplication != null) { defaultApplication.removeELContextListener(listener); } else { throw new UnsupportedOperationException(); } } /** * <p> * If no calls have been made to {@link #addELContextListener}, this method must return an empty * array. * </p> * * <p> * Otherwise, return an array representing the list of listeners added by calls to * {@link #addELContextListener}. * </p> * * <p> * An implementation is provided that throws <code>UnsupportedOperationException</code> so that * users that decorate the <code>Application</code> continue to work. * * @return an array of EL context listeners. * @since 1.2 */ public ELContextListener[] getELContextListeners() { if (defaultApplication != null) { return defaultApplication.getELContextListeners(); } throw new UnsupportedOperationException(); } /** * <p> * Register a new mapping of validator id to the name of the corresponding {@link Validator} * class. This allows subsequent calls to <code>createValidator()</code> to serve as a factory * for {@link Validator} instances. * </p> * * @param validatorId The validator id to be registered * @param validatorClass The fully qualified class name of the corresponding {@link Validator} * implementation * * @throws NullPointerException if <code>validatorId</code> or <code>validatorClass</code> is * <code>null</code> */ public abstract void addValidator(String validatorId, String validatorClass); /** * <p> * <span class="changed_modified_2_0">Instantiate</span> and return a new {@link Validator} * instance of the class specified by a previous call to <code>addValidator()</code> for the * specified validator id. * </p> * * <p class="changed_added_2_0"> * The argument <code>validator</code> must be inspected for the presence of the * {@link javax.faces.application.ResourceDependency} annotation. If the * <code>ResourceDependency</code> annotation is present, the action described in * <code>ResourceDependency</code> must be taken. If the <code>ResourceDependency</code> * annotation is not present, the argument <code>validator</code> must be inspected for the * presence of the {@link javax.faces.application.ResourceDependencies} annotation. If the * <code>ResourceDependencies</code> annotation is present, the action described in * <code>ResourceDependencies</code> must be taken. * </p> * * @param validatorId The validator id for which to create and return a new {@link Validator} * instance * @return the validator. * @throws FacesException if a {@link Validator} of the specified id cannot be created * @throws NullPointerException if <code>validatorId</code> is <code>null</code> */ public abstract Validator createValidator(String validatorId) throws FacesException; /** * <p> * Return an <code>Iterator</code> over the set of currently registered validator ids for this * <code>Application</code>. * </p> * * @return an iterator of validator ids. */ public abstract Iterator<String> getValidatorIds(); /** * <p> * Call {@link #getExpressionFactory} then call {@link ExpressionFactory#createValueExpression}, * passing the argument <code>ref</code>, <code>Object.class</code> for the expectedType, and * <code>null</code>, for the fnMapper. * </p> * * * @param ref Value binding expression for which to return a {@link ValueBinding} instance * @return the value binding. * @throws NullPointerException if <code>ref</code> is <code>null</code> * @throws ReferenceSyntaxException if the specified <code>ref</code> has invalid syntax * @deprecated This has been replaced by calling {@link #getExpressionFactory} then * {@link ExpressionFactory#createValueExpression}. */ public abstract ValueBinding createValueBinding(String ref) throws ReferenceSyntaxException; /** * <p class="changed_added_2_0"> * If {@link javax.faces.context.FacesContext#isProcessingEvents()} is <code>true</code> and * there are one or more listeners for events of the type represented by * <code>systemEventClass</code>, call those listeners, passing <code>source</code> as the * source of the event. The implementation should be as fast as possible in determining whether * or not a listener for the given <code>systemEventClass</code> and <code>source</code> has * been installed, and should return immediately once such a determination has been made. The * implementation of <code>publishEvent</code> must honor the requirements stated in * {@link #subscribeToEvent} regarding the storage and retrieval of listener instances. * Specifically, if {@link #subscribeToEvent(Class,Class,SystemEventListener)} was called, the * <code>sourceClass</code> argument must match exactly the <code>Class</code> of the * <code>source</code> argument in the call to <code>publishEvent()</code>. The implementation * must not do any inheritance hierarachy inspection when looking for a match between the * <code>sourceClass</code> passed to {@link #subscribeToEvent(Class,Class,SystemEventListener)} * and the <code>sourceClass</code> passed to <code>publishEvent()</code> in order to find any * listeners to which the event should be published. In the case where the <code>Class</code> of * the <code>source</code> argument does not match the <code>Class</code> of the * <code>sourceClass</code> used when the listener was subscribed using * <code>subscribeToEvent()</code>, {@link #publishEvent(FacesContext,Class,Class,Object)} can * be used to provide the <code>Class</code> used to perform the listener lookup and match. * </p> * * <div class="changed_added_2_0"> * * <p> * The default implementation must implement an algorithm semantically equivalent to the * following to locate listener instances and to invoke them. * </p> * * <ul> * * <li> * <p> * If the <code>source</code> argument implements * {@link javax.faces.event.SystemEventListenerHolder}, call * {@link javax.faces.event.SystemEventListenerHolder#getListenersForEventClass} on it, passing * the <code>systemEventClass</code> argument. If the list is not empty, perform algorithm * <em>traverseListenerList</em> on the list. * </p> * </li> * * <li> * <p> * If any <em>view</em> level listeners have been installed by previous calls to * {@link #subscribeToEvent(Class, Class, javax.faces.event.SystemEventListener)} on the * {@link javax.faces.component.UIViewRoot}, perform algorithm <em>traverseListenerList</em> on * the list of listeners for that event installed on the <code>UIViewRoot</code>. * </p> * </li> * * <li> * <p> * If any <code>Application</code> level listeners have been installed by previous calls to * {@link #subscribeToEvent(Class, Class, javax.faces.event.SystemEventListener)}, perform * algorithm <em>traverseListenerList</em> on the list. * </p> * </li> * * <li> * <p> * If any <code>Application</code> level listeners have been installed by previous calls to * {@link #subscribeToEvent(Class, javax.faces.event.SystemEventListener)}, perform algorithm * <em>traverseListenerList</em> on the list. * </p> * </li> * * </ul> * * <p> * If the act of invoking the <code>processListener</code> method causes an * {@link javax.faces.event.AbortProcessingException} to be thrown, processing of the listeners * must be aborted, no further processing of the listeners for this event must take place, and * the exception must be logged with <code>Level.SEVERE</code>. * </p> * * <p> * Algorithm <em>traverseListenerList</em>: For each listener in the list, * </p> * * <ul> * * <li> * <p> * Call {@link javax.faces.event.SystemEventListener#isListenerForSource}, passing the * <code>source</code> argument. If this returns <code>false</code>, take no action on the * listener. * </p> * </li> * * <li> * <p> * Otherwise, if the event to be passed to the listener instances has not yet been constructed, * construct the event, passing <code>source</code> as the argument to the one-argument * constructor that takes an <code>Object</code>. This same event instance must be passed to all * listener instances. * </p> * </li> * * <li> * <p> * Call {@link javax.faces.event.SystemEvent#isAppropriateListener}, passing the listener * instance as the argument. If this returns <code>false</code>, take no action on the listener. * </p> * </li> * * <li> * <p> * Call {@link javax.faces.event.SystemEvent#processListener}, passing the listener instance. * </p> * </li> * * </ul> * * <p class="changed_added_2_0"> * A default implementation is provided that throws <code>UnsupportedOperationException</code> * so that users that decorate <code>Application</code> can continue to function * </p> * . * * </div> * * @param context the <code>FacesContext</code> for the current request * @param systemEventClass The <code>Class</code> of event that is being published. * @param source The source for the event of type <code>systemEventClass</code>. * * @throws NullPointerException if either <code>context</code>, <code>systemEventClass</code> or * <code>source</code> is <code>null</code> * * @since 2.0 * */ public void publishEvent(FacesContext context, Class<? extends SystemEvent> systemEventClass, Object source) { if (defaultApplication != null) { defaultApplication.publishEvent(context, systemEventClass, source); } else { throw new UnsupportedOperationException(); } } /** * <p class="changed_added_2_0"> * This method functions exactly like {@link #publishEvent(FacesContext,Class,Object)}, except * the run-time must use the argument <code>sourceBaseType</code> to find the matching listener * instead of using the <code>Class</code> of the <code>source</code> argument. * </p> * * <p class="changed_added_2_0"> * A default implementation is provided that throws <code>UnsupportedOperationException</code> * so that users that decorate <code>Application</code> can continue to function * </p> * . * * @param context the <code>FacesContext</code> for the current request * @param systemEventClass The <code>Class</code> of event that is being published. * @param sourceBaseType The <code>Class</code> of the source event that must be used to lookup * the listener to which this event must be published. If this argument is * <code>null</code> the return from <code>source.getClass()</code> must be used as * the <code>sourceBaseType</code>. * @param source The source for the event of type <code>systemEventClass</code>. * * @throws NullPointerException if any arguments except for <code>sourceBaseType</code> are * <code>null</code> * * @since 2.0 */ public void publishEvent(FacesContext context, Class<? extends SystemEvent> systemEventClass, Class<?> sourceBaseType, Object source) { if (defaultApplication != null) { defaultApplication.publishEvent(context, systemEventClass, sourceBaseType, source); } else { throw new UnsupportedOperationException(); } } /** * <p class="changed_added_2_0"> * <span class="changed_modified_2_2">Install</span> the listener instance referenced by * argument <code>listener</code> into the application as a listener for events of type * <code>systemEventClass</code> that originate from objects of type <code>sourceClass</code>. * </p> * * <div class="changed_added_2_0"> * * <p> * If argument <code>sourceClass</code> is non-<code>null</code>, <code>sourceClass</code> and * <code>systemEventClass</code> must be used to store the argument <code>listener</code> in the * application in such a way that the <code>listener</code> can be quickly looked up by the * implementation of {@link #publishEvent} given <code>systemEventClass</code> and an instance * of the <code>Class</code> referenced by <code>sourceClass</code>. If argument * <code>sourceClass</code> is <code>null</code>, the <code>listener</code> must be discoverable * by the implementation of {@link #publishEvent} given only <code>systemEventClass</code>. * </p> * * </div> * * <div class="changed_added_2_2"> * * <p> * It is valid to call this method <strong>during</strong> the processing of an event which was * subscribed to by a previous call to this method. * </p> * * </div> * * * @param systemEventClass the <code>Class</code> of event for which <code>listener</code> must * be fired. * * @param sourceClass the <code>Class</code> of the instance which causes events of type * <code>systemEventClass</code> to be fired. May be <code>null</code>. * * @param listener the implementation of {@link javax.faces.event.SystemEventListener} whose * {@link javax.faces.event.SystemEventListener#processEvent} method must be called * when events of type <code>systemEventClass</code> are fired. * * @throws NullPointerException if any combination of <code>systemEventClass</code>, or * <code>listener</code> are <code>null</code>. * * @since 2.0 */ public void subscribeToEvent(Class<? extends SystemEvent> systemEventClass, Class<?> sourceClass, SystemEventListener listener) { if (defaultApplication != null) { defaultApplication.subscribeToEvent(systemEventClass, sourceClass, listener); } else { throw new UnsupportedOperationException(); } } /** * <p class="changed_added_2_0"> * <span class="changed_modified_2_2">Install</span> the listener instance referenced by * argument <code>listener</code> into application as a listener for events of type * <code>systemEventClass</code>. The default implementation simply calls through to * {@link #subscribeToEvent(Class, Class, javax.faces.event.SystemEventListener)} passing * <code>null</code> as the <code>sourceClass</code> argument * </p> * * <p class="changed_added_2_0"> * A default implementation is provided that throws <code>UnsupportedOperationException</code> * so that users that decorate <code>Application</code> can continue to function * </p> * . * * @param systemEventClass the <code>Class</code> of event for which <code>listener</code> must * be fired. * * @param listener the implementation of {@link javax.faces.event.SystemEventListener} whose * {@link javax.faces.event.SystemEventListener#processEvent} method must be called * when events of type <code>systemEventClass</code> are fired. * * <div class="changed_added_2_2"> * * <p> * See * {@link #subscribeToEvent(java.lang.Class,java.lang.Class,javax.faces.event.SystemEventListener)} * for an additional requirement regarding when it is valid to call this method. * </p> * * </div> * * @throws NullPointerException if any combination of <code>systemEventClass</code>, or * <code>listener</code> are <code>null</code>. * * @since 2.0 */ public void subscribeToEvent(Class<? extends SystemEvent> systemEventClass, SystemEventListener listener) { if (defaultApplication != null) { defaultApplication.subscribeToEvent(systemEventClass, listener); } else { throw new UnsupportedOperationException(); } } /** * <p class="changed_added_2_0"> * <span class="changed_modified_2_2">Remove</span> the listener instance referenced by argument * <code>listener</code> from the application as a listener for events of type * <code>systemEventClass</code> that originate from objects of type <code>sourceClass</code>. * See {@link #subscribeToEvent(Class, Class, javax.faces.event.SystemEventListener)} for the * specification of how the listener is stored, and therefore, how it must be removed. * </p> * * <div class="changed_added_2_2"> * * <p> * See * {@link #subscribeToEvent(java.lang.Class,java.lang.Class,javax.faces.event.SystemEventListener)} * for an additional requirement regarding when it is valid to call this method. * </p> * * </div> * * @param systemEventClass the <code>Class</code> of event for which <code>listener</code> must * be fired. * * @param sourceClass the <code>Class</code> of the instance which causes events of type * <code>systemEventClass</code> to be fired. May be <code>null</code>. * * @param listener the implementation of {@link javax.faces.event.SystemEventListener} to remove * from the internal data structure. * * @throws NullPointerException if any combination of <code>context</code>, * <code>systemEventClass</code>, or <code>listener</code> are <code>null</code>. * * @since 2.0 */ public void unsubscribeFromEvent(Class<? extends SystemEvent> systemEventClass, Class<?> sourceClass, SystemEventListener listener) { if (defaultApplication != null) { defaultApplication.unsubscribeFromEvent(systemEventClass, sourceClass, listener); } else { throw new UnsupportedOperationException(); } } /** * <p class="changed_added_2_0"> * <span class="changed_modified_2_2">Remove</span> the listener instance referenced by argument * <code>listener</code> from the application as a listener for events of type * <code>systemEventClass</code>. The default implementation simply calls through to * {@link #unsubscribeFromEvent(Class, javax.faces.event.SystemEventListener)} passing * <code>null</code> as the <code>sourceClass</code> argument * </p> * * <div class="changed_added_2_2"> * * <p> * See * {@link #subscribeToEvent(java.lang.Class,java.lang.Class,javax.faces.event.SystemEventListener)} * for an additional requirement regarding when it is valid to call this method. * </p> * * </div> * * @param systemEventClass the <code>Class</code> of event for which <code>listener</code> must * be fired. * * @param listener the implementation of {@link javax.faces.event.SystemEventListener} to remove * from the internal data structure. * * @throws NullPointerException if any combination of <code>context</code>, * <code>systemEventClass</code>, or <code>listener</code> are <code>null</code>. * * @since 2.0 */ public void unsubscribeFromEvent(Class<? extends SystemEvent> systemEventClass, SystemEventListener listener) { if (defaultApplication != null) { defaultApplication.unsubscribeFromEvent(systemEventClass, listener); } else { throw new UnsupportedOperationException(); } } /** * <p class="changed_added_2_3"> * Return the thread-safe singleton {@link SearchExpressionHandler} for this application. * </p> * * @return the {@link SearchExpressionHandler}. * @since 2.3 */ public SearchExpressionHandler getSearchExpressionHandler() { if (defaultApplication != null) { return defaultApplication.getSearchExpressionHandler(); } else { throw new UnsupportedOperationException(); } } /** * <p class="changed_added_2_3"> * Set the {@link SearchExpressionHandler} instance used by the application. * </p> * * @param searchExpressionHandler the {@link SearchExpressionHandler}. * @throws NullPointerException if searchExpressionHandler is <code>null</code> * @throws IllegalStateException if this method is called after at least one request has been * processed by the {@code Lifecycle} instance for this application. * * @since 2.3 */ public void setSearchExpressionHandler(SearchExpressionHandler searchExpressionHandler) { if (defaultApplication != null) { defaultApplication.setSearchExpressionHandler(searchExpressionHandler); } else { throw new UnsupportedOperationException(); } } /** * <p class="changed_added_2_3"> * Cause the argument <code>resolver</code> to be added to the head of the resolver chain. * </p> * * <div class="changed_added_2_3"> * * <p> * It is not possible to remove a {@link SearchKeywordResolver} registered with this method, * once it has been registered. * </p> * * <p> * The default implementation throws <code>UnsupportedOperationException</code> and is provided * for the sole purpose of not breaking existing applications that extend {@link Application}. * </p> * * </div> * * @throws IllegalStateException if called after the first request to the * {@link javax.faces.webapp.FacesServlet} has been serviced. * @throws NullPointerException when resolver is null. * * @param resolver the SearchKeywordResolver to add. * @since 2.3 */ public void addSearchKeywordResolver(SearchKeywordResolver resolver) { if (defaultApplication != null) { defaultApplication.addSearchKeywordResolver(resolver); } else { throw new UnsupportedOperationException(); } } /** * <p class="changed_added_2_3"> * Return the singleton {@link SearchKeywordResolver} instance to be used for all search keyword * resolution. This is actually an instance of a composite SearchKeywordResolver that must * contain the following <code>SearchKeywordResolver</code> instances in the following order: * </p> * * <ol> * * <li> * <p> * <code>SearchKeywordResolver</code> instances declared using the * <search-keyword-resolver> element in the application configuration resources. * </p> * </li> * * <li> * <p> * Any <code>SearchKeywordResolver</code> instances added by calls to * {@link #addSearchKeywordResolver}. * </p> * </li> * * <li> * <p> * The <code>SearchKeywordResolver</code> implementations for <code>@all</code>, * <code>@child(n)</code>, <code>@form</code>, <code>@id(...)</code>, * <code>@namingcontainer</code>, <code>@next</code>, <code>@none</code>, <code>@parent</code>, * <code>@previous</code>, <code>@root</code> and <code>@this</code>. * </p> * </li> * * </ol> * * <p> * The default implementation throws <code>UnsupportedOperationException</code> and is provided * for the sole purpose of not breaking existing applications that extend {@link Application}. * </p> * * @return the {@link SearchKeywordResolver}. * @since 2.3 */ public SearchKeywordResolver getSearchKeywordResolver() { if (defaultApplication != null) { return defaultApplication.getSearchKeywordResolver(); } throw new UnsupportedOperationException(); } }