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

org.apache.myfaces.trinidad.context.RequestContext Maven / Gradle / Ivy

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

import java.awt.Color;

import java.io.IOException;

import java.math.RoundingMode;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import javax.faces.component.UIComponent;
import javax.faces.component.UIViewRoot;
import javax.faces.component.visit.VisitContext;
import javax.faces.component.visit.VisitHint;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseId;

import org.apache.myfaces.trinidad.change.ChangeManager;
import org.apache.myfaces.trinidad.config.RegionManager;
import org.apache.myfaces.trinidad.event.WindowLifecycleListener;
import org.apache.myfaces.trinidad.logging.TrinidadLogger;
import org.apache.myfaces.trinidad.util.ArrayMap;
import org.apache.myfaces.trinidad.util.ClassLoaderUtils;
import org.apache.myfaces.trinidad.webapp.UploadedFileProcessor;


/**
 * Context class for all per-request and per-webapp information
 * required by Trinidad.  A RequestContext object can be
 * retrieved with the static {@link #getCurrentInstance} method.
 * There is one and only one RequestContext object
 * active in any one thread.
 * 

* This class does not extend FacesContext; this is intentional, * as extending FacesContext requires taking over the * FacesContextFactory. *

*/ // TODO Refactor this class after everything gets added to it. // TODO There's some values in here that seem to affect only output (e.g., // right-to-left); that's not great, since ideally that detail would be // buried in something more renderer-specific. abstract public class RequestContext { /** * Name of the EL implicit variable ("requestContext") that is used to * expose this context object. */ static public final String VARIABLE_NAME = "requestContext"; // Omitted APIs: // // LocaleContext // ============= // Locale getTranslationLocale // // DateFormatContext: // ================= // int getTwoDigitYearStart // boolean isLenient (very lame API, definitely gone) /** * Retrieves the RequestContext active for the current thread. */ static public RequestContext getCurrentInstance() { return _CURRENT_CONTEXT.get(); } /** * Creates an RequestContext. RequestContext is abstract * and may not be instantiated directly. * @see RequestContextFactory */ protected RequestContext() { } // // State related APIs // /** * Returns a Map of objects at "pageFlow" scope. */ public abstract Map getPageFlowScope(); /** * @deprecated use getPageFlowScope() */ @Deprecated final public Map getProcessScope() { return getPageFlowScope(); } /** * Method to obtain a Map stored on the view. *

