/*
* 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();
}
}
}