/* * 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.dev.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.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">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> */ public abstract ActionListener getActionListener(); /** * <p>Set the default {@link ActionListener} to be registered for all * {@link javax.faces.component.ActionSource} components.</p> * </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> */ 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> */ 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> */ 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> */ 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> */ 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> * @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> * * @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> * * @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> <ul> * * <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> * * </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> * * @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> * * @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> * @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> * * @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> * @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> * @since 2.2 * * @throws NullPounterException if {code newHandler} is {@code null} * * @throws IllegalStateException if this method is called after at least one * request has been processed by the {@code Lifecycle} instance for this application. * */ 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> */ 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> */ 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 * * @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> */ 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 * * @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 * * @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> * * @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 * * @throws FacesException if a {@link UIComponent} cannot be created * @throws NullPointerException if any parameter is <code>null</code> * * <p>A default implementation is provided that throws * <code>UnsupportedOperationException</code> so that users * that decorate <code>Application</code> can continue to function.</p> * * @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. * * @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. * * @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. * * @throws FacesException if a {@link UIComponent} from the {@link * Resource} cannot be created * @throws <code>NullPointerException</code> 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> */ 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 * * @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} * * @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> */ 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> */ 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. * * @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. * * @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. * * @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. * */ 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 * * @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> */ 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. * * @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. * * @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. * * @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 * * @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> */ 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 * * @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 <code>NullPointerException</code> 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.</p> * @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 <code>NullPointerException</code> 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 <code>NullPointerException</code> 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 <code>NullPointerException</code> 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(); } } }