This calls {@link #getViewMap(boolean)} with a true value for create.

*

This is a pre-cursor implementation to the JSF 2.0 UIViewRoot.getViewMap() function. * The implementation is taken from the initial UIViewRoot implementation in JSF but without * the event notification support.

*/ public abstract Map getViewMap(); /** * Method to obtain a Map stored on the view. *

This is a pre-cursor implementation to the JSF 2.0 UIViewRoot.getViewMap() function. * The implementation is taken from the initial UIViewRoot implementation in JSF but without * the event notification support.

* * @param create if the map should be created if it already does not exist. */ public abstract Map getViewMap(boolean create); /** * Returns a Map of objects associated with the current window if any. If there is no * current window, the Session Map is returned. * @return Map for storing objects associated with the current window. * @see org.apache.myfaces.trinidad.context.Window#getWindowMap */ public Map getWindowMap() { WindowManager wm = getWindowManager(); ExternalContext extContext = FacesContext.getCurrentInstance().getExternalContext(); Window window = wm.getCurrentWindow(extContext); if (window != null) { return window.getWindowMap(); } else { return extContext.getSessionMap(); } } // // Dialog APIs // /** * Returns from a dialog raised by a * {@link org.apache.myfaces.trinidad.component.UIXCommand UIXCommand} component, * or any component implementing * {@link org.apache.myfaces.trinidad.component.DialogSource DialogSource}, * or any direct calls to {@link #launchDialog launchDialog()}. *

* @see org.apache.myfaces.trinidad.event.ReturnEvent * @param returnValue the value to be delivered in the the ReturnEvent */ // TODO Do we need an explicit "cancelled" concept, or // is a null returnValue good enough? public abstract void returnFromDialog( Object returnValue, Map returnParameters); /** * Returns an DialogService, which exposes a number * of APIs needed by component and framework developers. This * will only rarely be needed by page authors. */ public abstract DialogService getDialogService(); /** * Launch a dialog, optionally raising it in a new dialog window. *

* The dialog will receive a new pageFlowScope map, * which includes all the values of the currently available pageFlowScope * as well as a set of properties passed to this function in * the dialogParameters map. Changes to this newly * created scope will not be visible once the dialog returns. *

* @param dialogRoot the UIViewRoot for the page being launched * @param dialogParameters a set of parameters to populate the * newly created pageFlowScope * @param source the UIComponent that launched the dialog and * should receive the {@link org.apache.myfaces.trinidad.event.ReturnEvent} * when the dialog is complete. * @param useWindow if true, use a popup window for the dialog * if available on the current user agent device * @param windowProperties the set of UI parameters used to * modify the window, if one is used. The set of properties that\ * are supported will depend on the RenderKit, but * common examples include "width", "height", "top" and "left". */ public abstract void launchDialog( UIViewRoot dialogRoot, Map dialogParameters, UIComponent source, boolean useWindow, Map windowProperties); // // General Apache Trinidad // /** * Returns true if JSF is currently processing a postback request. * isPostback() will return false if this is a request * for an initial render of a page (that is, if Apply Request Values * never executes), or if during the request the user is navigated * to a different page (because of a navigation rule, etc). For * example, during a request that results in a navigation to a new * page, isPostback() will return true from Apply * Request Values to Invoke Application, then false afterwards; * whereas if there was no navigation, it would return true *

* The value of this method is undefined during (or before) * the Restore View phase, but can be used in the afterPhase() * method of a PhaseListener for Restore View. *

*/ public abstract boolean isPostback(); /** * Method to indicate if this current HTTP request is a * partial page rendering request. * * @param context the FacesContext object for * the request we are processing * @return is this request a PPR request? */ public abstract boolean isPartialRequest(FacesContext context); /** * Returns true if output should contain debugging information. */ public abstract boolean isDebugOutput(); /** * Returns true if client-side validation should be disabled. */ public abstract boolean isClientValidationDisabled(); /** * Returns the "output mode" - printable, etc. */ public abstract String getOutputMode(); /** * Returns the OutputMode enumeration * @return OutputMode */ public OutputMode getOutputModeEnum() { return OutputMode.fromId(getOutputMode()); } /** * Returns the name of the preferred skin family. */ public abstract String getSkinFamily(); /** * Returns the name of the skin version that goes with the skin-family. */ public String getSkinVersion() { return null; } /** * Determines whether the current View Root is an internal view * @param context Faces context * @return true if the current View Root is an internal view, false otherwise */ public abstract boolean isInternalViewRequest(FacesContext context); /** * Enumeration representing OutputModes */ public enum OutputMode { DEFAULT("default"), PORTLET("portlet"), PRINTABLE("printable"), EMAIL("email"), ATTACHMENT("attachment"), WEB_CRAWLER("webcrawler"); private OutputMode(String id) { if (id == null) throw new NullPointerException(); _id = id; } /** * @return the id of this OutputMode. */ public String id() { return _id; } @Override public String toString() { return _id; } /** * Returns the OutputMode isntance of null if no id matches. * @param id of OutputMode to return * @return The OutputMode with the specified id * @throws NullPointerException if id is null. * @throws IllegalArgumentException if there is no enum with the specified name. */ public static OutputMode fromId(String id) { if (id == null) throw new NullPointerException(); OutputMode outputMode = ID_TO_OUTPUT_MODE.get(id); if (outputMode == null) throw new IllegalArgumentException(); return outputMode; } private static final Map ID_TO_OUTPUT_MODE = new HashMap(); static { OutputMode[] instances = OutputMode.class.getEnumConstants(); for (int i = 0; i < instances.length; i++) { ID_TO_OUTPUT_MODE.put(instances[i].toString(), instances[i]); } } private final String _id; } public enum Accessibility { /** * Output supports accessibility features */ DEFAULT("default"), /** * Accessibility-specific constructs are stripped out to optimize output size */ INACCESSIBLE("inaccessible"), /** * Accessibility-specific constructs are added to improve behavior under a screen reader * (but may affect other users negatively) */ SCREEN_READER("screenReader"); /** * Creates an Accessibility constant. * @param displayName a user-friendly display name for the constant. */ Accessibility(String displayName) { _displayName = displayName; } @Override public String toString() { return displayName(); } /** * Returns the display name for this enum constant. */ public String displayName() { return _displayName; } /** * Performs a reverse lookup of an Accessibilty constant based on * its display name. * * @param displayName the display name of the Accessibility constant to return. * @return the non-null Accessibility constant associated with the display name. * @throws IllegalArgumentException if displayName does not correspond * to some Accessibility constant. * @throws NullPointerException if displayName is null. */ public static Accessibility valueOfDisplayName(String displayName) { if (displayName == null) { throw new NullPointerException(); } Accessibility accessibility = _displayNameMap.get(displayName); if (accessibility == null) { String message = _LOG.getMessage("ILLEGAL_ENUM_VALUE", new Object[] { Accessibility.class.getName(), displayName }); throw new IllegalArgumentException(message); } return accessibility; } private final String _displayName; private static final Map _displayNameMap; static { Map displayNameMap = new ArrayMap(3); for (Accessibility accessibility : Accessibility.values()) { displayNameMap.put(accessibility.displayName(), accessibility); } _displayNameMap = Collections.unmodifiableMap(displayNameMap); } }; public enum ClientValidation { ALERT("alert"), INLINE("inline"), DISABLED("disabled"); ClientValidation(String name) { _name = name; } @Override public String toString() { return _name; } private final String _name; }; /** * Returns the name of the current accessibility mode. */ public abstract Accessibility getAccessibilityMode(); /** * Returns the accessibility profile for the current request. */ public abstract AccessibilityProfile getAccessibilityProfile(); /** * Returns the name of the current client validation mode. */ public abstract ClientValidation getClientValidation(); /** * Returns the system wide setting to turn animation on/off. */ public abstract boolean isAnimationEnabled(); // // General localization // /** * Returns true if the user should be shown output in right-to-left. */ public abstract boolean isRightToLeft(); /** * Returns the formatting locale. Converters without an explicit locale * should use this to format values. If not set, converters should * default to the value of FacesContext.getViewRoot().getLocale(). * This will, by default, simply return null. */ public abstract Locale getFormattingLocale(); // // Number formatting // /** * Return the separator used for groups of numbers. If NUL (zero), * use the default separator for the current language. */ public abstract char getNumberGroupingSeparator(); /** * Return the separator used as the decimal point. If NUL (zero), * use the default separator for the current language. */ public abstract char getDecimalSeparator(); /** * Return the ISO 4217 currency code used by default for formatting * currency fields when those fields do not specify an explicit * currency field via their converter. If this returns null, the default * code for the current locale will be used. */ // TODO do we need to provide getCurrencySymbol() as well? public abstract String getCurrencyCode(); /** * Notify Trinidad that tag execution will not be performed during this request. Functionality in * Trinidad assumes that tags will be executed as part of the render response phase. If 3rd party * libraries are used that cause the tags to not be executed, Trinidad must be notified to avoid * errors. */ public void tagExecutionSkipped() { _tagExecution = TagExecution.NONE; } /** * Checks if the tags will be executed during this request. * @see #tagExecutionSkipped() * @return an enumeration indicating the status of the tag execution */ public TagExecution getTagExecutionStatus() { return _tagExecution; } /** * @see #isTagExecutionSkipped() */ public enum TagExecution { /** Tag execution will be run normally during this request */ FULL, /** Tag execution will not be run during this request */ NONE } // // DateFormating API // /** * Returns the year offset for parsing years with only two digits. * If not set this is defaulted to 1950 * This is used by @link{org.apache.myfaces.trinidad.faces.view.converter.DateTimeConverter} * while converting strings to Date object. */ public abstract int getTwoDigitYearStart(); // // Help APIs // /** * Return the URL to an Oracle Help for the Web servlet. */ // TODO Add support for non-OHW help systems public abstract String getOracleHelpServletUrl(); /** * Returns a Map that will accept topic names as keys, and return * an URL as a result. */ public abstract Map getHelpTopic(); /** * Returns a Map that will accept help system properties as keys, and return * an URL as a result. */ public abstract Map getHelpSystem(); // // Date formatting // /** * Returns the default TimeZone used for interpreting and formatting * date values. */ public abstract TimeZone getTimeZone(); /** * Gets the ChangeManager for the current application. */ public abstract ChangeManager getChangeManager(); /** * Gets a per application concurrent map. There is no synchronization * with ServletContext attributes. */ public ConcurrentMap getApplicationScopedConcurrentMap() { ClassLoader cl = _getClassLoader(); ConcurrentMap classMap = _APPLICATION_MAPS.get(cl); if (classMap == null) { ConcurrentMap newClassMap = new ConcurrentHashMap(); ConcurrentMap oldClassMap = _APPLICATION_MAPS.putIfAbsent(cl, newClassMap); classMap = ((oldClassMap != null)? oldClassMap : newClassMap); assert(classMap != null); } return classMap; } /** * Gets the PageFlowScopeProvider for the current application. */ public abstract PageFlowScopeProvider getPageFlowScopeProvider(); /** * Gets the PageResolver for the current application. */ public abstract PageResolver getPageResolver(); /** * Gets the RegionManager for the current application. */ public abstract RegionManager getRegionManager(); /** * Gets the RoundingMode used by NumberConverter instances for the current application. */ public RoundingMode getRoundingMode() { return null; } // // Partial Page Rendering support // /** * Add a component as a partial target. In response to a partial event, only * components registered as partial targets are re-rendered. For * a component to be successfully re-rendered when it is manually * added with this API, it should have an explictly set "id". If * not, partial re-rendering may or may not work depending on the * component. */ public abstract void addPartialTarget(UIComponent newTarget); /** * Add components relative to the given component as partial targets. *

* See {@link #addPartialTarget(UIComponent)} for more information. *

* @param from the component to use as a relative reference for any * relative IDs in the list of targets * @param targets array of targets relative to the from component that * should be added as targets. * @see ComponentUtils#findRelativeComponent(UIComponent, String) */ public abstract void addPartialTargets(UIComponent from, String... targets); /** * Returns the set of partial targets related to a given UIComponent. */ public abstract Set getPartialTargets(UIComponent newTarget); /** * Adds a listener on a set of particular triggering components. If one of * the named components gets updated in response to a partial event, then * this listener component will be rerendered during the render phase (i.e. * it will be added as a partialTarget). The list should consist of names * suitable for use with the findComponent method on UIComponent. */ public abstract void addPartialTriggerListeners(UIComponent listener, String[] trigger); /** * Called when any component gets updated. Any partial target components * listening on this component will be added to the partialTargets list in * the render phase. */ public abstract void partialUpdateNotify(UIComponent updated); /** * Starts a new component binding context. Typically called from tag handlers when component * bindings in its subtree needs to be cleared, forcing the creation of new components. * * @param context FacesContext instance * @see RequestContext#popComponentBindingContext * @see RequestContext#isInComponentBindingContext */ public static void pushComponentBindingContext(FacesContext context) { ExternalContext ec = context.getExternalContext(); if (null != ec) { // Use a counter on the request map to generate the IDs. Map reqMap = ec.getRequestMap(); Integer value = (Integer)reqMap.get(_CURRENT_COMPONENT_BINDING_CONTEXT_KEY); int val = 0; if (value == null) { val = 1; } else { val = value + 1; } reqMap.put(_CURRENT_COMPONENT_BINDING_CONTEXT_KEY, val); } } /** * Pops out of the last pushed component binding context. Component binding instances will not be * cleared after popping out the outermost context. * * @param context FacesContext instance * @see RequestContext#pushComponentBindingContext * @see RequestContext#isInComponentBindingContext */ public static void popComponentBindingContext(FacesContext context) { ExternalContext ec = context.getExternalContext(); if (null != ec) { Map reqMap = ec.getRequestMap(); Integer value = (Integer)reqMap.get(_CURRENT_COMPONENT_BINDING_CONTEXT_KEY); int val = 0; if (value == null) { _LOG.warning("POP_COMPONENT_BINDING_CONTEXT_FAILED"); } else { val = value - 1; } if (val > 0) reqMap.put(_CURRENT_COMPONENT_BINDING_CONTEXT_KEY, val); else reqMap.put(_CURRENT_COMPONENT_BINDING_CONTEXT_KEY, null); } } /** * Returns true if we are currently within a component binding context. * * @see RequestContext#pushComponentBindingContext * @see RequestContext#popComponentBindingContext */ public static boolean isInComponentBindingContext(FacesContext context) { ExternalContext ec = context.getExternalContext(); if (null != ec) { Map reqMap = ec.getRequestMap(); Integer value = (Integer)reqMap.get(_CURRENT_COMPONENT_BINDING_CONTEXT_KEY); if (value != null && value > 0) return true; } return false; } // // Miscellaneous functionality // /** *

Creates a VisitContext instance for use with * {@link UIComponent#visitTree}.

* * @param context the FacesContext for the current request * @param ids the client ids of the components to visit. If null, * all components will be visited. * @param hints the VisitHints to apply to the visit * @param phaseId. ignored. * @return a VisitContext instance that is initialized with the * specified ids and hints. * @deprecated use {@link VisitContext#createVisitContext(FacesContext, Collection, Set)} instead */ public final VisitContext createVisitContext( FacesContext context, Collection ids, Set hints, PhaseId phaseId) { return VisitContext.createVisitContext(context, ids, hints); } public abstract UploadedFileProcessor getUploadedFileProcessor(); public abstract Long getUploadedFileMaxMemory(); public abstract Long getUploadedFileMaxDiskSpace(); public Long getUploadedFileMaxFileSize() { // default of unlimited file size return -1L; } public Long getUploadedFileMaxChunkSize() { // default of 2GB which is the maximum allowed chunk size return 2000000000L; } public abstract String getUploadedFileTempDir(); /** * Returns a Map that takes color palette names as keys, and returns * the color palette as a result. */ public abstract Map> getColorPalette(); /** * Returns a Map that performs message formatting with a recursive Map * structure. The first key must be the message formatting mask, and the * second the first parameter into the message. (The formatter Map supports * only a single parameter at this time.) */ public abstract Map> getFormatter(); /** * Returns the Agent information for the current context */ public abstract Agent getAgent(); /** * Saves the state of a UIComponent tree into an Object. The * Object will be serializable, unless a UIComponent * in this tree contains a non-serializable property. This * method does not check that condition. * @param component the component * @return an Object that can be passed to restoreComponent() * to reinstantiate the state */ public abstract Object saveComponent(UIComponent component); /** * Restores the state of a component. * @param state an Object created by a prior call to saveComponent(). * @return the component */ public abstract UIComponent restoreComponent(Object state) throws ClassNotFoundException, InstantiationException, IllegalAccessException; /** *

* Returns the WindowManager for this request. A non-null WindowManager * will always be returned. *

* The default implementation uses the first WindowManagerFactory specified * implementation class in a file named * org.apache.myfaces.trinidad.context.WindowManagerFactory * in the META-INF/services directory and uses the WindowManagerFactory * to create the WindowManager for this Session. If no WindowManagerFactory is * found, a default WindowManager that never returns any Windows is used. *

* @return the WindowManager used for this Session. */ public WindowManager getWindowManager() { // implement getWindowManager() in RequestContext for backwards compatibility // check if we have cached it for the request WindowManager windowManager = _windowManager; // get instance using the WindowManagerFactory if (windowManager == null) { FacesContext context = FacesContext.getCurrentInstance(); // just in case we're called before the real JSF lifecycle starts if (context != null) { // check if we have cached it per session ExternalContext extContext = context.getExternalContext(); // create a new instance using the WindowManagerFactory ConcurrentMap concurrentAppMap = getApplicationScopedConcurrentMap(); WindowManagerFactory windowManagerFactory = (WindowManagerFactory)concurrentAppMap.get( _WINDOW_MANAGER_FACTORY_CLASS_NAME); if (windowManagerFactory == null) { // we haven't registered a WindowManagerFactory yet, so use the services api to see // if a factory has been registered List windowManagerFactories = ClassLoaderUtils.getServices(_WINDOW_MANAGER_FACTORY_CLASS_NAME); if (windowManagerFactories.isEmpty()) { // no factory registered so use the factory that returns dummy stub WindowManagers windowManagerFactory = _STUB_WINDOW_MANAGER_FACTORY; } else { // only one WindowManager is allowed, use it windowManagerFactory = windowManagerFactories.get(0); } // save the WindowManagerFactory to the application if it hasn't already been saved // if it has been saved, use the previously registered WindowManagerFactory WindowManagerFactory oldWindowManagerFactory = (WindowManagerFactory) concurrentAppMap.putIfAbsent(_WINDOW_MANAGER_FACTORY_CLASS_NAME, windowManagerFactory); if (oldWindowManagerFactory != null) windowManagerFactory = oldWindowManagerFactory; } // create WindowManagerFactory // get the WindowManager from the factory. The factory will create a new instance // for this session if necessary windowManager = windowManagerFactory.getWindowManager(extContext); // remember for the next call on this thread _windowManager = windowManager; } } return windowManager; } /** * Get the component context manager. * @return The manager of component context changes to be used to suspend and resume * component specific context changes. */ public ComponentContextManager getComponentContextManager() { if (_componentContextManager == null) { _componentContextManager = new ComponentContextManagerImpl(); } return _componentContextManager; } /** * Push the component onto the stack so we know the current component being processed. * @param context the FacesContext for the current request * @param component an UIComponent object to be pushed as current component. * @exception NullPointerException if component is null. * @see popCurrentComponent(FacesContext, UIComponent) and getCurrentComponent() */ public void pushCurrentComponent(FacesContext context, UIComponent component) { return; } /** * Pop the component out from the stack. * @param context the FacesContext for the current request * @param component an UIComponent object to be poped. * @exception IllegalStateException if component is not the same * as the current top component in the component stack. * @see pushCurrentComponent(FacesContext, UIComponent) and getCurrentComponent() */ public void popCurrentComponent(FacesContext context, UIComponent component) { return; } /** * Returns the current component being processed. * @see pushCurrentComponent(FacesContext, UIComponent) and popCurrentComponent(FacesContext, UIComponent) */ public UIComponent getCurrentComponent() { return null; } /** * Releases the RequestContext object. This method must only * be called by the code that created the RequestContext. * @exception IllegalStateException if no RequestContext is attached * to the thread, or the attached context is not this object */ public void release() { if (_LOG.isFinest()) { _LOG.finest("RequestContext released.", new RuntimeException("This is not an error. This trace is for debugging.")); } Object o = _CURRENT_CONTEXT.get(); if (o == null) throw new IllegalStateException( _addHelp("RequestContext was already released or " + "had never been attached.")); if (o != this) throw new IllegalStateException(_LOG.getMessage( "RELEASE_DIFFERENT_REQUESTCONTEXT_THAN_CURRENT_ONE")); _CURRENT_CONTEXT.remove(); } /** * Release any state maintained at the application level. Called when the servlet context is * being destroyed. */ public static void releaseApplicationState() { _APPLICATION_MAPS.remove(_getClassLoader()); } /** * Attaches a RequestContext to the current thread. This method * should only be called by a RequestContext object itself. * @exception IllegalStateException if an RequestContext is already * attached to the thread */ public void attach() { if (_LOG.isFinest()) { _LOG.finest("RequestContext attached.", new RuntimeException(_LOG.getMessage( "DEBUGGING_TRACE_NOT_ERROR"))); } Object o = _CURRENT_CONTEXT.get(); if (o != null) { throw new IllegalStateException( _addHelp("Trying to attach RequestContext to a " + "thread that already had one.")); } _CURRENT_CONTEXT.set(this); } private static String _addHelp(String error) { if (!_LOG.isFinest()) { error += " To enable stack traces of each RequestContext attach/release call," + " enable Level.FINEST logging for the "+RequestContext.class; } return error; } // // Pick a ClassLoader // private static ClassLoader _getClassLoader() { return Thread.currentThread().getContextClassLoader(); } /** * Default WindowManagerFactory implementation that returns the StubWindowManager */ private static final class StubWindowManagerFactory extends WindowManagerFactory { public WindowManager getWindowManager(ExternalContext extContext) { return _STUB_WINDOW_MANAGER; } private static final WindowManager _STUB_WINDOW_MANAGER = new StubWindowManager(); } /** * Default WindowManager implementation that returns no Windows */ private static final class StubWindowManager extends WindowManager { @Override public Window getCurrentWindow(ExternalContext extContext) { return null; } @Override public Map getWindows(ExternalContext extContext) { return Collections.emptyMap(); } @Override public void addWindowLifecycleListener( ExternalContext extContext, WindowLifecycleListener windowListener) { // do nothing } @Override public void removeWindowLifecycleListener( ExternalContext extContext, WindowLifecycleListener windowListener) { // do nothing } @Override public void writeState(FacesContext context) throws IOException { // do nothing } } /* singleton for WindowManagerFactory that returns WindowManagers that don't do anything */ private static final WindowManagerFactory _STUB_WINDOW_MANAGER_FACTORY = new StubWindowManagerFactory(); private static final String _WINDOW_MANAGER_FACTORY_CLASS_NAME = WindowManagerFactory.class.getName(); @SuppressWarnings({"CollectionWithoutInitialCapacity"}) private static final ConcurrentMap> _APPLICATION_MAPS = new ConcurrentHashMap>(); static private final ThreadLocal _CURRENT_CONTEXT = new ThreadLocal(); static private final String _CURRENT_COMPONENT_BINDING_CONTEXT_KEY = RequestContext.class.getName() + ".CCBCK"; static private final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(RequestContext.class); private ComponentContextManager _componentContextManager; private TagExecution _tagExecution = TagExecution.FULL; // window manager for this request private WindowManager _windowManager; }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy