SWF-991 Replace ajax-driven flow attribute with mode=embedded flow input attribute.
This commit is contained in:
@@ -5,8 +5,6 @@
|
||||
|
||||
<secured attributes="ROLE_USER" />
|
||||
|
||||
<ajax-driven />
|
||||
|
||||
<input name="hotelId" required="true" />
|
||||
|
||||
<on-start>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<br />
|
||||
${hotel.country}
|
||||
</address>
|
||||
<form action="booking" method="get">
|
||||
<form action="booking?mode=embedded" method="get">
|
||||
<p>
|
||||
Nightly Rate:
|
||||
<spring:bind path="hotel.price">${status.value}</spring:bind>
|
||||
|
||||
@@ -157,4 +157,10 @@ public interface RequestControlContext extends RequestContext {
|
||||
*/
|
||||
public boolean getRedirectInSameState();
|
||||
|
||||
/**
|
||||
* Returns true if the flow current flow execution was launched in embedded page mode. When a flow is embedded on a
|
||||
* page it can make different assumptions with regards to whether redirect after post is necessary.
|
||||
*/
|
||||
public boolean getEmbeddedMode();
|
||||
|
||||
}
|
||||
@@ -41,11 +41,6 @@ import org.springframework.webflow.execution.ViewFactory;
|
||||
*/
|
||||
public class ViewState extends TransitionableState {
|
||||
|
||||
/**
|
||||
* The name of the attribute indicating an Ajax-driven Flow Definition.
|
||||
*/
|
||||
private static final String AJAX_DRIVEN_ATTRIBUTE_NAME = "ajaxDriven";
|
||||
|
||||
/**
|
||||
* The list of actions to be executed before the view is rendered.
|
||||
*/
|
||||
@@ -273,10 +268,8 @@ public class ViewState extends TransitionableState {
|
||||
if (redirect != null) {
|
||||
return redirect.booleanValue();
|
||||
}
|
||||
if (getAjaxDriven(context) != null) {
|
||||
if (context.getExternalContext().isAjaxRequest()) {
|
||||
return false;
|
||||
}
|
||||
if (context.getExternalContext().isAjaxRequest() && context.getEmbeddedMode()) {
|
||||
return false;
|
||||
}
|
||||
return context.getRedirectOnPause();
|
||||
}
|
||||
@@ -285,18 +278,12 @@ public class ViewState extends TransitionableState {
|
||||
if (redirect != null) {
|
||||
return redirect.booleanValue();
|
||||
}
|
||||
if (getAjaxDriven(context) != null) {
|
||||
if (context.getExternalContext().isAjaxRequest()) {
|
||||
return false;
|
||||
}
|
||||
if (context.getExternalContext().isAjaxRequest() && context.getEmbeddedMode()) {
|
||||
return false;
|
||||
}
|
||||
return context.getRedirectInSameState();
|
||||
}
|
||||
|
||||
private Boolean getAjaxDriven(RequestControlContext context) {
|
||||
return context.getActiveFlow().getAttributes().getBoolean(AJAX_DRIVEN_ATTRIBUTE_NAME);
|
||||
}
|
||||
|
||||
private void render(RequestControlContext context, View view) throws ViewRenderingException {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Rendering + " + view);
|
||||
|
||||
@@ -76,7 +76,6 @@ import org.springframework.webflow.engine.model.AbstractActionModel;
|
||||
import org.springframework.webflow.engine.model.AbstractMappingModel;
|
||||
import org.springframework.webflow.engine.model.AbstractStateModel;
|
||||
import org.springframework.webflow.engine.model.ActionStateModel;
|
||||
import org.springframework.webflow.engine.model.AjaxDrivenModel;
|
||||
import org.springframework.webflow.engine.model.AttributeModel;
|
||||
import org.springframework.webflow.engine.model.BeanImportModel;
|
||||
import org.springframework.webflow.engine.model.BinderModel;
|
||||
@@ -383,7 +382,6 @@ public class FlowModelFlowBuilder extends AbstractFlowBuilder {
|
||||
MutableAttributeMap flowAttributes = parseMetaAttributes(flow.getAttributes());
|
||||
parseAndPutPersistenceContext(flow.getPersistenceContext(), flowAttributes);
|
||||
parseAndPutSecured(flow.getSecured(), flowAttributes);
|
||||
parseAndPutAjaxDriven(flow.getAjaxDriven(), flowAttributes);
|
||||
return flowAttributes;
|
||||
}
|
||||
|
||||
@@ -929,12 +927,6 @@ public class FlowModelFlowBuilder extends AbstractFlowBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
private void parseAndPutAjaxDriven(AjaxDrivenModel ajaxDrivenModel, MutableAttributeMap attributes) {
|
||||
if (ajaxDrivenModel != null) {
|
||||
attributes.put("ajaxDriven", Boolean.TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
private void parseAndPutSecured(SecuredModel secured, MutableAttributeMap attributes) {
|
||||
if (secured != null) {
|
||||
SecurityRule rule = new SecurityRule();
|
||||
|
||||
@@ -214,6 +214,9 @@ public class FlowExecutionImpl implements FlowExecution, Externalizable {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Starting in " + externalContext + " with input " + input);
|
||||
}
|
||||
if (hasEmbeddedModeAttribute(input)) {
|
||||
attributes.asMap().put("embeddedMode", Boolean.TRUE);
|
||||
}
|
||||
MessageContext messageContext = createMessageContext(null);
|
||||
RequestControlContext requestContext = createRequestContext(externalContext, messageContext);
|
||||
RequestContextHolder.setRequestContext(requestContext);
|
||||
@@ -243,9 +246,8 @@ public class FlowExecutionImpl implements FlowExecution, Externalizable {
|
||||
}
|
||||
|
||||
public void resume(ExternalContext externalContext) throws FlowExecutionException, IllegalStateException {
|
||||
Assert
|
||||
.state(status == FlowExecutionStatus.ACTIVE,
|
||||
"This FlowExecution cannot be resumed because it is not active; it has either not been started or has ended");
|
||||
Assert.state(status == FlowExecutionStatus.ACTIVE,
|
||||
"This FlowExecution cannot be resumed because it is not active; it has either not been started or has ended");
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Resuming in " + externalContext);
|
||||
}
|
||||
@@ -643,4 +645,14 @@ public class FlowExecutionImpl implements FlowExecution, Externalizable {
|
||||
return getActiveSessionInternal().getFlow().handleException(exception, context);
|
||||
}
|
||||
|
||||
private boolean hasEmbeddedModeAttribute(AttributeMap input) {
|
||||
if (input != null) {
|
||||
String mode = (String) input.get("mode");
|
||||
if (mode != null && mode.trim().toLowerCase().equals("embedded")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -251,11 +251,12 @@ class RequestControlContextImpl implements RequestControlContext {
|
||||
return true;
|
||||
}
|
||||
Boolean redirectInSameState = flowExecution.getAttributes().getBoolean("redirectInSameState");
|
||||
if (redirectInSameState != null) {
|
||||
return redirectInSameState.booleanValue();
|
||||
} else {
|
||||
return getRedirectOnPause();
|
||||
}
|
||||
return (redirectInSameState != null) ? redirectInSameState.booleanValue() : getRedirectOnPause();
|
||||
}
|
||||
|
||||
public boolean getEmbeddedMode() {
|
||||
Boolean embedded = flowExecution.getAttributes().getBoolean("embeddedMode");
|
||||
return (embedded != null) ? embedded.booleanValue() : false;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
@@ -264,4 +265,5 @@ class RequestControlContextImpl implements RequestControlContext {
|
||||
.append("attributes", attributes).append("messageContext", messageContext)
|
||||
.append("flowExecution", flowExecution).toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.webflow.engine.model;
|
||||
|
||||
/**
|
||||
* Model support for the ajax-driven element.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 2.3
|
||||
*/
|
||||
public class AjaxDrivenModel extends AbstractModel {
|
||||
|
||||
public AjaxDrivenModel() {
|
||||
}
|
||||
|
||||
public boolean isMergeableWith(Model model) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void merge(Model model) {
|
||||
|
||||
}
|
||||
|
||||
public Model createCopy() {
|
||||
return new AjaxDrivenModel();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -58,8 +58,6 @@ public class FlowModel extends AbstractModel {
|
||||
|
||||
private PersistenceContextModel persistenceContext;
|
||||
|
||||
private AjaxDrivenModel ajaxDriven;
|
||||
|
||||
private LinkedList vars;
|
||||
|
||||
private LinkedList inputs;
|
||||
@@ -226,20 +224,6 @@ public class FlowModel extends AbstractModel {
|
||||
this.persistenceContext = persistenceContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the ajaxDriven model
|
||||
*/
|
||||
public AjaxDrivenModel getAjaxDriven() {
|
||||
return ajaxDriven;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ajaxDriven the ajaxDriven model to set
|
||||
*/
|
||||
public void setAjaxDriven(AjaxDrivenModel ajaxDriven) {
|
||||
this.ajaxDriven = ajaxDriven;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the vars
|
||||
*/
|
||||
|
||||
@@ -41,7 +41,7 @@ import org.xml.sax.SAXException;
|
||||
*/
|
||||
class WebFlowEntityResolver implements EntityResolver {
|
||||
|
||||
private static final String[] WEBFLOW_VERSIONS = new String[] { "spring-webflow-2.3", "spring-webflow-2.0" };
|
||||
private static final String[] WEBFLOW_VERSIONS = new String[] { "spring-webflow-2.0" };
|
||||
|
||||
public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
|
||||
if (systemId != null && systemId.indexOf("spring-webflow.xsd") > -1) {
|
||||
|
||||
@@ -31,7 +31,6 @@ import org.springframework.util.xml.DomUtils;
|
||||
import org.springframework.webflow.engine.model.AbstractActionModel;
|
||||
import org.springframework.webflow.engine.model.AbstractStateModel;
|
||||
import org.springframework.webflow.engine.model.ActionStateModel;
|
||||
import org.springframework.webflow.engine.model.AjaxDrivenModel;
|
||||
import org.springframework.webflow.engine.model.AttributeModel;
|
||||
import org.springframework.webflow.engine.model.BeanImportModel;
|
||||
import org.springframework.webflow.engine.model.BinderModel;
|
||||
@@ -202,7 +201,6 @@ public class XmlFlowModelBuilder implements FlowModelBuilder {
|
||||
flow.setAttributes(parseAttributes(element));
|
||||
flow.setSecured(parseSecured(element));
|
||||
flow.setPersistenceContext(parsePersistenceContext(element));
|
||||
flow.setAjaxDriven(parseAjaxDriven(element));
|
||||
flow.setVars(parseVars(element));
|
||||
flow.setInputs(parseInputs(element));
|
||||
flow.setOnStartActions(parseOnStartActions(element));
|
||||
@@ -412,15 +410,6 @@ public class XmlFlowModelBuilder implements FlowModelBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
private AjaxDrivenModel parseAjaxDriven(Element element) {
|
||||
element = DomUtils.getChildElementByTagName(element, "ajax-driven");
|
||||
if (element == null) {
|
||||
return null;
|
||||
} else {
|
||||
return new AjaxDrivenModel();
|
||||
}
|
||||
}
|
||||
|
||||
private VarModel parseVar(Element element) {
|
||||
return new VarModel(element.getAttribute("name"), element.getAttribute("class"));
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -137,6 +137,14 @@ public class MockRequestControlContext extends MockRequestContext implements Req
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getEmbeddedMode() {
|
||||
Boolean embedded = getMockFlowExecutionContext().getAttributes().getBoolean("embeddedMode");
|
||||
if (embedded != null) {
|
||||
return embedded;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// implementation specific accessors for testing
|
||||
|
||||
public void setAlwaysRedirectOnPause(boolean alwaysRedirectOnPause) {
|
||||
@@ -149,4 +157,8 @@ public class MockRequestControlContext extends MockRequestContext implements Req
|
||||
.put("redirectInSameState", Boolean.valueOf(redirectInSameState));
|
||||
}
|
||||
|
||||
public void setEmbeddedMode(boolean embedded) {
|
||||
getMockFlowExecutionContext().getAttributeMap().put("embeddedMode", Boolean.valueOf(embedded));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -443,28 +443,23 @@ public class ViewStateTests extends TestCase {
|
||||
assertTrue(context.getMockExternalContext().getFlowExecutionRedirectRequested());
|
||||
}
|
||||
|
||||
public void testAjaxDrivenAttributeOverridesRedirectInSameState() {
|
||||
public void testEmbeddedModeOverridesRedirectInSameState() {
|
||||
Flow flow = new Flow("myFlow");
|
||||
flow.getAttributes().put("ajaxDriven", Boolean.TRUE);
|
||||
StubViewFactory viewFactory = new StubViewFactory();
|
||||
ViewState state = new ViewState(flow, "viewState", viewFactory);
|
||||
Transition t = new Transition(on("submit"), null);
|
||||
state.getTransitionSet().add(t);
|
||||
MockRequestControlContext context = new MockRequestControlContext(flow);
|
||||
state.enter(context);
|
||||
context = new MockRequestControlContext(context.getFlowExecutionContext());
|
||||
context.getMockExternalContext().setAjaxRequest(true);
|
||||
context.setEmbeddedMode(true);
|
||||
context.setAlwaysRedirectOnPause(true);
|
||||
context.setRedirectInSameState(true);
|
||||
context.getFlowScope().remove("renderCalled");
|
||||
context.putRequestParameter("_eventId", "submit");
|
||||
state.resume(context);
|
||||
state.enter(context);
|
||||
assertFalse(context.getMockExternalContext().getFlowExecutionRedirectRequested());
|
||||
}
|
||||
|
||||
public void testViewStateRedirectOverridesAjaxDrivenAttribute() {
|
||||
public void testViewStateRedirectOverridesEmbeddedMode() {
|
||||
Flow flow = new Flow("myFlow");
|
||||
flow.getAttributes().put("ajaxDriven", Boolean.TRUE);
|
||||
StubViewFactory viewFactory = new StubViewFactory();
|
||||
ViewState state = new ViewState(flow, "viewState", viewFactory);
|
||||
state.setRedirect(false);
|
||||
@@ -472,13 +467,10 @@ public class ViewStateTests extends TestCase {
|
||||
state.getTransitionSet().add(t);
|
||||
MockRequestControlContext context = new MockRequestControlContext(flow);
|
||||
state.enter(context);
|
||||
context = new MockRequestControlContext(context.getFlowExecutionContext());
|
||||
context.getMockExternalContext().setAjaxRequest(true);
|
||||
context.setEmbeddedMode(true);
|
||||
context.setAlwaysRedirectOnPause(true);
|
||||
context.setRedirectInSameState(true);
|
||||
context.getFlowScope().remove("renderCalled");
|
||||
context.putRequestParameter("_eventId", "submit");
|
||||
state.resume(context);
|
||||
assertFalse(context.getMockExternalContext().getFlowExecutionRedirectRequested());
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@ import org.springframework.webflow.engine.ViewState;
|
||||
import org.springframework.webflow.engine.builder.FlowAssembler;
|
||||
import org.springframework.webflow.engine.builder.FlowBuilderException;
|
||||
import org.springframework.webflow.engine.impl.FlowExecutionImplFactory;
|
||||
import org.springframework.webflow.engine.model.AjaxDrivenModel;
|
||||
import org.springframework.webflow.engine.model.AttributeModel;
|
||||
import org.springframework.webflow.engine.model.EndStateModel;
|
||||
import org.springframework.webflow.engine.model.EvaluateModel;
|
||||
@@ -130,14 +129,6 @@ public class FlowModelFlowBuilderTests extends TestCase {
|
||||
assertTrue(((Boolean) flow.getAttributes().get("persistenceContext")).booleanValue());
|
||||
}
|
||||
|
||||
public void testAjaxDrivenFlow() {
|
||||
model.setAjaxDriven(new AjaxDrivenModel());
|
||||
model.setStates(singleList(new EndStateModel("end")));
|
||||
Flow flow = getFlow(model);
|
||||
assertNotNull(flow.getAttributes().get("ajaxDriven"));
|
||||
assertTrue(((Boolean) flow.getAttributes().get("ajaxDriven")).booleanValue());
|
||||
}
|
||||
|
||||
public void testFlowInputOutputMapping() {
|
||||
InputModel input1 = new InputModel("foo", "flowScope.foo");
|
||||
InputModel input2 = new InputModel("foo", "flowScope.bar");
|
||||
|
||||
@@ -8,13 +8,6 @@ public class WebFlowEntityResolverTests extends TestCase {
|
||||
|
||||
private static final String PUBLIC_ID = "http://www.springframework.org/schema/webflow";
|
||||
|
||||
public void testResolve23() throws Exception {
|
||||
WebFlowEntityResolver resolver = new WebFlowEntityResolver();
|
||||
InputSource source = resolver.resolveEntity(PUBLIC_ID,
|
||||
"http://www.springframework.org/schema/webflow/spring-webflow-2.3.xsd");
|
||||
assertNotNull(source);
|
||||
}
|
||||
|
||||
public void testResolve20() throws Exception {
|
||||
WebFlowEntityResolver resolver = new WebFlowEntityResolver();
|
||||
InputSource source = resolver.resolveEntity(PUBLIC_ID,
|
||||
|
||||
@@ -13,7 +13,6 @@ import org.springframework.webflow.engine.builder.FlowAssembler;
|
||||
import org.springframework.webflow.engine.builder.model.FlowModelFlowBuilder;
|
||||
import org.springframework.webflow.engine.impl.FlowExecutionImplFactory;
|
||||
import org.springframework.webflow.engine.model.AbstractStateModel;
|
||||
import org.springframework.webflow.engine.model.AjaxDrivenModel;
|
||||
import org.springframework.webflow.engine.model.AttributeModel;
|
||||
import org.springframework.webflow.engine.model.BindingModel;
|
||||
import org.springframework.webflow.engine.model.ExceptionHandlerModel;
|
||||
@@ -104,16 +103,6 @@ public class XmlFlowModelBuilderTests extends TestCase {
|
||||
assertEquals("ROLE_USER", secured.getAttributes());
|
||||
}
|
||||
|
||||
public void testFlowAjaxDriven() {
|
||||
ClassPathResource resource = new ClassPathResource("flow-ajax-driven.xml", getClass());
|
||||
FlowModelBuilder builder = new XmlFlowModelBuilder(resource, registry);
|
||||
builder.init();
|
||||
builder.build();
|
||||
FlowModel flow = builder.getFlowModel();
|
||||
AjaxDrivenModel ajaxDriven = flow.getAjaxDriven();
|
||||
assertNotNull(ajaxDriven);
|
||||
}
|
||||
|
||||
public void testFlowSecuredState() {
|
||||
ClassPathResource resource = new ClassPathResource("flow-secured-state.xml", getClass());
|
||||
FlowModelBuilder builder = new XmlFlowModelBuilder(resource, registry);
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
<flow xmlns="http://www.springframework.org/schema/webflow"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/webflow http://www.springframework.org/schema/webflow/spring-webflow-2.3.xsd">
|
||||
|
||||
<ajax-driven/>
|
||||
|
||||
<end-state id="end"/>
|
||||
|
||||
</flow>
|
||||
Reference in New Issue
Block a user