Merge changes for JSF 2.2+ baseline
This commit is contained in:
@@ -75,7 +75,7 @@ public class AbstractFacesFlowConfiguration implements ApplicationContextAware {
|
||||
* @return the created builder
|
||||
*/
|
||||
protected FlowExecutorBuilder getFlowExecutorBuilder(FlowDefinitionLocator flowRegistry) {
|
||||
return new FlowExecutorBuilder(flowRegistry, this.applicationContext);
|
||||
return new FlowExecutorBuilder(flowRegistry);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-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.faces.support;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.faces.FacesWrapper;
|
||||
import javax.faces.application.StateManager.SerializedView;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.render.ResponseStateManager;
|
||||
|
||||
/**
|
||||
* Provides a simple implementation of {@link ResponseStateManager} that can be subclassed by developers wishing to
|
||||
* provide specialized behavior to an existing {@link ResponseStateManager instance} . The default implementation of all
|
||||
* methods is to call through to the wrapped {@link ResponseStateManager}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*
|
||||
* @since 2.4
|
||||
*/
|
||||
public abstract class ResponseStateManagerWrapper extends ResponseStateManager implements
|
||||
FacesWrapper<ResponseStateManager> {
|
||||
|
||||
public abstract ResponseStateManager getWrapped();
|
||||
|
||||
@Override
|
||||
public void writeState(FacesContext context, Object state) throws IOException {
|
||||
getWrapped().writeState(context, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void writeState(FacesContext context, SerializedView state) throws IOException {
|
||||
getWrapped().writeState(context, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getState(FacesContext context, String viewId) {
|
||||
return getWrapped().getState(context, viewId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Object getTreeStructureToRestore(FacesContext context, String viewId) {
|
||||
return getWrapped().getTreeStructureToRestore(context, viewId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Object getComponentStateToRestore(FacesContext context) {
|
||||
return getWrapped().getComponentStateToRestore(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPostback(FacesContext context) {
|
||||
return getWrapped().isPostback(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getViewState(FacesContext context, Object state) {
|
||||
return getWrapped().getViewState(context, state);
|
||||
}
|
||||
}
|
||||
@@ -94,12 +94,10 @@ public class FlowApplication extends ApplicationWrapper {
|
||||
return (delegateViewHandler != null) && (!(delegateViewHandler instanceof FlowViewHandler));
|
||||
}
|
||||
|
||||
private boolean wrapAndSetViewHandler(ViewHandler target) {
|
||||
private void wrapAndSetViewHandler(ViewHandler target) {
|
||||
if ((target != null) && (!(target instanceof FlowViewHandler))) {
|
||||
ViewHandler handler = new FlowViewHandler(target);
|
||||
super.setViewHandler(handler);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,10 @@
|
||||
*/
|
||||
package org.springframework.faces.webflow;
|
||||
|
||||
import javax.faces.render.RenderKit;
|
||||
import javax.faces.render.RenderKitWrapper;
|
||||
import javax.faces.render.ResponseStateManager;
|
||||
|
||||
/**
|
||||
* A render kit implementation that ensures use of Web Flow's FlowViewResponseStateManager, which takes over reading and
|
||||
* writing JSF state and manages that in Web Flow's view scope.
|
||||
@@ -23,15 +27,6 @@ package org.springframework.faces.webflow;
|
||||
* @author Phillip Webb
|
||||
* @since 2.2.0
|
||||
*/
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
import javax.faces.render.RenderKit;
|
||||
import javax.faces.render.RenderKitWrapper;
|
||||
import javax.faces.render.ResponseStateManager;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
public class FlowRenderKit extends RenderKitWrapper {
|
||||
|
||||
private final RenderKit wrapped;
|
||||
@@ -40,24 +35,7 @@ public class FlowRenderKit extends RenderKitWrapper {
|
||||
|
||||
public FlowRenderKit(RenderKit wrapped) {
|
||||
this.wrapped = wrapped;
|
||||
this.flowViewResponseStateManager = initResponseStateManager(wrapped.getResponseStateManager());
|
||||
}
|
||||
|
||||
private ResponseStateManager initResponseStateManager(ResponseStateManager wrapped) {
|
||||
if (JsfRuntimeInformation.isMojarraPresent() && !JsfRuntimeInformation.isMyFacesInUse()) {
|
||||
return new FlowResponseStateManager(wrapped);
|
||||
}
|
||||
Constructor<?> constructor;
|
||||
try {
|
||||
String className = "org.springframework.faces.webflow.MyFacesFlowResponseStateManager";
|
||||
Class<?> clazz = ClassUtils.forName(className, FlowRenderKit.class.getClassLoader());
|
||||
constructor = ClassUtils.getConstructorIfAvailable(clazz, FlowResponseStateManager.class);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new IllegalStateException("Could not initialize MyFacesFlowResponseStateManager", e);
|
||||
} catch (LinkageError e) {
|
||||
throw new IllegalStateException("Could not initialize MyFacesFlowResponseStateManager", e);
|
||||
}
|
||||
return (ResponseStateManager) BeanUtils.instantiateClass(constructor, new FlowResponseStateManager(wrapped));
|
||||
this.flowViewResponseStateManager = new FlowResponseStateManager(wrapped.getResponseStateManager());
|
||||
}
|
||||
|
||||
public RenderKit getWrapped() {
|
||||
@@ -74,4 +52,5 @@ public class FlowRenderKit extends RenderKitWrapper {
|
||||
}
|
||||
return this.wrapped.getResponseStateManager();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2004-2018 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.faces.webflow;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import javax.faces.FacesException;
|
||||
import javax.faces.application.ResourceHandler;
|
||||
import javax.faces.application.ResourceHandlerWrapper;
|
||||
import javax.faces.application.ViewResource;
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.RequestContextHolder;
|
||||
|
||||
/**
|
||||
* Resolves Facelets resources using Spring Resource paths such as "classpath:foo.xhtml".
|
||||
* <p>This handler is auto-configured in the faces-config.xml bundled with the
|
||||
* "spring-faces" module.
|
||||
* @since 2.5
|
||||
*/
|
||||
public class FlowResourceHandler extends ResourceHandlerWrapper {
|
||||
|
||||
private final ResourceHandler wrapped;
|
||||
|
||||
public FlowResourceHandler(ResourceHandler delegate) {
|
||||
this.wrapped = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceHandler getWrapped() {
|
||||
return this.wrapped;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViewResource createViewResource(FacesContext facesContext, String resourceName) {
|
||||
if (!JsfUtils.isFlowRequest()) {
|
||||
return this.wrapped.createViewResource(facesContext, resourceName);
|
||||
}
|
||||
|
||||
try {
|
||||
RequestContext context = RequestContextHolder.getRequestContext();
|
||||
ApplicationContext flowContext = context.getActiveFlow().getApplicationContext();
|
||||
if (flowContext == null) {
|
||||
throw new IllegalStateException(
|
||||
"A Flow ApplicationContext is required to resolve Flow View Resources");
|
||||
}
|
||||
ApplicationContext appContext = flowContext.getParent();
|
||||
Resource viewResource = appContext.getResource(resourceName);
|
||||
URL url = viewResource.getURL();
|
||||
if (viewResource.exists()) {
|
||||
return new ViewResource() {
|
||||
@Override
|
||||
public URL getURL() {
|
||||
return url;
|
||||
}
|
||||
};
|
||||
} else {
|
||||
return this.wrapped.createViewResource(facesContext, resourceName);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
throw new FacesException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,7 +22,6 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.faces.FacesException;
|
||||
import javax.faces.view.facelets.ResourceResolver;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.io.Resource;
|
||||
@@ -31,20 +30,22 @@ import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.RequestContextHolder;
|
||||
|
||||
/**
|
||||
* Resolves Facelets templates using Spring Resource paths such as "classpath:foo.xhtml". Configure it via a context
|
||||
* parameter in web.xml:
|
||||
*
|
||||
* Resolves Facelets templates using Spring Resource paths such as "classpath:foo.xhtml".
|
||||
* Configure it via a context parameter in web.xml:
|
||||
* <pre>
|
||||
* <context-param/>
|
||||
* <param-name>facelets.RESOURCE_RESOLVER</param-name>
|
||||
* <param-value>org.springframework.faces.webflow.FlowResourceResolver</param-value>
|
||||
* </context-param>
|
||||
* </pre>
|
||||
* @deprecated as of 2.5 in favor of {@link FlowResourceHandler}.
|
||||
*/
|
||||
public class FlowResourceResolver extends ResourceResolver {
|
||||
@Deprecated
|
||||
@SuppressWarnings("deprecation")
|
||||
public class FlowResourceResolver extends javax.faces.view.facelets.ResourceResolver {
|
||||
|
||||
/**
|
||||
* All known {@link ResourceResolver} implementations in the priority order
|
||||
* All known {@code ResourceResolver} implementations in the priority order
|
||||
*/
|
||||
private static final List<String> RESOLVERS_CLASSES;
|
||||
static {
|
||||
@@ -54,18 +55,19 @@ public class FlowResourceResolver extends ResourceResolver {
|
||||
RESOLVERS_CLASSES = Collections.unmodifiableList(resolvers);
|
||||
}
|
||||
|
||||
private final ResourceResolver delegateResolver;
|
||||
private final javax.faces.view.facelets.ResourceResolver delegateResolver;
|
||||
|
||||
public FlowResourceResolver() {
|
||||
this.delegateResolver = createDelegateResolver();
|
||||
}
|
||||
|
||||
private ResourceResolver createDelegateResolver() {
|
||||
private javax.faces.view.facelets.ResourceResolver createDelegateResolver() {
|
||||
try {
|
||||
ClassLoader classLoader = getClass().getClassLoader();
|
||||
for (String resolverClass : RESOLVERS_CLASSES) {
|
||||
if (ClassUtils.isPresent(resolverClass, classLoader)) {
|
||||
return (ResourceResolver) ClassUtils.forName(resolverClass, classLoader).newInstance();
|
||||
return (javax.faces.view.facelets.ResourceResolver)
|
||||
ClassUtils.forName(resolverClass, classLoader).newInstance();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.faces.webflow;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
|
||||
import javax.faces.FacesWrapper;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
import javax.faces.render.RenderKitFactory;
|
||||
@@ -25,7 +26,7 @@ import javax.faces.render.ResponseStateManager;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.faces.support.ResponseStateManagerWrapper;
|
||||
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.RequestContextHolder;
|
||||
|
||||
@@ -38,7 +39,8 @@ import org.springframework.webflow.execution.RequestContextHolder;
|
||||
*
|
||||
* @since 2.2.0
|
||||
*/
|
||||
public class FlowResponseStateManager extends ResponseStateManagerWrapper {
|
||||
public class FlowResponseStateManager extends ResponseStateManager
|
||||
implements FacesWrapper<ResponseStateManager> {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(FlowResponseStateManager.class);
|
||||
|
||||
@@ -61,6 +63,11 @@ public class FlowResponseStateManager extends ResponseStateManagerWrapper {
|
||||
return this.wrapped;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStateless(FacesContext context, String viewId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeState(FacesContext facesContext, Object state) throws IOException {
|
||||
if (!JsfUtils.isFlowRequest()) {
|
||||
@@ -142,4 +149,15 @@ public class FlowResponseStateManager extends ResponseStateManagerWrapper {
|
||||
writer.endElement("input");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPostback(FacesContext context) {
|
||||
return getWrapped().isPostback(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCryptographicallyStrongTokenFromSession(FacesContext context) {
|
||||
return getWrapped().getCryptographicallyStrongTokenFromSession(context);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ import javax.el.ExpressionFactory;
|
||||
import javax.el.ValueExpression;
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.springframework.expression.AccessException;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.PropertyAccessor;
|
||||
import org.springframework.expression.TypedValue;
|
||||
|
||||
@@ -20,7 +20,6 @@ import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.FacesContextWrapper;
|
||||
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* Helper class to provide information about the JSF runtime environment such as
|
||||
@@ -33,33 +32,6 @@ public class JsfRuntimeInformation {
|
||||
|
||||
private static final ClassLoader CLASSLOADER = JsfRuntimeInformation.class.getClassLoader();
|
||||
|
||||
|
||||
public static final int JSF_22 = 4;
|
||||
|
||||
public static final int JSF_21 = 3;
|
||||
|
||||
public static final int JSF_20 = 2;
|
||||
|
||||
public static final int JSF_12 = 1;
|
||||
|
||||
public static final int JSF_11 = 0;
|
||||
|
||||
private static final int jsfVersion;
|
||||
|
||||
static {
|
||||
if (ReflectionUtils.findMethod(FacesContext.class, "getResourceLibraryContracts") != null) {
|
||||
jsfVersion = JSF_22;
|
||||
} else if (ReflectionUtils.findMethod(FacesContext.class, "isReleased") != null) {
|
||||
jsfVersion = JSF_21;
|
||||
} else if (ReflectionUtils.findMethod(FacesContext.class, "isPostback") != null) {
|
||||
jsfVersion = JSF_20;
|
||||
} else if (ReflectionUtils.findMethod(FacesContext.class, "getELContext") != null) {
|
||||
jsfVersion = JSF_12;
|
||||
} else {
|
||||
jsfVersion = JSF_11;
|
||||
}
|
||||
}
|
||||
|
||||
private static final boolean mojarraPresent =
|
||||
ClassUtils.isPresent("com.sun.faces.context.FacesContextImpl", CLASSLOADER);
|
||||
|
||||
@@ -69,25 +41,39 @@ public class JsfRuntimeInformation {
|
||||
private static Boolean myFacesInUse;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated as of 2.5, always returns true.
|
||||
*/
|
||||
public static boolean isAtLeastJsf22() {
|
||||
return jsfVersion >= JSF_22;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated as of 2.5, always returns true.
|
||||
*/
|
||||
public static boolean isAtLeastJsf21() {
|
||||
return jsfVersion >= JSF_21;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated as of 2.5, always returns true.
|
||||
*/
|
||||
public static boolean isAtLeastJsf20() {
|
||||
return jsfVersion >= JSF_20;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated as of 2.5, always returns true.
|
||||
*/
|
||||
public static boolean isAtLeastJsf12() {
|
||||
return jsfVersion >= JSF_12;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated as of 2.5, always returns false.
|
||||
*/
|
||||
public static boolean isLessThanJsf20() {
|
||||
return jsfVersion < JSF_20;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@ package org.springframework.faces.webflow;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.FactoryFinder;
|
||||
import javax.faces.application.ApplicationFactory;
|
||||
import javax.faces.component.visit.VisitContextFactory;
|
||||
@@ -103,9 +102,7 @@ public class JsfUtils {
|
||||
FACTORY_NAMES.put(ApplicationFactory.class, FactoryFinder.APPLICATION_FACTORY);
|
||||
FACTORY_NAMES.put(ExceptionHandlerFactory.class, FactoryFinder.EXCEPTION_HANDLER_FACTORY);
|
||||
FACTORY_NAMES.put(ExternalContextFactory.class, FactoryFinder.EXTERNAL_CONTEXT_FACTORY);
|
||||
if (JsfRuntimeInformation.isAtLeastJsf21()) {
|
||||
FACTORY_NAMES.put(FaceletCacheFactory.class, FactoryFinder.FACELET_CACHE_FACTORY);
|
||||
}
|
||||
FACTORY_NAMES.put(FaceletCacheFactory.class, FactoryFinder.FACELET_CACHE_FACTORY);
|
||||
FACTORY_NAMES.put(FacesContextFactory.class, FactoryFinder.FACES_CONTEXT_FACTORY);
|
||||
FACTORY_NAMES.put(LifecycleFactory.class, FactoryFinder.LIFECYCLE_FACTORY);
|
||||
FACTORY_NAMES.put(PartialViewContextFactory.class, FactoryFinder.PARTIAL_VIEW_CONTEXT_FACTORY);
|
||||
|
||||
@@ -21,6 +21,8 @@ import java.io.Serializable;
|
||||
import javax.faces.component.UIViewRoot;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.lifecycle.Lifecycle;
|
||||
import javax.faces.view.StateManagementStrategy;
|
||||
import javax.faces.view.ViewDeclarationLanguage;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -119,7 +121,13 @@ public class JsfView implements View {
|
||||
public void saveState() {
|
||||
FacesContext facesContext = FlowFacesContext.getCurrentInstance();
|
||||
facesContext.setViewRoot(this.viewRoot);
|
||||
facesContext.getApplication().getStateManager().saveView(facesContext);
|
||||
ViewDeclarationLanguage viewDeclarationLanguage = facesContext.getApplication().getViewHandler()
|
||||
.getViewDeclarationLanguage(facesContext, this.viewId);
|
||||
StateManagementStrategy stateManagementStrategy = (viewDeclarationLanguage == null ? null
|
||||
: viewDeclarationLanguage.getStateManagementStrategy(facesContext, this.viewId));
|
||||
if (stateManagementStrategy != null) {
|
||||
stateManagementStrategy.saveView(facesContext);
|
||||
}
|
||||
}
|
||||
|
||||
public Serializable getUserEventState() {
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
/*
|
||||
* 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.faces.webflow;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.faces.FacesWrapper;
|
||||
import javax.faces.application.StateManager.SerializedView;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.render.ResponseStateManager;
|
||||
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.RequestContextHolder;
|
||||
|
||||
/**
|
||||
* A wrapper for {@link FlowResponseStateManager} used to support MyFaces partial
|
||||
* state saving. MyFaces supports an extension to the {@link ResponseStateManager}
|
||||
* that reduces the amount of buffering required when writing a response. Empty
|
||||
* state is provided at the time that the {@link #writeState(FacesContext, Object)
|
||||
* writeState} method is invoked with an additional
|
||||
* {@link #saveState(FacesContext, Object) saveState} method called later
|
||||
* containing the real state to save.
|
||||
*
|
||||
* <p>Since JSF 2.0, the strategy used by MyFaces to determine if a
|
||||
* {@link org.apache.myfaces.renderkit.MyfacesResponseStateManager} is available
|
||||
* will always succeed since it
|
||||
* follows {@link FacesWrapper}s to find the root <tt>HtmlResponseStateManager</tt>
|
||||
* implementation. Since state management for web flow requests is handled by the
|
||||
* {@link FlowResponseStateManager} this* assumption causes problems and results
|
||||
* in empty state data being saved. This wrapper provides the additional hook
|
||||
* required to ensure that the {@link #saveState(FacesContext, Object) saveState}
|
||||
* method also triggers web flow state management.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @since 2.4
|
||||
* @see FlowResponseStateManager
|
||||
* @see FlowRenderKit
|
||||
*/
|
||||
public class MyFacesFlowResponseStateManager extends ResponseStateManager
|
||||
implements FacesWrapper<ResponseStateManager> {
|
||||
|
||||
private final ResponseStateManager wrapped;
|
||||
|
||||
public MyFacesFlowResponseStateManager(FlowResponseStateManager wrapped) {
|
||||
this.wrapped = wrapped;
|
||||
}
|
||||
|
||||
public ResponseStateManager getWrapped() {
|
||||
return this.wrapped;
|
||||
}
|
||||
|
||||
public void saveState(FacesContext facesContext, Object state) {
|
||||
RequestContext requestContext = RequestContextHolder.getRequestContext();
|
||||
requestContext.getViewScope().put(FlowResponseStateManager.FACES_VIEW_STATE, state);
|
||||
}
|
||||
|
||||
public Object getComponentStateToRestore(FacesContext context) {
|
||||
return getWrapped().getComponentStateToRestore(context);
|
||||
}
|
||||
|
||||
public Object getState(FacesContext context, String viewId) {
|
||||
return getWrapped().getState(context, viewId);
|
||||
}
|
||||
|
||||
public Object getTreeStructureToRestore(FacesContext context, String viewId) {
|
||||
return getWrapped().getTreeStructureToRestore(context, viewId);
|
||||
}
|
||||
|
||||
public String getViewState(FacesContext context, Object state) {
|
||||
return getWrapped().getViewState(context, state);
|
||||
}
|
||||
|
||||
public boolean isPostback(FacesContext context) {
|
||||
return getWrapped().isPostback(context);
|
||||
}
|
||||
|
||||
public void writeState(FacesContext context, Object state) throws IOException {
|
||||
getWrapped().writeState(context, state);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void writeState(FacesContext context, SerializedView state) throws IOException {
|
||||
getWrapped().writeState(context, state);
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@
|
||||
<action-listener>org.springframework.faces.webflow.FlowActionListener</action-listener>
|
||||
<action-listener>org.springframework.faces.model.SelectionTrackingActionListener</action-listener>
|
||||
<el-resolver>org.springframework.faces.webflow.FlowELResolver</el-resolver>
|
||||
<resource-handler>org.springframework.faces.webflow.FlowResourceHandler</resource-handler>
|
||||
</application>
|
||||
|
||||
<factory>
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package org.springframework.faces.webflow;
|
||||
|
||||
import javax.el.ELContext;
|
||||
import javax.el.MethodExpression;
|
||||
import javax.el.MethodInfo;
|
||||
import javax.faces.component.UICommand;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.el.EvaluationException;
|
||||
import javax.faces.el.MethodBinding;
|
||||
import javax.faces.el.MethodNotFoundException;
|
||||
import javax.faces.event.ActionEvent;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
@@ -44,9 +43,9 @@ public class FlowActionListenerTests extends TestCase {
|
||||
public final void testProcessAction() {
|
||||
|
||||
String outcome = "foo";
|
||||
MethodBinding binding = new MethodBindingStub(outcome);
|
||||
MethodExpression expression = new MethodExpressionStub(outcome);
|
||||
UICommand commandButton = new UICommand();
|
||||
commandButton.setAction(binding);
|
||||
commandButton.setActionExpression(expression);
|
||||
ActionEvent event = new ActionEvent(commandButton);
|
||||
|
||||
this.listener.processAction(event);
|
||||
@@ -60,9 +59,9 @@ public class FlowActionListenerTests extends TestCase {
|
||||
public final void testProcessAction_NullOutcome() {
|
||||
|
||||
String outcome = null;
|
||||
MethodBinding binding = new MethodBindingStub(outcome);
|
||||
MethodExpression expression = new MethodExpressionStub(outcome);
|
||||
UICommand commandButton = new UICommand();
|
||||
commandButton.setAction(binding);
|
||||
commandButton.setActionExpression(expression);
|
||||
ActionEvent event = new ActionEvent(commandButton);
|
||||
|
||||
this.listener.processAction(event);
|
||||
@@ -71,22 +70,43 @@ public class FlowActionListenerTests extends TestCase {
|
||||
this.jsfMock.externalContext().getRequestMap().containsKey(JsfView.EVENT_KEY));
|
||||
}
|
||||
|
||||
private class MethodBindingStub extends MethodBinding {
|
||||
private class MethodExpressionStub extends MethodExpression {
|
||||
|
||||
String result;
|
||||
|
||||
public MethodBindingStub(String result) {
|
||||
public MethodExpressionStub(String result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public Class<?> getType(FacesContext context) throws MethodNotFoundException {
|
||||
return String.class;
|
||||
@Override
|
||||
public MethodInfo getMethodInfo(ELContext context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object invoke(FacesContext context, Object... args) throws EvaluationException {
|
||||
@Override
|
||||
public Object invoke(ELContext context, Object[] params) {
|
||||
return this.result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExpressionString() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLiteralText() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private class MockViewState extends ViewState {
|
||||
|
||||
@@ -16,15 +16,18 @@ public class FlowResponseStateManagerTests extends TestCase {
|
||||
|
||||
private final JSFMockHelper jsfMock = new JSFMockHelper();
|
||||
|
||||
private StaticWebApplicationContext webappContext;
|
||||
|
||||
private FlowResponseStateManager responseStateManager;
|
||||
|
||||
private RequestContext requestContext;
|
||||
private FlowExecutionContext flowExecutionContext;
|
||||
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
this.jsfMock.setUp();
|
||||
StaticWebApplicationContext webappContext = new StaticWebApplicationContext();
|
||||
webappContext.setServletContext(this.jsfMock.servletContext());
|
||||
this.webappContext = new StaticWebApplicationContext();
|
||||
this.webappContext.setServletContext(this.jsfMock.servletContext());
|
||||
|
||||
this.requestContext = EasyMock.createMock(RequestContext.class);
|
||||
RequestContextHolder.setRequestContext(this.requestContext);
|
||||
@@ -35,6 +38,7 @@ public class FlowResponseStateManagerTests extends TestCase {
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
this.webappContext.close();
|
||||
this.jsfMock.tearDown();
|
||||
RequestContextHolder.setRequestContext(null);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ public class JsfManagedBeanAwareELExpressionParserTests extends TestCase {
|
||||
RequestContextHolder.setRequestContext(null);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testGetJSFBean() {
|
||||
this.jsfMock.externalContext().getRequestMap().put("myJsfBean", new Object());
|
||||
Expression expr = this.parser.parseExpression("myJsfBean", new FluentParserContext().evaluate(RequestContext.class));
|
||||
|
||||
@@ -41,11 +41,13 @@ public class JsfManagedBeanPropertyAccessorTests extends TestCase {
|
||||
RequestContextHolder.setRequestContext(null);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testCanRead() {
|
||||
this.jsfMock.externalContext().getRequestMap().put("myJsfBean", new Object());
|
||||
assertTrue(this.accessor.canRead(null, null, "myJsfBean"));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testRead() {
|
||||
Object jsfBean = new Object();
|
||||
this.jsfMock.externalContext().getRequestMap().put("myJsfBean", jsfBean);
|
||||
|
||||
@@ -159,7 +159,7 @@ public class JsfViewFactoryTests extends TestCase {
|
||||
/**
|
||||
* View already exists in view/flash scope and must be restored and the lifecycle executed, no flow event signaled
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@SuppressWarnings({ "deprecation", "unchecked" })
|
||||
public final void testGetView_RestoreWithBindings() {
|
||||
|
||||
this.lifecycle = new NoExecutionLifecycle(this.jsfMock.lifecycle());
|
||||
|
||||
@@ -2,7 +2,6 @@ package org.springframework.faces.webflow;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
|
||||
import javax.faces.FacesException;
|
||||
import javax.faces.component.UIForm;
|
||||
import javax.faces.component.UIInput;
|
||||
@@ -13,10 +12,9 @@ import javax.faces.context.FacesContext;
|
||||
import javax.faces.lifecycle.Lifecycle;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.myfaces.test.mock.MockResponseWriter;
|
||||
import org.apache.myfaces.test.mock.MockStateManager;
|
||||
import org.easymock.EasyMock;
|
||||
|
||||
import org.springframework.webflow.core.collection.MutableAttributeMap;
|
||||
import org.springframework.webflow.execution.FlowExecutionContext;
|
||||
import org.springframework.webflow.execution.FlowExecutionKey;
|
||||
@@ -65,7 +63,6 @@ public class JsfViewTests extends TestCase {
|
||||
|
||||
this.jsfMock.setUp();
|
||||
this.jsfMock.facesContext().getApplication().setViewHandler(new MockViewHandler());
|
||||
this.jsfMock.facesContext().getApplication().setStateManager(new TestStateManager());
|
||||
this.jsfMock.facesContext().setResponseWriter(new MockResponseWriter(this.output, null, null));
|
||||
|
||||
UIViewRoot viewToRender = new UIViewRoot();
|
||||
@@ -210,13 +207,6 @@ public class JsfViewTests extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
private class TestStateManager extends MockStateManager {
|
||||
public SerializedView saveSerializedView(FacesContext context) {
|
||||
SerializedView state = new SerializedView(new Object[] { "tree_state" }, new Object[] { "component_state" });
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
private class NoEventLifecycle extends FlowLifecycle {
|
||||
|
||||
boolean executed = false;
|
||||
|
||||
@@ -1,169 +0,0 @@
|
||||
/*
|
||||
* 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.faces.webflow;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.faces.FacesException;
|
||||
import javax.faces.application.Application;
|
||||
import javax.faces.application.NavigationHandler;
|
||||
import javax.faces.application.StateManager;
|
||||
import javax.faces.application.ViewHandler;
|
||||
import javax.faces.component.UIComponent;
|
||||
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.faces.validator.Validator;
|
||||
|
||||
public class MockApplication extends Application {
|
||||
private ViewHandler viewHandler;
|
||||
|
||||
public ActionListener getActionListener() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setActionListener(ActionListener listener) {
|
||||
}
|
||||
|
||||
public Locale getDefaultLocale() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setDefaultLocale(Locale locale) {
|
||||
}
|
||||
|
||||
public String getDefaultRenderKitId() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setDefaultRenderKitId(String renderKitId) {
|
||||
}
|
||||
|
||||
public String getMessageBundle() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setMessageBundle(String bundle) {
|
||||
}
|
||||
|
||||
public NavigationHandler getNavigationHandler() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setNavigationHandler(NavigationHandler handler) {
|
||||
}
|
||||
|
||||
public PropertyResolver getPropertyResolver() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setPropertyResolver(PropertyResolver resolver) {
|
||||
}
|
||||
|
||||
public VariableResolver getVariableResolver() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setVariableResolver(VariableResolver resolver) {
|
||||
}
|
||||
|
||||
public ViewHandler getViewHandler() {
|
||||
return this.viewHandler;
|
||||
}
|
||||
|
||||
public void setViewHandler(ViewHandler handler) {
|
||||
this.viewHandler = handler;
|
||||
}
|
||||
|
||||
public StateManager getStateManager() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setStateManager(StateManager manager) {
|
||||
}
|
||||
|
||||
public void addComponent(String componentType, String componentClass) {
|
||||
}
|
||||
|
||||
public UIComponent createComponent(String componentType) throws FacesException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public UIComponent createComponent(ValueBinding componentBinding, FacesContext context, String componentType)
|
||||
throws FacesException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Iterator<String> getComponentTypes() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void addConverter(String converterId, String converterClass) {
|
||||
}
|
||||
|
||||
public void addConverter(Class<?> targetClass, String converterClass) {
|
||||
}
|
||||
|
||||
public Converter createConverter(String converterId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Converter createConverter(Class<?> targetClass) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Iterator<String> getConverterIds() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Iterator<Class<?>> getConverterTypes() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public MethodBinding createMethodBinding(String ref, Class<?>... params) throws ReferenceSyntaxException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Iterator<Locale> getSupportedLocales() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setSupportedLocales(Collection<Locale> locales) {
|
||||
}
|
||||
|
||||
public void addValidator(String validatorId, String validatorClass) {
|
||||
}
|
||||
|
||||
public Validator createValidator(String validatorId) throws FacesException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Iterator<String> getValidatorIds() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public ValueBinding createValueBinding(String ref) throws ReferenceSyntaxException {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,6 @@ package org.springframework.faces.webflow;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.security.Principal;
|
||||
import java.util.Collections;
|
||||
|
||||
Reference in New Issue
Block a user