m2 code review / polishing / simplification
- removed flow faces context factory, not needed, favoring simple creation of flow faces context from jsf view factory / jsf view instead - replace response state manager usage with state manager as discussed; allowed removal of custom render kit - removed flow lifecycle factory; not needed, favoring simple creation of flow lifecycle factory from view factory instead. this needs review, several tests still need updating - misc naming improvements - removed use of thread locals where possible
This commit is contained in:
@@ -10,16 +10,12 @@
|
||||
<classpathentry kind="lib" path="lib/global/spring-core.jar"/>
|
||||
<classpathentry kind="lib" path="lib/global/spring-web.jar"/>
|
||||
<classpathentry kind="lib" path="lib/global/spring-webmvc.jar"/>
|
||||
<classpathentry kind="lib" path="lib/buildtime/avalon-framework.jar"/>
|
||||
<classpathentry kind="lib" path="lib/buildtime/commons-beanutils.jar"/>
|
||||
<classpathentry kind="lib" path="lib/buildtime/commons-codec.jar"/>
|
||||
<classpathentry kind="lib" path="lib/buildtime/commons-collections.jar"/>
|
||||
<classpathentry kind="lib" path="lib/buildtime/commons-digester.jar"/>
|
||||
<classpathentry kind="lib" path="lib/buildtime/commons-discovery.jar"/>
|
||||
<classpathentry kind="lib" path="lib/buildtime/concurrent.jar"/>
|
||||
<classpathentry kind="lib" path="lib/buildtime/el-api.jar"/>
|
||||
<classpathentry kind="lib" path="lib/buildtime/log4j.jar"/>
|
||||
<classpathentry kind="lib" path="lib/buildtime/logkit.jar"/>
|
||||
<classpathentry kind="lib" path="lib/buildtime/myfaces-api.jar" sourcepath="/Users/jgrelle/Desktop/myfaces-api-1.2.0-sources.jar"/>
|
||||
<classpathentry kind="lib" path="lib/buildtime/myfaces-impl.jar" sourcepath="/Users/jgrelle/Desktop/myfaces-impl-1.2.0-sources.jar"/>
|
||||
<classpathentry kind="lib" path="lib/test/easymock.jar"/>
|
||||
|
||||
@@ -4,23 +4,14 @@
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
|
||||
|
||||
<factory>
|
||||
<lifecycle-factory>org.springframework.faces.webflow.FlowLifecycleFactory</lifecycle-factory>
|
||||
<faces-context-factory>org.springframework.faces.webflow.FlowFacesContextFactory</faces-context-factory>
|
||||
<render-kit-factory>org.springframework.faces.webflow.FlowRenderKitFactory</render-kit-factory>
|
||||
</factory>
|
||||
|
||||
<application>
|
||||
<action-listener>org.springframework.faces.webflow.FlowActionListener</action-listener>
|
||||
<el-resolver>org.springframework.webflow.core.expression.el.RequestContextELResolver</el-resolver>
|
||||
<el-resolver>org.springframework.webflow.core.expression.el.ScopeSearchingELResolver</el-resolver>
|
||||
<view-handler>org.springframework.faces.webflow.FlowExecutionViewHandler</view-handler>
|
||||
<state-manager>org.springframework.faces.webflow.FlowViewStateManager</state-manager>
|
||||
<view-handler>org.springframework.faces.webflow.FlowViewHandler</view-handler>
|
||||
</application>
|
||||
|
||||
<lifecycle>
|
||||
<phase-listener>org.springframework.faces.support.RequestLoggingPhaseListener</phase-listener>
|
||||
</lifecycle>
|
||||
|
||||
<component>
|
||||
<component-type>spring.faces.DojoClientTextValidator</component-type>
|
||||
<component-class>org.springframework.faces.ui.DojoClientTextValidator</component-class>
|
||||
|
||||
@@ -16,12 +16,14 @@
|
||||
package org.springframework.faces.webflow;
|
||||
|
||||
import javax.faces.application.NavigationHandler;
|
||||
import javax.faces.component.ActionSource;
|
||||
import javax.faces.component.ActionSource2;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.event.AbortProcessingException;
|
||||
import javax.faces.event.ActionEvent;
|
||||
import javax.faces.event.ActionListener;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -34,32 +36,29 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
public class FlowActionListener implements ActionListener {
|
||||
|
||||
private ActionListener delegate;
|
||||
private static final Log logger = LogFactory.getLog(FlowActionListener.class);
|
||||
|
||||
public FlowActionListener(ActionListener delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
public void processAction(ActionEvent actionEvent) throws AbortProcessingException {
|
||||
|
||||
if (!JsfFlowUtils.isFlowRequest()) {
|
||||
delegate.processAction(actionEvent);
|
||||
}
|
||||
|
||||
FacesContext context = FacesContext.getCurrentInstance();
|
||||
ActionSource source = (ActionSource) actionEvent.getSource();
|
||||
ActionSource2 source = (ActionSource2) actionEvent.getSource();
|
||||
String result = null;
|
||||
|
||||
if (source.getAction() != null) {
|
||||
result = (String) source.getAction().invoke(context, null);
|
||||
if (source.getActionExpression() != null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Invoking action expression " + source.getActionExpression());
|
||||
}
|
||||
result = (String) source.getActionExpression().invoke(context.getELContext(), null);
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(result)) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Event '" + result + "' detected");
|
||||
}
|
||||
context.getExternalContext().getRequestMap().put(JsfView.EVENT_KEY, result);
|
||||
} else {
|
||||
logger.debug("No action event detected");
|
||||
context.getExternalContext().getRequestMap().remove(JsfView.EVENT_KEY);
|
||||
}
|
||||
context.renderResponse();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.springframework.binding.message.Messages;
|
||||
import org.springframework.binding.message.Severity;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.RequestContextHolder;
|
||||
|
||||
/**
|
||||
@@ -44,42 +45,30 @@ import org.springframework.webflow.execution.RequestContextHolder;
|
||||
public class FlowFacesContext extends FacesContext {
|
||||
|
||||
/**
|
||||
* The key for storing the responseComplete flag
|
||||
* The Web Flow request context.
|
||||
*/
|
||||
static final String RESPONSE_COMPLETE_KEY = "responseComplete";
|
||||
|
||||
/**
|
||||
* The key for storing the renderResponse flag
|
||||
*/
|
||||
static final String RENDER_RESPONSE_KEY = "renderResponse";
|
||||
private RequestContext context;
|
||||
|
||||
/**
|
||||
* The base FacesContext delegate
|
||||
*/
|
||||
private FacesContext delegate;
|
||||
|
||||
public FlowFacesContext(FacesContext delegate) {
|
||||
public FlowFacesContext(RequestContext context, FacesContext delegate) {
|
||||
this.context = context;
|
||||
this.delegate = delegate;
|
||||
FacesContext.setCurrentInstance(this);
|
||||
setCurrentInstance(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates a FacesMessage to an SWF Message and adds it to the current MessageContext
|
||||
*/
|
||||
public void addMessage(String clientId, FacesMessage message) {
|
||||
if (!JsfFlowUtils.isFlowRequest()) {
|
||||
delegate.addMessage(clientId, message);
|
||||
return;
|
||||
}
|
||||
|
||||
MessageResolver messageResolver;
|
||||
|
||||
StringBuffer msgText = new StringBuffer();
|
||||
|
||||
if (StringUtils.hasText(message.getSummary())) {
|
||||
msgText.append(message.getSummary());
|
||||
}
|
||||
|
||||
if (message.getSeverity() == FacesMessage.SEVERITY_INFO) {
|
||||
messageResolver = Messages.text(msgText.toString(), Severity.INFO);
|
||||
} else if (message.getSeverity() == FacesMessage.SEVERITY_WARN) {
|
||||
@@ -87,18 +76,13 @@ public class FlowFacesContext extends FacesContext {
|
||||
} else {
|
||||
messageResolver = Messages.text(msgText.toString(), Severity.ERROR);
|
||||
}
|
||||
|
||||
RequestContextHolder.getRequestContext().getMessageContext().addMessage(messageResolver);
|
||||
context.getMessageContext().addMessage(messageResolver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Iterator for all component clientId's for which messages have been added.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Iterator<String> getClientIdsWithMessages() {
|
||||
if (!JsfFlowUtils.isFlowRequest()) {
|
||||
return delegate.getClientIdsWithMessages();
|
||||
}
|
||||
return new ClientIdIterator();
|
||||
}
|
||||
|
||||
@@ -107,15 +91,9 @@ public class FlowFacesContext extends FacesContext {
|
||||
* associated with any specific UIComponent. If no such messages have been queued, return null.
|
||||
*/
|
||||
public FacesMessage.Severity getMaximumSeverity() {
|
||||
|
||||
if (!JsfFlowUtils.isFlowRequest()) {
|
||||
return delegate.getMaximumSeverity();
|
||||
}
|
||||
|
||||
if (RequestContextHolder.getRequestContext().getMessageContext().getMessages() == null
|
||||
|| RequestContextHolder.getRequestContext().getMessageContext().getMessages().length == 0)
|
||||
if (context.getMessageContext().getMessages().length == 0) {
|
||||
return null;
|
||||
|
||||
}
|
||||
FacesMessage.Severity max = FacesMessage.SEVERITY_INFO;
|
||||
Iterator<FacesMessage> i = getMessages();
|
||||
while (i.hasNext()) {
|
||||
@@ -132,11 +110,7 @@ public class FlowFacesContext extends FacesContext {
|
||||
/**
|
||||
* Returns an Iterator for all Messages in the current MessageContext that does translation to FacesMessages.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Iterator<FacesMessage> getMessages() {
|
||||
if (!JsfFlowUtils.isFlowRequest()) {
|
||||
return delegate.getMessages();
|
||||
}
|
||||
return new FacesMessageIterator();
|
||||
}
|
||||
|
||||
@@ -144,55 +118,24 @@ public class FlowFacesContext extends FacesContext {
|
||||
* Returns an Iterator for all Messages with the given clientId in the current MessageContext that does translation
|
||||
* to FacesMessages.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Iterator<FacesMessage> getMessages(String clientId) {
|
||||
if (!JsfFlowUtils.isFlowRequest()) {
|
||||
return delegate.getMessages(clientId);
|
||||
}
|
||||
return new FacesMessageIterator(clientId);
|
||||
}
|
||||
|
||||
public boolean getRenderResponse() {
|
||||
if (!JsfFlowUtils.isFlowRequest()) {
|
||||
return delegate.getRenderResponse();
|
||||
}
|
||||
|
||||
Boolean renderResponse = RequestContextHolder.getRequestContext().getFlashScope().getBoolean(
|
||||
RENDER_RESPONSE_KEY);
|
||||
if (renderResponse == null) {
|
||||
return false;
|
||||
}
|
||||
return renderResponse;
|
||||
return delegate.getRenderResponse();
|
||||
}
|
||||
|
||||
public boolean getResponseComplete() {
|
||||
|
||||
if (!JsfFlowUtils.isFlowRequest()) {
|
||||
return delegate.getResponseComplete();
|
||||
}
|
||||
|
||||
Boolean responseComplete = RequestContextHolder.getRequestContext().getFlashScope().getBoolean(
|
||||
RESPONSE_COMPLETE_KEY);
|
||||
if (responseComplete == null) {
|
||||
return false;
|
||||
}
|
||||
return responseComplete;
|
||||
return delegate.getResponseComplete();
|
||||
}
|
||||
|
||||
public void renderResponse() {
|
||||
if (!JsfFlowUtils.isFlowRequest()) {
|
||||
delegate.renderResponse();
|
||||
return;
|
||||
}
|
||||
RequestContextHolder.getRequestContext().getFlashScope().put(RENDER_RESPONSE_KEY, Boolean.TRUE);
|
||||
delegate.renderResponse();
|
||||
}
|
||||
|
||||
public void responseComplete() {
|
||||
if (!JsfFlowUtils.isFlowRequest()) {
|
||||
delegate.responseComplete();
|
||||
return;
|
||||
}
|
||||
RequestContextHolder.getRequestContext().getFlashScope().put(RESPONSE_COMPLETE_KEY, Boolean.TRUE);
|
||||
delegate.responseComplete();
|
||||
}
|
||||
|
||||
// ------------------ Pass-through delegate methods ----------------------//
|
||||
@@ -227,6 +170,7 @@ public class FlowFacesContext extends FacesContext {
|
||||
|
||||
public void release() {
|
||||
delegate.release();
|
||||
setCurrentInstance(null);
|
||||
}
|
||||
|
||||
public void setResponseStream(ResponseStream responseStream) {
|
||||
@@ -245,7 +189,7 @@ public class FlowFacesContext extends FacesContext {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
private class FacesMessageIterator implements Iterator {
|
||||
private class FacesMessageIterator implements Iterator<FacesMessage> {
|
||||
|
||||
private Message[] messages;
|
||||
|
||||
@@ -263,10 +207,9 @@ public class FlowFacesContext extends FacesContext {
|
||||
return messages.length > currentIndex + 1;
|
||||
}
|
||||
|
||||
public Object next() {
|
||||
public FacesMessage next() {
|
||||
currentIndex++;
|
||||
Message nextMessage = messages[currentIndex];
|
||||
|
||||
FacesMessage facesMessage;
|
||||
if (nextMessage.getSeverity() == Severity.INFO) {
|
||||
facesMessage = new FacesMessage(FacesMessage.SEVERITY_INFO, nextMessage.getText(), nextMessage
|
||||
@@ -287,13 +230,12 @@ public class FlowFacesContext extends FacesContext {
|
||||
|
||||
}
|
||||
|
||||
private class ClientIdIterator implements Iterator {
|
||||
private class ClientIdIterator implements Iterator<String> {
|
||||
|
||||
private Message[] messages;
|
||||
|
||||
int currentIndex = -1;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected ClientIdIterator() {
|
||||
this.messages = RequestContextHolder.getRequestContext().getMessageContext().getMessages();
|
||||
}
|
||||
@@ -309,7 +251,7 @@ public class FlowFacesContext extends FacesContext {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Object next() {
|
||||
public String next() {
|
||||
Message next = messages[++currentIndex];
|
||||
while (next.getSource() == null || "".equals(next.getSource())) {
|
||||
next = messages[++currentIndex];
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2007 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 javax.faces.FacesException;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.FacesContextFactory;
|
||||
import javax.faces.lifecycle.Lifecycle;
|
||||
|
||||
import org.springframework.context.MessageSource;
|
||||
|
||||
/**
|
||||
* {@link FacesContextFactory} implementation that installs the {@link FlowFacesContext}, allowing for integration with
|
||||
* a Spring {@link MessageSource}.
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
*/
|
||||
public class FlowFacesContextFactory extends FacesContextFactory {
|
||||
|
||||
FacesContextFactory delegate;
|
||||
|
||||
public FlowFacesContextFactory(FacesContextFactory delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
public FacesContext getFacesContext(Object context, Object request, Object response, Lifecycle lifecycle)
|
||||
throws FacesException {
|
||||
return new FlowFacesContext(delegate.getFacesContext(context, request, response, lifecycle));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -21,6 +21,9 @@ import javax.faces.event.PhaseId;
|
||||
import javax.faces.event.PhaseListener;
|
||||
import javax.faces.lifecycle.Lifecycle;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Custom {@link Lifecycle} for Spring Web Flow that only executes the APPLY_REQUEST_VALUES through INVOKE_APPLICATION
|
||||
* phases.
|
||||
@@ -30,7 +33,9 @@ import javax.faces.lifecycle.Lifecycle;
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
*/
|
||||
public class FlowLifecycle extends Lifecycle {
|
||||
class FlowLifecycle extends Lifecycle {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(FlowLifecycle.class);
|
||||
|
||||
private final Lifecycle delegate;
|
||||
|
||||
@@ -42,7 +47,7 @@ public class FlowLifecycle extends Lifecycle {
|
||||
* Executes APPLY_REQUEST_VALUES through INVOKE_APPLICATION.
|
||||
*/
|
||||
public void execute(FacesContext context) throws FacesException {
|
||||
|
||||
logger.debug("Executing view post back lifecycle");
|
||||
for (int p = PhaseId.APPLY_REQUEST_VALUES.getOrdinal(); p <= PhaseId.INVOKE_APPLICATION.getOrdinal(); p++) {
|
||||
PhaseId phaseId = (PhaseId) PhaseId.VALUES.get(p);
|
||||
if (!skipPhase(context, phaseId)) {
|
||||
@@ -90,16 +95,20 @@ public class FlowLifecycle extends Lifecycle {
|
||||
}
|
||||
|
||||
private void invokePhase(FacesContext context, PhaseId phaseId) {
|
||||
JsfFlowUtils.notifyBeforeListeners(phaseId, this);
|
||||
JsfUtils.notifyBeforeListeners(phaseId, this, context);
|
||||
if (phaseId == PhaseId.APPLY_REQUEST_VALUES) {
|
||||
logger.debug("Processing decodes");
|
||||
context.getViewRoot().processDecodes(context);
|
||||
} else if (phaseId == PhaseId.PROCESS_VALIDATIONS) {
|
||||
logger.debug("Processing validators");
|
||||
context.getViewRoot().processValidators(context);
|
||||
} else if (phaseId == PhaseId.UPDATE_MODEL_VALUES) {
|
||||
logger.debug("Processing model updates");
|
||||
context.getViewRoot().processUpdates(context);
|
||||
} else {
|
||||
logger.debug("Processing application");
|
||||
context.getViewRoot().processApplication(context);
|
||||
}
|
||||
JsfFlowUtils.notifyAfterListeners(phaseId, this);
|
||||
JsfUtils.notifyAfterListeners(phaseId, this, context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2007 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.Iterator;
|
||||
|
||||
import javax.faces.lifecycle.Lifecycle;
|
||||
import javax.faces.lifecycle.LifecycleFactory;
|
||||
|
||||
/**
|
||||
* This {@link LifecycleFactory} implementation is responsible for installing a custom JSF Lifecycle the executes within
|
||||
* the context of Spring Web Flow.
|
||||
* <p>
|
||||
* The {@link FlowLifecycle} will be configured to delegate to the default {@link Lifecycle} where custom behavior is
|
||||
* not needed.
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
*/
|
||||
public class FlowLifecycleFactory extends LifecycleFactory {
|
||||
|
||||
public static final String FLOW_LIFECYCLE_ID = "org.springframework.FlowLifecycle";
|
||||
|
||||
private final LifecycleFactory delegate;
|
||||
|
||||
public FlowLifecycleFactory(LifecycleFactory delegate) {
|
||||
this.delegate = delegate;
|
||||
addLifecycle(FLOW_LIFECYCLE_ID, new FlowLifecycle(delegate.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE)));
|
||||
}
|
||||
|
||||
public void addLifecycle(String lifecycleId, Lifecycle lifecycle) {
|
||||
delegate.addLifecycle(lifecycleId, lifecycle);
|
||||
}
|
||||
|
||||
public Lifecycle getLifecycle(String lifecycleId) {
|
||||
return delegate.getLifecycle(lifecycleId);
|
||||
}
|
||||
|
||||
public Iterator<String> getLifecycleIds() {
|
||||
return delegate.getLifecycleIds();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2007 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.Iterator;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.render.RenderKit;
|
||||
import javax.faces.render.RenderKitFactory;
|
||||
|
||||
/**
|
||||
* {@link RenderKitFactory} implementation that wraps the current {@link RenderKit} implementation inside the
|
||||
* {@link FlowRenderKitWrapper}.
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
*/
|
||||
public class FlowRenderKitFactory extends RenderKitFactory {
|
||||
|
||||
private RenderKitFactory delegate;
|
||||
|
||||
public FlowRenderKitFactory(RenderKitFactory renderKitFactory) {
|
||||
this.delegate = renderKitFactory;
|
||||
}
|
||||
|
||||
public void addRenderKit(String renderKitId, RenderKit renderKit) {
|
||||
FlowRenderKitWrapper wrapper = new FlowRenderKitWrapper(renderKit);
|
||||
delegate.addRenderKit(renderKitId, wrapper);
|
||||
}
|
||||
|
||||
public RenderKit getRenderKit(FacesContext context, String renderKitId) {
|
||||
RenderKit renderKit = delegate.getRenderKit(context, renderKitId);
|
||||
if (!(renderKit instanceof FlowRenderKitWrapper)) {
|
||||
return new FlowRenderKitWrapper(renderKit);
|
||||
}
|
||||
return renderKit;
|
||||
}
|
||||
|
||||
public Iterator getRenderKitIds() {
|
||||
return delegate.getRenderKitIds();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2007 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.OutputStream;
|
||||
import java.io.Writer;
|
||||
|
||||
import javax.faces.context.ResponseStream;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
import javax.faces.render.RenderKit;
|
||||
import javax.faces.render.Renderer;
|
||||
import javax.faces.render.ResponseStateManager;
|
||||
|
||||
/**
|
||||
* Delegating {@link RenderKit} implementation that provides a custom {@link ResponseStateManager} for storing JSF view
|
||||
* state as part of the current FlowExecution.
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
*/
|
||||
public class FlowRenderKitWrapper extends RenderKit {
|
||||
|
||||
RenderKit delegate;
|
||||
|
||||
ResponseStateManager manager = new FlowResponseStateManager();
|
||||
|
||||
public FlowRenderKitWrapper(RenderKit renderKit) {
|
||||
this.delegate = renderKit;
|
||||
}
|
||||
|
||||
public void addRenderer(String family, String rendererType, Renderer renderer) {
|
||||
delegate.addRenderer(family, rendererType, renderer);
|
||||
}
|
||||
|
||||
public ResponseStream createResponseStream(OutputStream out) {
|
||||
return delegate.createResponseStream(out);
|
||||
}
|
||||
|
||||
public ResponseWriter createResponseWriter(Writer writer, String contentTypeList, String characterEncoding) {
|
||||
return delegate.createResponseWriter(writer, contentTypeList, characterEncoding);
|
||||
}
|
||||
|
||||
public Renderer getRenderer(String family, String rendererType) {
|
||||
return delegate.getRenderer(family, rendererType);
|
||||
}
|
||||
|
||||
public ResponseStateManager getResponseStateManager() {
|
||||
if (!JsfFlowUtils.isFlowRequest()) {
|
||||
return delegate.getResponseStateManager();
|
||||
}
|
||||
return manager;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2007 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.io.Writer;
|
||||
|
||||
import javax.el.ValueExpression;
|
||||
import javax.faces.application.StateManager.SerializedView;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.render.ResponseStateManager;
|
||||
|
||||
import org.springframework.webflow.execution.FlowExecution;
|
||||
import org.springframework.webflow.execution.FlowExecutionKey;
|
||||
import org.springframework.webflow.execution.RequestContextHolder;
|
||||
|
||||
/**
|
||||
* {@link ResponseStateManager} implementation that writes out the current {@link FlowExecutionKey} in place of the JSF
|
||||
* view state, and manages the JSF view state as part of the FlowExecution instance state.
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
*/
|
||||
public class FlowResponseStateManager extends ResponseStateManager {
|
||||
|
||||
private static final int VIEW_ID_INDEX = 0;
|
||||
|
||||
private static final int TREE_STATE_INDEX = 1;
|
||||
|
||||
private static final int COMPONENT_STATE_INDEX = 2;
|
||||
|
||||
// TODO - This needs to be replaced with a common static, probably from FlowExecutorArgumentExtractor
|
||||
private static final String VIEW_STATE_PARAM = "org.springframework.webflow.FlowExecutionKey";
|
||||
|
||||
private static final char[] STATE_FIELD_START = ("<input type=\"hidden\" name=\"" + VIEW_STATE_PARAM + "\" id=\""
|
||||
+ VIEW_STATE_PARAM + "\" value=\"").toCharArray();
|
||||
|
||||
private static final char[] STATE_FIELD_END = "\" />".toCharArray();
|
||||
|
||||
public Object getState(FacesContext context, String viewId) {
|
||||
Object[] structureAndState = new Object[2];
|
||||
structureAndState[0] = getTreeStructureToRestore(context, viewId);
|
||||
if (structureAndState[0] == null) {
|
||||
return null;
|
||||
}
|
||||
structureAndState[1] = getComponentStateToRestore(context);
|
||||
return structureAndState;
|
||||
}
|
||||
|
||||
public Object getComponentStateToRestore(FacesContext context) {
|
||||
Object[] state = (Object[]) RequestContextHolder.getRequestContext().getFlowScope().get(JsfView.STATE_KEY);
|
||||
if (state == null) {
|
||||
return null;
|
||||
} else {
|
||||
return state[COMPONENT_STATE_INDEX];
|
||||
}
|
||||
}
|
||||
|
||||
public Object getTreeStructureToRestore(FacesContext context, String viewId) {
|
||||
Object[] state = (Object[]) RequestContextHolder.getRequestContext().getFlowScope().get(JsfView.STATE_KEY);
|
||||
if (state == null || !state[VIEW_ID_INDEX].equals(viewId)) {
|
||||
return null;
|
||||
} else {
|
||||
return state[TREE_STATE_INDEX];
|
||||
}
|
||||
}
|
||||
|
||||
private FlowExecution getFlowExecution() {
|
||||
FacesContext ctx = FacesContext.getCurrentInstance();
|
||||
ValueExpression expr = ctx.getApplication().getExpressionFactory().createValueExpression(ctx.getELContext(),
|
||||
"#{flowExecution}", FlowExecution.class);
|
||||
return (FlowExecution) expr.getValue(ctx.getELContext());
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the serializable component state in Flash scope and writes out the FlowExecutionKey
|
||||
*/
|
||||
public void writeState(FacesContext context, SerializedView state) throws IOException {
|
||||
|
||||
Object[] serializableState = new Object[] { context.getViewRoot().getViewId(), state.getStructure(),
|
||||
state.getState() };
|
||||
|
||||
RequestContextHolder.getRequestContext().getFlowScope().put(JsfView.STATE_KEY, serializableState);
|
||||
|
||||
Writer writer = context.getResponseWriter();
|
||||
writer.write(STATE_FIELD_START);
|
||||
writer.write(RequestContextHolder.getRequestContext().getFlowExecutionContext().getKey().toString());
|
||||
writer.write(STATE_FIELD_END);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -31,18 +31,15 @@ import org.springframework.webflow.execution.RequestContextHolder;
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
*/
|
||||
public class FlowExecutionViewHandler extends ViewHandler {
|
||||
public class FlowViewHandler extends ViewHandler {
|
||||
|
||||
ViewHandler delegate;
|
||||
private ViewHandler delegate;
|
||||
|
||||
public FlowExecutionViewHandler(ViewHandler delegate) {
|
||||
public FlowViewHandler(ViewHandler delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
public String getActionURL(FacesContext context, String viewId) {
|
||||
if (!JsfFlowUtils.isFlowRequest()) {
|
||||
return delegate.getActionURL(context, viewId);
|
||||
}
|
||||
return RequestContextHolder.getRequestContext().getFlowExecutionUrl();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
package org.springframework.faces.webflow;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.application.StateManager;
|
||||
import javax.faces.component.UIViewRoot;
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.RequestContextHolder;
|
||||
|
||||
public class FlowViewStateManager extends StateManager {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(FlowViewStateManager.class);
|
||||
|
||||
private static final String VIEW_MAP = "org.springframework.webflow.viewMap";
|
||||
|
||||
public boolean isSavingStateInClient(FacesContext context) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// required to implement for 1.1 view handlers - unfortunately, facelets is one of these...
|
||||
public javax.faces.application.StateManager.SerializedView saveSerializedView(FacesContext context) {
|
||||
SerializedView view = (SerializedView) saveView(context);
|
||||
return new javax.faces.application.StateManager.SerializedView(view.treeStructure, view.componentState);
|
||||
}
|
||||
|
||||
public Object saveView(FacesContext context) {
|
||||
RequestContext requestContext = RequestContextHolder.getRequestContext();
|
||||
SerializedViewMap viewMap = (SerializedViewMap) requestContext.getFlowScope().get(VIEW_MAP);
|
||||
if (viewMap == null) {
|
||||
viewMap = new SerializedViewMap();
|
||||
requestContext.getFlowScope().put(VIEW_MAP, viewMap);
|
||||
}
|
||||
logger.debug("Saving view root in flow scope");
|
||||
return viewMap.putSerializedView(context);
|
||||
}
|
||||
|
||||
public UIViewRoot restoreView(FacesContext context, String viewId, String renderKitId) {
|
||||
RequestContext requestContext = RequestContextHolder.getRequestContext();
|
||||
SerializedViewMap viewMap = (SerializedViewMap) requestContext.getFlowScope().get(VIEW_MAP);
|
||||
if (viewMap == null) {
|
||||
logger.debug("No view map in flow scope; no views have been saved yet...");
|
||||
return null;
|
||||
}
|
||||
logger.debug("Restoring view root from flow scope");
|
||||
return viewMap.getDeserializedView(viewId, context);
|
||||
}
|
||||
|
||||
public void writeState(FacesContext context, Object state) throws IOException {
|
||||
// nothing to do, as saving state to client always returns false
|
||||
}
|
||||
|
||||
private static class SerializedViewMap implements Serializable {
|
||||
private static final Log logger = LogFactory.getLog(SerializedViewMap.class);
|
||||
|
||||
private Map<String, SerializedView> views;
|
||||
|
||||
public SerializedViewMap() {
|
||||
views = new HashMap<String, SerializedView>();
|
||||
}
|
||||
|
||||
public void put(String viewId, SerializedView view) {
|
||||
views.put(viewId, view);
|
||||
}
|
||||
|
||||
public SerializedView get(String viewId) {
|
||||
return views.get(viewId);
|
||||
}
|
||||
|
||||
public Object putSerializedView(FacesContext context) {
|
||||
SerializedView view = SerializedView.create(context);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Indexing serialized view under key '" + context.getViewRoot().getViewId() + "'");
|
||||
}
|
||||
put(context.getViewRoot().getViewId(), view);
|
||||
return view;
|
||||
}
|
||||
|
||||
public UIViewRoot getDeserializedView(String viewId, FacesContext context) {
|
||||
SerializedView view = get(viewId);
|
||||
if (view == null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("No serialized view found under key '" + viewId + "; returning null");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return view.deserialize(context);
|
||||
}
|
||||
}
|
||||
|
||||
private static class SerializedView implements Serializable {
|
||||
private static final Log logger = LogFactory.getLog(SerializedView.class);
|
||||
|
||||
private Serializable treeStructure;
|
||||
|
||||
private Object componentState;
|
||||
|
||||
private SerializedView(Serializable treeStructure, Object componentState) {
|
||||
this.treeStructure = treeStructure;
|
||||
this.componentState = componentState;
|
||||
}
|
||||
|
||||
public UIViewRoot deserialize(FacesContext context) {
|
||||
if (treeStructure == null) {
|
||||
logger.debug("Tree structure is null indicating transient UIViewRoot; returning null");
|
||||
return null;
|
||||
}
|
||||
UIViewRoot viewRoot = new TreeStructureManager().restoreTreeStructure(treeStructure);
|
||||
logger.debug("UIViewRoot structure restored");
|
||||
viewRoot.processRestoreState(context, componentState);
|
||||
logger.debug("UIViewRoot component state restored");
|
||||
logger.debug("Returning restored UIViewRoot");
|
||||
return viewRoot;
|
||||
}
|
||||
|
||||
public static SerializedView create(FacesContext context) {
|
||||
return new SerializedView(getTreeStructure(context), getComponentState(context));
|
||||
}
|
||||
|
||||
private static Serializable getTreeStructure(FacesContext context) {
|
||||
UIViewRoot viewRoot = context.getViewRoot();
|
||||
if (viewRoot.isTransient()) {
|
||||
return null;
|
||||
} else {
|
||||
return new TreeStructureManager().buildTreeStructureToSave(viewRoot);
|
||||
}
|
||||
}
|
||||
|
||||
private static Object getComponentState(FacesContext context) {
|
||||
UIViewRoot viewRoot = context.getViewRoot();
|
||||
if (viewRoot.isTransient()) {
|
||||
return null;
|
||||
} else {
|
||||
return viewRoot.processSaveState(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,13 +17,11 @@ package org.springframework.faces.webflow;
|
||||
|
||||
import javax.faces.component.UIViewRoot;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.webflow.engine.EndState;
|
||||
import org.springframework.webflow.execution.Action;
|
||||
import org.springframework.webflow.execution.Event;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.View;
|
||||
import org.springframework.webflow.execution.ViewFactory;
|
||||
|
||||
/**
|
||||
* Specialized {@link Action} implementation for rendering the JSF view in an {@link EndState}.
|
||||
@@ -33,26 +31,19 @@ import org.springframework.webflow.execution.ViewFactory;
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
*/
|
||||
public class JsfRenderFinalResponseAction implements Action {
|
||||
public class JsfFinalResponseAction implements Action {
|
||||
|
||||
ViewFactory viewFactory;
|
||||
private JsfViewFactory viewFactory;
|
||||
|
||||
public JsfRenderFinalResponseAction(ViewFactory viewFactory) {
|
||||
Assert.notNull(viewFactory);
|
||||
public JsfFinalResponseAction(JsfViewFactory viewFactory) {
|
||||
this.viewFactory = viewFactory;
|
||||
}
|
||||
|
||||
public Event execute(RequestContext context) throws Exception {
|
||||
|
||||
View view = viewFactory.getView(context);
|
||||
Assert.isInstanceOf(JsfView.class, view);
|
||||
|
||||
((JsfView) view).getViewRoot().setTransient(true);
|
||||
|
||||
view.render();
|
||||
|
||||
return new Event(this, "success");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2007 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 org.springframework.webflow.core.FlowException;
|
||||
|
||||
/**
|
||||
* Thrown when there is a configuration error with SWF within a JSF environment.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class JsfFlowConfigurationException extends FlowException {
|
||||
|
||||
public JsfFlowConfigurationException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public JsfFlowConfigurationException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
}
|
||||
@@ -15,39 +15,21 @@
|
||||
*/
|
||||
package org.springframework.faces.webflow;
|
||||
|
||||
import javax.faces.FactoryFinder;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.FacesContextFactory;
|
||||
import javax.faces.event.PhaseEvent;
|
||||
import javax.faces.event.PhaseId;
|
||||
import javax.faces.event.PhaseListener;
|
||||
import javax.faces.lifecycle.Lifecycle;
|
||||
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.RequestContextHolder;
|
||||
|
||||
/**
|
||||
* Common support for the JSF integration with Spring Web Flow.
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
*/
|
||||
class JsfFlowUtils {
|
||||
class JsfUtils {
|
||||
|
||||
public static FacesContext getFacesContext(Lifecycle lifecycle) {
|
||||
FacesContext facesContext = FacesContext.getCurrentInstance();
|
||||
if (facesContext == null) {
|
||||
RequestContext requestContext = RequestContextHolder.getRequestContext();
|
||||
FacesContextFactory facesContextFactory = (FacesContextFactory) FactoryFinder
|
||||
.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
|
||||
facesContext = facesContextFactory.getFacesContext(requestContext.getExternalContext().getContext(),
|
||||
requestContext.getExternalContext().getRequest(),
|
||||
requestContext.getExternalContext().getResponse(), lifecycle);
|
||||
}
|
||||
return facesContext;
|
||||
}
|
||||
|
||||
public static void notifyAfterListeners(PhaseId phaseId, Lifecycle lifecycle) {
|
||||
PhaseEvent afterPhaseEvent = new PhaseEvent(getFacesContext(lifecycle), phaseId, lifecycle);
|
||||
public static void notifyAfterListeners(PhaseId phaseId, Lifecycle lifecycle, FacesContext context) {
|
||||
PhaseEvent afterPhaseEvent = new PhaseEvent(context, phaseId, lifecycle);
|
||||
for (int i = 0; i < lifecycle.getPhaseListeners().length; i++) {
|
||||
PhaseListener listener = lifecycle.getPhaseListeners()[i];
|
||||
if (listener.getPhaseId() == phaseId || listener.getPhaseId() == PhaseId.ANY_PHASE) {
|
||||
@@ -56,8 +38,8 @@ class JsfFlowUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static void notifyBeforeListeners(PhaseId phaseId, Lifecycle lifecycle) {
|
||||
PhaseEvent beforePhaseEvent = new PhaseEvent(getFacesContext(lifecycle), phaseId, lifecycle);
|
||||
public static void notifyBeforeListeners(PhaseId phaseId, Lifecycle lifecycle, FacesContext context) {
|
||||
PhaseEvent beforePhaseEvent = new PhaseEvent(context, phaseId, lifecycle);
|
||||
for (int i = 0; i < lifecycle.getPhaseListeners().length; i++) {
|
||||
PhaseListener listener = lifecycle.getPhaseListeners()[i];
|
||||
if (listener.getPhaseId() == phaseId || listener.getPhaseId() == PhaseId.ANY_PHASE) {
|
||||
@@ -65,11 +47,4 @@ class JsfFlowUtils {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isFlowRequest() {
|
||||
if (RequestContextHolder.getRequestContext() == null) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -18,15 +18,17 @@ package org.springframework.faces.webflow;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.faces.FacesException;
|
||||
import javax.faces.FactoryFinder;
|
||||
import javax.faces.component.UIViewRoot;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.FacesContextFactory;
|
||||
import javax.faces.event.PhaseId;
|
||||
import javax.faces.lifecycle.Lifecycle;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.webflow.execution.Event;
|
||||
import org.springframework.webflow.execution.RequestContextHolder;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.View;
|
||||
|
||||
/**
|
||||
@@ -36,42 +38,32 @@ import org.springframework.webflow.execution.View;
|
||||
*/
|
||||
public class JsfView implements View {
|
||||
|
||||
public static final String EVENT_KEY = "org.springframework.webflow.FacesEvent";
|
||||
private static final Log logger = LogFactory.getLog(JsfView.class);
|
||||
|
||||
public static final String STATE_KEY = "org.springframework.webflow.FacesState";
|
||||
public static final String EVENT_KEY = "org.springframework.webflow.FacesEvent";
|
||||
|
||||
/**
|
||||
* The root of the JSF component tree managed by this view
|
||||
*/
|
||||
private UIViewRoot viewRoot;
|
||||
|
||||
private Event event;
|
||||
|
||||
private Lifecycle facesLifecycle;
|
||||
|
||||
public JsfView(UIViewRoot viewRoot, Lifecycle facesLifecycle) {
|
||||
|
||||
Assert.notNull(viewRoot);
|
||||
Assert.notNull(facesLifecycle);
|
||||
private RequestContext context;
|
||||
|
||||
public JsfView(UIViewRoot viewRoot, Lifecycle facesLifecycle, RequestContext context) {
|
||||
this.viewRoot = viewRoot;
|
||||
this.facesLifecycle = facesLifecycle;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public boolean eventSignaled() {
|
||||
return getEvent() != null;
|
||||
return context.getExternalContext().getRequestMap().contains(EVENT_KEY);
|
||||
}
|
||||
|
||||
public Event getEvent() {
|
||||
if (event == null) {
|
||||
|
||||
String jsfEvent = (String) RequestContextHolder.getRequestContext().getExternalContext().getRequestMap()
|
||||
.get(EVENT_KEY);
|
||||
if (StringUtils.hasText(jsfEvent)) {
|
||||
event = new Event(this, jsfEvent);
|
||||
}
|
||||
}
|
||||
return event;
|
||||
String eventId = (String) context.getExternalContext().getRequestMap().get(EVENT_KEY);
|
||||
return new Event(this, eventId);
|
||||
}
|
||||
|
||||
public UIViewRoot getViewRoot() {
|
||||
@@ -82,19 +74,33 @@ public class JsfView implements View {
|
||||
* This implementation performs the standard duties of the JSF RENDER_RESPONSE phase.
|
||||
*/
|
||||
public void render() {
|
||||
FacesContext facesContext = JsfFlowUtils.getFacesContext(facesLifecycle);
|
||||
FacesContext facesContext = createFlowFacesContext();
|
||||
facesContext.setViewRoot(viewRoot);
|
||||
facesContext.renderResponse();
|
||||
try {
|
||||
JsfFlowUtils.notifyBeforeListeners(PhaseId.RENDER_RESPONSE, facesLifecycle);
|
||||
JsfUtils.notifyBeforeListeners(PhaseId.RENDER_RESPONSE, facesLifecycle, facesContext);
|
||||
logger.debug("Asking view handler to render view");
|
||||
facesContext.getApplication().getViewHandler().renderView(facesContext, viewRoot);
|
||||
JsfFlowUtils.notifyAfterListeners(PhaseId.RENDER_RESPONSE, facesLifecycle);
|
||||
JsfUtils.notifyAfterListeners(PhaseId.RENDER_RESPONSE, facesLifecycle, facesContext);
|
||||
} catch (IOException e) {
|
||||
throw new FacesException("An I/O error occurred during view rendering", e);
|
||||
} finally {
|
||||
logger.debug("View rendering complete");
|
||||
facesContext.responseComplete();
|
||||
facesContext.release();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
private FacesContext createFlowFacesContext() {
|
||||
FacesContextFactory facesContextFactory = (FacesContextFactory) FactoryFinder
|
||||
.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
|
||||
FacesContext defaultFacesContext = facesContextFactory.getFacesContext(context.getExternalContext()
|
||||
.getContext(), context.getExternalContext().getRequest(), context.getExternalContext().getResponse(),
|
||||
facesLifecycle);
|
||||
return new FlowFacesContext(context, defaultFacesContext);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "[JSFView = '" + viewRoot.getViewId() + "']";
|
||||
}
|
||||
}
|
||||
@@ -17,15 +17,19 @@ package org.springframework.faces.webflow;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import javax.el.ELContext;
|
||||
import javax.el.ValueExpression;
|
||||
import javax.faces.FactoryFinder;
|
||||
import javax.faces.application.ViewHandler;
|
||||
import javax.faces.component.UIComponent;
|
||||
import javax.faces.component.UIViewRoot;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.FacesContextFactory;
|
||||
import javax.faces.event.PhaseId;
|
||||
import javax.faces.lifecycle.Lifecycle;
|
||||
import javax.faces.lifecycle.LifecycleFactory;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.binding.expression.Expression;
|
||||
import org.springframework.core.io.ContextResource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
@@ -44,67 +48,67 @@ import org.springframework.webflow.execution.ViewFactory;
|
||||
*/
|
||||
public class JsfViewFactory implements ViewFactory {
|
||||
|
||||
private final Lifecycle facesLifecycle;
|
||||
private static final Log logger = LogFactory.getLog(JsfViewFactory.class);
|
||||
|
||||
private final Expression viewExpr;
|
||||
|
||||
private final ResourceLoader resourceLoader;
|
||||
|
||||
public JsfViewFactory(Lifecycle facesLifecycle, Expression viewExpr, ResourceLoader resourceLoader) {
|
||||
|
||||
this.facesLifecycle = facesLifecycle;
|
||||
public JsfViewFactory(Expression viewExpr, ResourceLoader resourceLoader) {
|
||||
this.viewExpr = viewExpr;
|
||||
this.resourceLoader = resourceLoader;
|
||||
}
|
||||
|
||||
public View getView(RequestContext context) {
|
||||
|
||||
String viewName = resolveViewName(context);
|
||||
FacesContext facesContext = JsfFlowUtils.getFacesContext(facesLifecycle);
|
||||
Lifecycle lifecycle = createFlowFacesLifecycle();
|
||||
FacesContext facesContext = createFlowFacesContext(context, lifecycle);
|
||||
try {
|
||||
boolean restored = false;
|
||||
|
||||
if (!facesContext.getRenderResponse()) {
|
||||
JsfFlowUtils.notifyBeforeListeners(PhaseId.RESTORE_VIEW, facesLifecycle);
|
||||
JsfUtils.notifyBeforeListeners(PhaseId.RESTORE_VIEW, lifecycle, facesContext);
|
||||
}
|
||||
|
||||
JsfView view;
|
||||
|
||||
ViewHandler handler = facesContext.getApplication().getViewHandler();
|
||||
|
||||
if (viewExists(facesContext, viewName)) {
|
||||
view = new JsfView(facesContext.getViewRoot(), facesLifecycle);
|
||||
restored = true;
|
||||
} else {
|
||||
UIViewRoot root = handler.restoreView(facesContext, viewName);
|
||||
if (root != null) {
|
||||
view = new JsfView(root, facesLifecycle);
|
||||
restored = true;
|
||||
} else {
|
||||
view = new JsfView(handler.createView(facesContext, viewName), facesLifecycle);
|
||||
restored = false;
|
||||
String viewName = resolveViewName(context);
|
||||
ViewHandler viewHandler = facesContext.getApplication().getViewHandler();
|
||||
viewHandler.initView(facesContext);
|
||||
UIViewRoot viewRoot = viewHandler.restoreView(facesContext, viewName);
|
||||
if (viewRoot != null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("View root restored for '" + viewName + "'");
|
||||
}
|
||||
facesContext.setViewRoot(viewRoot);
|
||||
processComponentBinding(facesContext, viewRoot);
|
||||
JsfUtils.notifyAfterListeners(PhaseId.RESTORE_VIEW, lifecycle, facesContext);
|
||||
lifecycle.execute(facesContext);
|
||||
return new JsfView(viewRoot, lifecycle, context);
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Creating view root for '" + viewName + "'");
|
||||
}
|
||||
viewRoot = viewHandler.createView(facesContext, viewName);
|
||||
facesContext.setViewRoot(viewRoot);
|
||||
JsfUtils.notifyAfterListeners(PhaseId.RESTORE_VIEW, lifecycle, facesContext);
|
||||
return new JsfView(viewRoot, lifecycle, context);
|
||||
}
|
||||
|
||||
facesContext.setViewRoot(view.getViewRoot());
|
||||
|
||||
processBindings(facesContext.getELContext(), view.getViewRoot());
|
||||
|
||||
if (!facesContext.getRenderResponse()) {
|
||||
JsfFlowUtils.notifyAfterListeners(PhaseId.RESTORE_VIEW, facesLifecycle);
|
||||
}
|
||||
|
||||
if (restored && !facesContext.getResponseComplete() && !facesContext.getRenderResponse()) {
|
||||
facesLifecycle.execute(facesContext);
|
||||
facesContext.renderResponse();
|
||||
}
|
||||
|
||||
return view;
|
||||
} finally {
|
||||
facesContext.release();
|
||||
}
|
||||
}
|
||||
|
||||
private Lifecycle createFlowFacesLifecycle() {
|
||||
LifecycleFactory lifecycleFactory = (LifecycleFactory) FactoryFinder
|
||||
.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
|
||||
Lifecycle defaultLifecycle = lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
|
||||
return new FlowLifecycle(defaultLifecycle);
|
||||
}
|
||||
|
||||
private FacesContext createFlowFacesContext(RequestContext context, Lifecycle lifecycle) {
|
||||
FacesContextFactory facesContextFactory = (FacesContextFactory) FactoryFinder
|
||||
.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
|
||||
FacesContext defaultFacesContext = facesContextFactory.getFacesContext(context.getExternalContext()
|
||||
.getContext(), context.getExternalContext().getRequest(), context.getExternalContext().getResponse(),
|
||||
lifecycle);
|
||||
return new FlowFacesContext(context, defaultFacesContext);
|
||||
}
|
||||
|
||||
private String resolveViewName(RequestContext context) {
|
||||
String viewId = (String) viewExpr.getValue(context);
|
||||
if (viewId.startsWith("/")) {
|
||||
@@ -115,24 +119,13 @@ public class JsfViewFactory implements ViewFactory {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean viewExists(FacesContext facesContext, String viewId) {
|
||||
if (facesContext.getViewRoot() != null && facesContext.getViewRoot().getViewId().equals(viewId)) {
|
||||
return true;
|
||||
private void processComponentBinding(FacesContext context, UIComponent component) {
|
||||
ValueExpression binding = component.getValueExpression("binding");
|
||||
if (binding != null) {
|
||||
binding.setValue(context.getELContext(), component);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void processBindings(ELContext elContext, UIComponent component) {
|
||||
|
||||
ValueExpression expr = component.getValueExpression("binding");
|
||||
if (expr != null) {
|
||||
expr.setValue(elContext, component);
|
||||
}
|
||||
|
||||
Iterator i = component.getChildren().iterator();
|
||||
while (i.hasNext()) {
|
||||
UIComponent child = (UIComponent) i.next();
|
||||
processBindings(elContext, child);
|
||||
for (Iterator<UIComponent> iter = component.getFacetsAndChildren(); iter.hasNext();) {
|
||||
processComponentBinding(context, iter.next());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,9 +15,6 @@
|
||||
*/
|
||||
package org.springframework.faces.webflow;
|
||||
|
||||
import javax.faces.FactoryFinder;
|
||||
import javax.faces.lifecycle.LifecycleFactory;
|
||||
|
||||
import org.springframework.binding.expression.Expression;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.webflow.engine.builder.ViewFactoryCreator;
|
||||
@@ -32,14 +29,11 @@ import org.springframework.webflow.execution.ViewFactory;
|
||||
public class JsfViewFactoryCreator implements ViewFactoryCreator {
|
||||
|
||||
public Action createFinalResponseAction(Expression viewName, ResourceLoader resourceLoader) {
|
||||
return new JsfRenderFinalResponseAction(new JsfViewFactory(((LifecycleFactory) FactoryFinder
|
||||
.getFactory(FactoryFinder.LIFECYCLE_FACTORY)).getLifecycle(FlowLifecycleFactory.FLOW_LIFECYCLE_ID),
|
||||
viewName, resourceLoader));
|
||||
return new JsfFinalResponseAction(new JsfViewFactory(viewName, resourceLoader));
|
||||
}
|
||||
|
||||
public ViewFactory createViewFactory(Expression viewName, ResourceLoader resourceLoader) {
|
||||
return new JsfViewFactory(((LifecycleFactory) FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY))
|
||||
.getLifecycle(FlowLifecycleFactory.FLOW_LIFECYCLE_ID), viewName, resourceLoader);
|
||||
return new JsfViewFactory(viewName, resourceLoader);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright 2004 The Apache Software Foundation.
|
||||
*
|
||||
* 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.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.component.UIComponent;
|
||||
import javax.faces.component.UIViewRoot;
|
||||
|
||||
import org.apache.myfaces.shared_impl.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* @author Manfred Geiler (latest modification by $Author: dennisbyrne $)
|
||||
* @version $Revision: 511715 $ $Date: 2007-02-26 05:05:36 +0100 (Mo, 26 Feb 2007) $
|
||||
*/
|
||||
class TreeStructureManager {
|
||||
public Serializable buildTreeStructureToSave(UIViewRoot viewRoot) {
|
||||
return internalBuildTreeStructureToSave(viewRoot);
|
||||
}
|
||||
|
||||
private TreeStructComponent internalBuildTreeStructureToSave(UIComponent component) {
|
||||
TreeStructComponent structComp = new TreeStructComponent(component.getClass().getName(), component.getId());
|
||||
|
||||
// children
|
||||
if (component.getChildCount() > 0) {
|
||||
List childList = component.getChildren();
|
||||
List<TreeStructComponent> structChildList = new ArrayList<TreeStructComponent>();
|
||||
for (int i = 0, len = childList.size(); i < len; i++) {
|
||||
UIComponent child = (UIComponent) childList.get(i);
|
||||
if (!child.isTransient()) {
|
||||
TreeStructComponent structChild = internalBuildTreeStructureToSave(child);
|
||||
structChildList.add(structChild);
|
||||
}
|
||||
}
|
||||
TreeStructComponent[] childArray = structChildList.toArray(new TreeStructComponent[structChildList.size()]);
|
||||
structComp.setChildren(childArray);
|
||||
}
|
||||
|
||||
// facets
|
||||
Map<String, UIComponent> facetMap = component.getFacets();
|
||||
if (!facetMap.isEmpty()) {
|
||||
List<Object[]> structFacetList = new ArrayList<Object[]>();
|
||||
for (Iterator it = facetMap.entrySet().iterator(); it.hasNext();) {
|
||||
Map.Entry entry = (Map.Entry) it.next();
|
||||
UIComponent child = (UIComponent) entry.getValue();
|
||||
if (!child.isTransient()) {
|
||||
String facetName = (String) entry.getKey();
|
||||
TreeStructComponent structChild = internalBuildTreeStructureToSave(child);
|
||||
structFacetList.add(new Object[] { facetName, structChild });
|
||||
}
|
||||
}
|
||||
Object[] facetArray = structFacetList.toArray(new Object[structFacetList.size()]);
|
||||
structComp.setFacets(facetArray);
|
||||
}
|
||||
|
||||
return structComp;
|
||||
}
|
||||
|
||||
public UIViewRoot restoreTreeStructure(Object treeStructRoot) {
|
||||
if (treeStructRoot instanceof TreeStructComponent) {
|
||||
return (UIViewRoot) internalRestoreTreeStructure((TreeStructComponent) treeStructRoot);
|
||||
}
|
||||
throw new IllegalArgumentException("TreeStructure of type " + treeStructRoot.getClass().getName()
|
||||
+ " is not supported.");
|
||||
}
|
||||
|
||||
private UIComponent internalRestoreTreeStructure(TreeStructComponent treeStructComp) {
|
||||
String compClass = treeStructComp.getComponentClass();
|
||||
String compId = treeStructComp.getComponentId();
|
||||
UIComponent component = (UIComponent) ClassUtils.newInstance(compClass);
|
||||
component.setId(compId);
|
||||
|
||||
// children
|
||||
TreeStructComponent[] childArray = treeStructComp.getChildren();
|
||||
if (childArray != null) {
|
||||
List<UIComponent> childList = component.getChildren();
|
||||
for (int i = 0, len = childArray.length; i < len; i++) {
|
||||
UIComponent child = internalRestoreTreeStructure(childArray[i]);
|
||||
childList.add(child);
|
||||
}
|
||||
}
|
||||
|
||||
// facets
|
||||
Object[] facetArray = treeStructComp.getFacets();
|
||||
if (facetArray != null) {
|
||||
Map<String, UIComponent> facetMap = component.getFacets();
|
||||
for (int i = 0, len = facetArray.length; i < len; i++) {
|
||||
Object[] tuple = (Object[]) facetArray[i];
|
||||
String facetName = (String) tuple[0];
|
||||
TreeStructComponent structChild = (TreeStructComponent) tuple[1];
|
||||
UIComponent child = internalRestoreTreeStructure(structChild);
|
||||
facetMap.put(facetName, child);
|
||||
}
|
||||
}
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
public static class TreeStructComponent implements Serializable {
|
||||
private static final long serialVersionUID = 5069109074684737231L;
|
||||
private String _componentClass;
|
||||
private String _componentId;
|
||||
private TreeStructComponent[] _children = null; // Array of children
|
||||
private Object[] _facets = null; // Array of Array-tuples with Facetname and TreeStructComponent
|
||||
|
||||
TreeStructComponent(String componentClass, String componentId) {
|
||||
_componentClass = componentClass;
|
||||
_componentId = componentId;
|
||||
}
|
||||
|
||||
public String getComponentClass() {
|
||||
return _componentClass;
|
||||
}
|
||||
|
||||
public String getComponentId() {
|
||||
return _componentId;
|
||||
}
|
||||
|
||||
void setChildren(TreeStructComponent[] children) {
|
||||
_children = children;
|
||||
}
|
||||
|
||||
TreeStructComponent[] getChildren() {
|
||||
return _children;
|
||||
}
|
||||
|
||||
Object[] getFacets() {
|
||||
return _facets;
|
||||
}
|
||||
|
||||
void setFacets(Object[] facets) {
|
||||
_facets = facets;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,7 +16,6 @@ import org.springframework.binding.message.MessageContext;
|
||||
import org.springframework.binding.message.MessageResolver;
|
||||
import org.springframework.binding.message.Severity;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.RequestContextHolder;
|
||||
|
||||
public class FlowFacesContextTests extends TestCase {
|
||||
|
||||
@@ -30,8 +29,7 @@ public class FlowFacesContextTests extends TestCase {
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
jsf.setUp();
|
||||
facesContext = new FlowFacesContext(jsf.facesContext());
|
||||
RequestContextHolder.setRequestContext(requestContext);
|
||||
facesContext = new FlowFacesContext(requestContext, jsf.facesContext());
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
|
||||
@@ -48,6 +48,7 @@ import org.springframework.webflow.execution.FlowExecutionKey;
|
||||
import org.springframework.webflow.execution.FlowExecutionKeyFactory;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.ScopeType;
|
||||
import org.springframework.webflow.test.MockRequestContext;
|
||||
|
||||
public class JSFFlowExecutionTests extends TestCase {
|
||||
|
||||
@@ -77,8 +78,8 @@ public class JSFFlowExecutionTests extends TestCase {
|
||||
|
||||
flow = Flow.create("jsf-flow", null);
|
||||
|
||||
ViewState view1 = new ViewState(flow, "viewState1", new JsfViewFactory(new TestLifecycle(jsf.lifecycle()),
|
||||
parser.parseExpression("/view1", RequestContext.class, String.class, null), null));
|
||||
ViewState view1 = new ViewState(flow, "viewState1", new JsfViewFactory(parser.parseExpression("/view1",
|
||||
RequestContext.class, String.class, null), null));
|
||||
view1.getTransitionSet().add(new Transition(on("event1"), to("doSomething")));
|
||||
view1.getTransitionSet().add(new Transition(on("event2"), to("evalSomething")));
|
||||
|
||||
@@ -98,8 +99,8 @@ public class JSFFlowExecutionTests extends TestCase {
|
||||
String.class, null)));
|
||||
evalSomething.getTransitionSet().add(new Transition(on("success"), to("viewState2")));
|
||||
|
||||
ViewState viewState2 = new ViewState(flow, "viewState2", new JsfViewFactory(new TestLifecycle(jsf.lifecycle()),
|
||||
parser.parseExpression("/view2", RequestContext.class, String.class, null), null));
|
||||
ViewState viewState2 = new ViewState(flow, "viewState2", new JsfViewFactory(parser.parseExpression("/view2",
|
||||
RequestContext.class, String.class, null), null));
|
||||
viewState2.getEntryActionList().add(new ViewState2SetupAction());
|
||||
viewState2.getTransitionSet().add(new Transition(on("event1"), to("endState1")));
|
||||
|
||||
@@ -114,7 +115,7 @@ public class JSFFlowExecutionTests extends TestCase {
|
||||
jsf = new JSFMockHelper();
|
||||
jsf.tearDown();
|
||||
jsf.setUp();
|
||||
FacesContext flowContext = new FlowFacesContext(jsf.facesContext());
|
||||
FacesContext flowContext = new FlowFacesContext(new MockRequestContext(), jsf.facesContext());
|
||||
org.apache.shale.test.mock.MockFacesContext.setCurrentInstance(flowContext);
|
||||
|
||||
viewHandler = new NoRenderViewHandler();
|
||||
|
||||
@@ -3,6 +3,8 @@ package org.springframework.faces.webflow;
|
||||
import javax.faces.FactoryFinder;
|
||||
import javax.faces.application.Application;
|
||||
import javax.faces.component.UIViewRoot;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.FacesContextFactory;
|
||||
import javax.faces.lifecycle.LifecycleFactory;
|
||||
import javax.faces.render.RenderKitFactory;
|
||||
|
||||
@@ -29,9 +31,6 @@ public class JSFMockHelper {
|
||||
private JSFMock mock = new JSFMock();
|
||||
|
||||
public Application application() {
|
||||
if (mock.application() == null) {
|
||||
return mock.facesContext.getApplication();
|
||||
}
|
||||
return mock.application();
|
||||
}
|
||||
|
||||
@@ -43,11 +42,11 @@ public class JSFMockHelper {
|
||||
return mock.externalContext();
|
||||
}
|
||||
|
||||
public FlowFacesContext facesContext() {
|
||||
public FacesContext facesContext() {
|
||||
return mock.facesContext();
|
||||
}
|
||||
|
||||
public FlowFacesContextFactory facesContextFactory() {
|
||||
public FacesContextFactory facesContextFactory() {
|
||||
return mock.facesContextFactory();
|
||||
}
|
||||
|
||||
@@ -93,8 +92,8 @@ public class JSFMockHelper {
|
||||
super("JSFMock");
|
||||
}
|
||||
|
||||
FlowFacesContextFactory facesContextFactory;
|
||||
FlowFacesContext facesContext;
|
||||
FacesContextFactory facesContextFactory;
|
||||
FacesContext facesContext;
|
||||
|
||||
public void setUp() throws Exception {
|
||||
|
||||
@@ -116,19 +115,18 @@ public class JSFMockHelper {
|
||||
FactoryFinder.setFactory(FactoryFinder.FACES_CONTEXT_FACTORY,
|
||||
"org.springframework.faces.webflow.MockBaseFacesContextFactory");
|
||||
FactoryFinder.setFactory(FactoryFinder.FACES_CONTEXT_FACTORY,
|
||||
"org.springframework.faces.webflow.FlowFacesContextFactory");
|
||||
"org.apache.shale.test.mock.MockFacesContextFactory");
|
||||
FactoryFinder
|
||||
.setFactory(FactoryFinder.LIFECYCLE_FACTORY, "org.apache.shale.test.mock.MockLifecycleFactory");
|
||||
FactoryFinder.setFactory(FactoryFinder.RENDER_KIT_FACTORY,
|
||||
"org.apache.shale.test.mock.MockRenderKitFactory");
|
||||
|
||||
application = new MockApplication();
|
||||
externalContext = new MockExternalContext(servletContext, request, response);
|
||||
lifecycleFactory = (MockLifecycleFactory) FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
|
||||
lifecycle = (MockLifecycle) lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
|
||||
facesContextFactory = (FlowFacesContextFactory) FactoryFinder
|
||||
.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
|
||||
facesContext = (FlowFacesContext) facesContextFactory.getFacesContext(servletContext, request, response,
|
||||
lifecycle);
|
||||
facesContextFactory = (FacesContextFactory) FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
|
||||
facesContext = facesContextFactory.getFacesContext(servletContext, request, response, lifecycle);
|
||||
externalContext = (MockExternalContext) facesContext.getExternalContext();
|
||||
UIViewRoot root = new UIViewRoot();
|
||||
root.setViewId("/viewId");
|
||||
@@ -171,11 +169,11 @@ public class JSFMockHelper {
|
||||
return externalContext;
|
||||
}
|
||||
|
||||
public FlowFacesContext facesContext() {
|
||||
public FacesContext facesContext() {
|
||||
return facesContext;
|
||||
}
|
||||
|
||||
public FlowFacesContextFactory facesContextFactory() {
|
||||
public FacesContextFactory facesContextFactory() {
|
||||
return facesContextFactory;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,16 +25,15 @@ import org.springframework.webflow.core.collection.LocalAttributeMap;
|
||||
import org.springframework.webflow.core.expression.el.WebFlowELExpressionParser;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.RequestContextHolder;
|
||||
import org.springframework.webflow.execution.ViewFactory;
|
||||
import org.springframework.webflow.test.MockExternalContext;
|
||||
|
||||
public class JsfRenderFinalResponseActionTests extends TestCase {
|
||||
public class JsfFinalResponseActionTests extends TestCase {
|
||||
|
||||
private static final String VIEW_ID = "/testView.xhtml";
|
||||
|
||||
private ViewFactory factory;
|
||||
private JsfViewFactory factory;
|
||||
|
||||
private JsfRenderFinalResponseAction finalResponseAction;
|
||||
private JsfFinalResponseAction finalResponseAction;
|
||||
|
||||
private JSFMockHelper jsfMock = new JSFMockHelper();
|
||||
|
||||
@@ -67,9 +66,9 @@ public class JsfRenderFinalResponseActionTests extends TestCase {
|
||||
jsfMock.facesContext().setViewRoot(null);
|
||||
jsfMock.application().setViewHandler(viewHandler);
|
||||
lifecycle = new TestLifecycle(jsfMock.lifecycle());
|
||||
factory = new JsfViewFactory(lifecycle, parser.parseExpression("#{'" + VIEW_ID + "'}", RequestContext.class,
|
||||
String.class, null), null);
|
||||
finalResponseAction = new JsfRenderFinalResponseAction(factory);
|
||||
factory = new JsfViewFactory(parser.parseExpression("#{'" + VIEW_ID + "'}", RequestContext.class, String.class,
|
||||
null), null);
|
||||
finalResponseAction = new JsfFinalResponseAction(factory);
|
||||
RequestContextHolder.setRequestContext(context);
|
||||
ExternalContext ext = new MockExternalContext();
|
||||
EasyMock.expect(context.getExternalContext()).andStubReturn(ext);
|
||||
@@ -77,8 +77,7 @@ public class JsfViewFactoryTests extends TestCase {
|
||||
public final void testGetView_Create() {
|
||||
|
||||
lifecycle = new NoEventLifecycle(jsfMock.lifecycle());
|
||||
factory = new JsfViewFactory(lifecycle, parser.parseExpression(VIEW_ID, RequestContext.class, String.class,
|
||||
null), null);
|
||||
factory = new JsfViewFactory(parser.parseExpression(VIEW_ID, RequestContext.class, String.class, null), null);
|
||||
|
||||
UIViewRoot newRoot = new UIViewRoot();
|
||||
newRoot.setViewId(VIEW_ID);
|
||||
@@ -99,8 +98,7 @@ public class JsfViewFactoryTests extends TestCase {
|
||||
public final void testGetView_Restore_NoEvent() {
|
||||
|
||||
lifecycle = new NoEventLifecycle(jsfMock.lifecycle());
|
||||
factory = new JsfViewFactory(lifecycle, parser.parseExpression(VIEW_ID, RequestContext.class, String.class,
|
||||
null), null);
|
||||
factory = new JsfViewFactory(parser.parseExpression(VIEW_ID, RequestContext.class, String.class, null), null);
|
||||
|
||||
UIViewRoot existingRoot = new UIViewRoot();
|
||||
existingRoot.setViewId(VIEW_ID);
|
||||
@@ -121,8 +119,7 @@ public class JsfViewFactoryTests extends TestCase {
|
||||
public final void testGetView_Restore_EventSignaled() {
|
||||
|
||||
lifecycle = new EventSignalingLifecycle(jsfMock.lifecycle());
|
||||
factory = new JsfViewFactory(lifecycle, parser.parseExpression(VIEW_ID, RequestContext.class, String.class,
|
||||
null), null);
|
||||
factory = new JsfViewFactory(parser.parseExpression(VIEW_ID, RequestContext.class, String.class, null), null);
|
||||
|
||||
UIViewRoot existingRoot = new UIViewRoot();
|
||||
existingRoot.setViewId(VIEW_ID);
|
||||
@@ -173,8 +170,7 @@ public class JsfViewFactoryTests extends TestCase {
|
||||
public final void testGetView_ExternalViewRoot() {
|
||||
|
||||
lifecycle = new NoEventLifecycle(jsfMock.lifecycle());
|
||||
factory = new JsfViewFactory(lifecycle, parser.parseExpression(VIEW_ID, RequestContext.class, String.class,
|
||||
null), null);
|
||||
factory = new JsfViewFactory(parser.parseExpression(VIEW_ID, RequestContext.class, String.class, null), null);
|
||||
|
||||
UIViewRoot newRoot = new UIViewRoot();
|
||||
newRoot.setViewId(VIEW_ID);
|
||||
|
||||
@@ -4,20 +4,15 @@ import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
|
||||
import javax.faces.FacesException;
|
||||
import javax.faces.FactoryFinder;
|
||||
import javax.faces.component.UIForm;
|
||||
import javax.faces.component.UIInput;
|
||||
import javax.faces.component.UIViewRoot;
|
||||
import javax.faces.component.html.HtmlForm;
|
||||
import javax.faces.component.html.HtmlInputText;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.render.RenderKitFactory;
|
||||
import javax.faces.render.Renderer;
|
||||
import javax.faces.render.ResponseStateManager;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.shale.test.mock.MockRenderKit;
|
||||
import org.apache.shale.test.mock.MockResponseWriter;
|
||||
import org.apache.shale.test.mock.MockStateManager;
|
||||
import org.easymock.EasyMock;
|
||||
@@ -25,7 +20,6 @@ import org.springframework.webflow.core.collection.MutableAttributeMap;
|
||||
import org.springframework.webflow.execution.FlowExecutionContext;
|
||||
import org.springframework.webflow.execution.FlowExecutionKey;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.RequestContextHolder;
|
||||
|
||||
public class JsfViewTests extends TestCase {
|
||||
|
||||
@@ -64,9 +58,6 @@ public class JsfViewTests extends TestCase {
|
||||
jsfMock.application().setStateManager(new TestStateManager());
|
||||
jsfMock.facesContext().setResponseWriter(new MockResponseWriter(output, null, null));
|
||||
|
||||
RenderKitFactory rkf = (RenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
|
||||
rkf.addRenderKit("TEST_KIT", new TestRenderKit());
|
||||
|
||||
UIViewRoot viewToRender = new UIViewRoot();
|
||||
viewToRender.setRenderKitId("TEST_KIT");
|
||||
viewToRender.setViewId(VIEW_ID);
|
||||
@@ -81,9 +72,7 @@ public class JsfViewTests extends TestCase {
|
||||
form.getChildren().add(input);
|
||||
viewToRender.getChildren().add(form);
|
||||
|
||||
view = new JsfView(viewToRender, jsfMock.lifecycle());
|
||||
|
||||
RequestContextHolder.setRequestContext(requestContext);
|
||||
view = new JsfView(viewToRender, jsfMock.lifecycle(), requestContext);
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
@@ -96,7 +85,6 @@ public class JsfViewTests extends TestCase {
|
||||
EasyMock.expect(requestContext.getFlowScope()).andStubReturn(flowMap);
|
||||
EasyMock.expect(requestContext.getFlowExecutionContext()).andStubReturn(flowExecutionContext);
|
||||
EasyMock.expect(flowExecutionContext.getKey()).andStubReturn(key);
|
||||
EasyMock.expect(flowMap.put(EasyMock.matches(JsfView.STATE_KEY), EasyMock.anyObject())).andStubReturn(null);
|
||||
EasyMock.expect(flashMap.put(EasyMock.matches("renderResponse"), EasyMock.anyObject())).andStubReturn(null);
|
||||
EasyMock.expect(flashMap.put(EasyMock.matches("responseComplete"), EasyMock.anyObject())).andStubReturn(null);
|
||||
|
||||
@@ -139,17 +127,4 @@ public class JsfViewTests extends TestCase {
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
private class TestRenderKit extends MockRenderKit {
|
||||
Renderer renderer = new Renderer() {
|
||||
};
|
||||
|
||||
public Renderer getRenderer(String family, String rendererType) {
|
||||
return renderer;
|
||||
}
|
||||
|
||||
public ResponseStateManager getResponseStateManager() {
|
||||
return new FlowResponseStateManager();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user