/* * Copyright 2004-2012 the original author or authors. * * Licensed 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.springframework.webflow.context; import java.io.Writer; import java.security.Principal; import java.util.Locale; import org.springframework.webflow.core.collection.MutableAttributeMap; import org.springframework.webflow.core.collection.ParameterMap; import org.springframework.webflow.core.collection.SharedAttributeMap; /** * A facade that provides normalized access to an external system that has called into the Spring Web Flow system. * <p> * This context object provides a normalized interface for internal web flow artifacts to use to reason on and * manipulate the state of an external actor calling into SWF to execute flows. It represents the context about a * single, <i>external</i> client request to manipulate a flow execution. * <p> * The design of this interface was inspired by JSF's own ExternalContext abstraction and shares the same name for * consistency. If a particular external client type does not support all methods defined by this interface, they can * just be implemented as returning an empty map or <code>null</code>. * * @author Keith Donald * @author Erwin Vervaet * @author Jeremy Grelle * @author Scott Andrews */ public interface ExternalContext { /** * Returns the logical path to the application hosting this external context. * @return the context path */ public String getContextPath(); /** * Provides access to the parameters associated with the user request that led to SWF being called. This map is * expected to be immutable and cannot be changed. * @return the immutable request parameter map */ public ParameterMap getRequestParameterMap(); /** * Provides access to the external request attribute map, providing a storage for data local to the current user * request and accessible to both internal and external SWF artifacts. * @return the mutable request attribute map */ public MutableAttributeMap<Object> getRequestMap(); /** * Provides access to the external session map, providing a storage for data local to the current user session and * accessible to both internal and external SWF artifacts. * @return the mutable session attribute map */ public SharedAttributeMap<Object> getSessionMap(); /** * Provides access to the <i>global</i> external session map, providing a storage for data globally accross the user * session and accessible to both internal and external SWF artifacts. * <p> * Note: most external context implementations do not distinguish between the concept of a "local" user session * scope and a "global" session scope. The Portlet world does, but not the Servlet for example. In those cases * calling this method returns the same map as calling {@link #getSessionMap()}. * @return the mutable global session attribute map */ public SharedAttributeMap<Object> getGlobalSessionMap(); /** * Provides access to the external application map, providing a storage for data local to the current user * application and accessible to both internal and external SWF artifacts. * @return the mutable application attribute map */ public SharedAttributeMap<Object> getApplicationMap(); /** * Returns true if the current request is an asynchronous Ajax request. * @return true if the current request is an Ajax request */ public boolean isAjaxRequest(); /** * Get a flow execution URL for the execution with the provided key. Typically used by response writers that write * out references to the flow execution to support postback on a subsequent request. The URL returned is encoded. * @param flowId the flow definition id * @param flowExecutionKey the flow execution key * @return the flow execution URL */ public String getFlowExecutionUrl(String flowId, String flowExecutionKey); /** * Provides access to the user's principal security object. * @return the user principal */ public Principal getCurrentUser(); /** * Returns the client locale. * @return the locale */ public Locale getLocale(); /** * Provides access to the context object for the current environment. * @return the environment specific context object */ public Object getNativeContext(); /** * Provides access to the request object for the current environment. * @return the environment specific request object. */ public Object getNativeRequest(); /** * Provides access to the response object for the current environment. * @return the environment specific response object. */ public Object getNativeResponse(); /** * Get a writer for writing out a response. * @return the writer * @throws IllegalStateException if the response has completed or is not allowed */ public Writer getResponseWriter() throws IllegalStateException; /** * Is a <i>render</i> response allowed to be written for this request? Always return false after a response has been * completed. May return false before that to indicate a response is not allowed to be completed. For example, in a * Portlet environment, render responses are only allowed in render requests. * @return true if yes, false otherwise */ public boolean isResponseAllowed(); /** * Request that a flow execution redirect be performed by the calling environment. Typically called from within a * flow execution to request a refresh operation, usually to support "refresh after event processing" behavior. * Calling this method also sets responseComplete status to true. * @see #isResponseComplete() * @throws IllegalStateException if the response has completed */ public void requestFlowExecutionRedirect() throws IllegalStateException; /** * Request that a flow definition redirect be performed by the calling environment. Typically called from within a * flow execution end state to request starting a new, independent execution of a flow in a chain-like manner. * Calling this method also sets responseComplete status to true. * @see #isResponseComplete() * @param flowId the id of the flow definition to redirect to * @param input input to pass the flow; this input is generally encoded the url to launch the flow * @throws IllegalStateException if the response has completed */ public void requestFlowDefinitionRedirect(String flowId, MutableAttributeMap<?> input) throws IllegalStateException; /** * Request a redirect to an arbitrary resource location. May not be supported in some environments. Calling this * method also sets responseComplete status to true. * @see #isResponseComplete() * @param location the location of the resource to redirect to * @throws IllegalStateException if the response has completed */ public void requestExternalRedirect(String location) throws IllegalStateException; /** * Request that the current redirect requested be sent to the client in a manner that causes the client to issue the * redirect from a popup dialog. Only call this method after a redirect has been requested. * @see #requestFlowExecutionRedirect() * @see #requestFlowDefinitionRedirect(String, MutableAttributeMap) * @see #requestExternalRedirect(String) * @throws IllegalStateException if a redirect has not been requested */ public void requestRedirectInPopup() throws IllegalStateException; /** * Called by flow artifacts such as View states and end states to indicate they handled the response, typically by * writing out content to the response stream. Setting this flag allows this external context to know the response * was handled, and that it not need to take additional response handling action itself. */ public void recordResponseComplete(); /** * Has the response been completed? Response complete status can be achieved by: * <ul> * <li>Writing out the response and calling {@link #recordResponseComplete()}, or * <li>Calling one of the redirect request methods * </ul> * @see #getResponseWriter() * @see #recordResponseComplete() * @see #requestFlowExecutionRedirect() * @see #requestFlowDefinitionRedirect(String, MutableAttributeMap) * @see #requestExternalRedirect(String) * @return true if yes, false otherwise */ public boolean isResponseComplete(); /** * Returns true if the response has been completed with flow execution redirect request. * @return true if a redirect response has been completed * @see #isResponseComplete() * @see #requestFlowExecutionRedirect() */ public boolean isResponseCompleteFlowExecutionRedirect(); }