made event id configurable; made requird a boolean
This commit is contained in:
@@ -28,7 +28,7 @@ public class BindingModel extends AbstractModel {
|
||||
|
||||
private String converter;
|
||||
|
||||
private String required;
|
||||
private boolean required;
|
||||
|
||||
/**
|
||||
* Create a binding model
|
||||
@@ -36,7 +36,7 @@ public class BindingModel extends AbstractModel {
|
||||
* @param converter the converter
|
||||
* @param required required status
|
||||
*/
|
||||
public BindingModel(String property, String converter, String required) {
|
||||
public BindingModel(String property, String converter, boolean required) {
|
||||
setProperty(property);
|
||||
setConverter(converter);
|
||||
setRequired(required);
|
||||
@@ -91,16 +91,12 @@ public class BindingModel extends AbstractModel {
|
||||
}
|
||||
}
|
||||
|
||||
public String getRequired() {
|
||||
public boolean getRequired() {
|
||||
return required;
|
||||
}
|
||||
|
||||
public void setRequired(String required) {
|
||||
if (StringUtils.hasText(required)) {
|
||||
this.required = required;
|
||||
} else {
|
||||
this.required = null;
|
||||
}
|
||||
public void setRequired(boolean required) {
|
||||
this.required = required;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -543,8 +543,8 @@ public class XmlFlowModelBuilder implements FlowModelBuilder {
|
||||
}
|
||||
|
||||
private BindingModel parseBinding(Element element) {
|
||||
return new BindingModel(element.getAttribute("property"), element.getAttribute("converter"), element
|
||||
.getAttribute("required"));
|
||||
boolean required = Boolean.valueOf(element.getAttribute("required")).booleanValue();
|
||||
return new BindingModel(element.getAttribute("property"), element.getAttribute("converter"), required);
|
||||
}
|
||||
|
||||
private LinkedList parseOnExitActions(Element element) {
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.springframework.binding.expression.ExpressionParser;
|
||||
import org.springframework.binding.expression.beanwrapper.BeanWrapperExpressionParser;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.servlet.View;
|
||||
import org.springframework.web.servlet.ViewResolver;
|
||||
import org.springframework.webflow.engine.builder.ViewFactoryCreator;
|
||||
@@ -31,6 +32,7 @@ import org.springframework.webflow.engine.model.BinderModel;
|
||||
import org.springframework.webflow.execution.ViewFactory;
|
||||
import org.springframework.webflow.mvc.portlet.PortletMvcViewFactory;
|
||||
import org.springframework.webflow.mvc.servlet.ServletMvcViewFactory;
|
||||
import org.springframework.webflow.mvc.view.AbstractMvcViewFactory;
|
||||
import org.springframework.webflow.mvc.view.FlowViewResolver;
|
||||
|
||||
/**
|
||||
@@ -60,32 +62,23 @@ public class MvcViewFactoryCreator implements ViewFactoryCreator, ApplicationCon
|
||||
|
||||
private boolean useSpringBeanBinding;
|
||||
|
||||
private String eventIdParameterName;
|
||||
|
||||
private String fieldMarkerPrefix;
|
||||
|
||||
/**
|
||||
* Create a new Spring MVC View Factory Creator.
|
||||
* @see #setDefaultViewSuffix(String)
|
||||
* @see #setViewResolvers(List)
|
||||
* @see #setEventIdParameterName(String)
|
||||
* @see #setFieldMarkerPrefix(String)
|
||||
* @see #setUseSpringBeanBinding(boolean)
|
||||
* @see #setFlowViewResolver(FlowViewResolver)
|
||||
* @see #setViewResolvers(List)
|
||||
*/
|
||||
public MvcViewFactoryCreator() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the configured mvc environment.
|
||||
* @return the mvc environment
|
||||
*/
|
||||
public MvcEnvironment getEnvironment() {
|
||||
return environment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the configured mvc environment.
|
||||
* @param environment the mvc environment.
|
||||
*/
|
||||
public void setEnvironment(MvcEnvironment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure an {@link FlowResourceFlowViewResolver} capable of resolving view resources by applying the specified
|
||||
* default resource suffix. Default is .jsp.
|
||||
@@ -98,13 +91,41 @@ public class MvcViewFactoryCreator implements ViewFactoryCreator, ApplicationCon
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the chain of Spring MVC {@link ViewResolver view resolvers} to delegate to resolve views selected by flows.
|
||||
* Allows for reuse of existing View Resolvers configured in a Spring application context. If multiple resolvers are
|
||||
* to be used, the resolvers should be ordered in the manner they should be applied.
|
||||
* @param viewResolvers the view resolver list
|
||||
* Sets the name of the request parameter to use to lookup user events signaled by views created in this factory. If
|
||||
* not specified, the default is <code>_eventId</code>
|
||||
* @param eventIdParameterName the event id parameter name
|
||||
*/
|
||||
public void setViewResolvers(List viewResolvers) {
|
||||
this.flowViewResolver = new DelegatingFlowViewResolver(viewResolvers);
|
||||
public void setEventIdParameterName(String eventIdParameterName) {
|
||||
this.eventIdParameterName = eventIdParameterName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a prefix that can be used for parameters that mark potentially empty fields, having "prefix + field" as
|
||||
* name. Such a marker parameter is checked by existence: You can send any value for it, for example "visible". This
|
||||
* is particularly useful for HTML checkboxes and select options.
|
||||
* <p>
|
||||
* Default is "_", for "_FIELD" parameters (e.g. "_subscribeToNewsletter"). Set this to null if you want to turn off
|
||||
* the empty field check completely.
|
||||
* <p>
|
||||
* HTML checkboxes only send a value when they're checked, so it is not possible to detect that a formerly checked
|
||||
* box has just been unchecked, at least not with standard HTML means.
|
||||
* <p>
|
||||
* This auto-reset mechanism addresses this deficiency, provided that a marker parameter is sent for each checkbox
|
||||
* field, like "_subscribeToNewsletter" for a "subscribeToNewsletter" field. As the marker parameter is sent in any
|
||||
* case, the data binder can detect an empty field and automatically reset its value.
|
||||
*/
|
||||
public void setFieldMarkerPrefix(String fieldMarkerPrefix) {
|
||||
this.fieldMarkerPrefix = fieldMarkerPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether to use data binding with Spring's {@link BeanWrapper} should be enabled. Set to 'true' to enable.
|
||||
* 'false', disabled, is the default. With this enabled, the same binding system used by Spring MVC 2.x is also used
|
||||
* in a Web Flow environment.
|
||||
* @param useSpringBeanBinding the Spring bean binding flag
|
||||
*/
|
||||
public void setUseSpringBeanBinding(boolean useSpringBeanBinding) {
|
||||
this.useSpringBeanBinding = useSpringBeanBinding;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -116,22 +137,13 @@ public class MvcViewFactoryCreator implements ViewFactoryCreator, ApplicationCon
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether data binding with Spring's {@link BeanWrapper} should be enabled. Default is false. With this enabled,
|
||||
* the same binding system used by Spring MVC 2.x is also used in a Web Flow environment.
|
||||
* @return the use Spring bean binding flag
|
||||
* Sets the chain of Spring MVC {@link ViewResolver view resolvers} to delegate to resolve views selected by flows.
|
||||
* Allows for reuse of existing View Resolvers configured in a Spring application context. If multiple resolvers are
|
||||
* to be used, the resolvers should be ordered in the manner they should be applied.
|
||||
* @param viewResolvers the view resolver list
|
||||
*/
|
||||
public boolean getUseSpringBeanBinding() {
|
||||
return useSpringBeanBinding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether to use data binding with Spring's {@link BeanWrapper} should be enabled. Set to 'true' to enable.
|
||||
* 'false', disabled, is the default. With this enabled, the same binding system used by Spring MVC 2.x is also used
|
||||
* in a Web Flow environment.
|
||||
* @param useSpringBeanBinding the Spring bean binding flag
|
||||
*/
|
||||
public void setUseSpringBeanBinding(boolean useSpringBeanBinding) {
|
||||
this.useSpringBeanBinding = useSpringBeanBinding;
|
||||
public void setViewResolvers(List viewResolvers) {
|
||||
this.flowViewResolver = new DelegatingFlowViewResolver(viewResolvers);
|
||||
}
|
||||
|
||||
// implementing ApplicationContextAware
|
||||
@@ -145,6 +157,19 @@ public class MvcViewFactoryCreator implements ViewFactoryCreator, ApplicationCon
|
||||
if (useSpringBeanBinding) {
|
||||
expressionParser = new BeanWrapperExpressionParser(conversionService);
|
||||
}
|
||||
AbstractMvcViewFactory viewFactory = createMvcViewFactory(viewId, expressionParser, conversionService,
|
||||
binderModel);
|
||||
if (StringUtils.hasText(eventIdParameterName)) {
|
||||
viewFactory.setEventIdParameterName(eventIdParameterName);
|
||||
}
|
||||
if (StringUtils.hasText(fieldMarkerPrefix)) {
|
||||
viewFactory.setFieldMarkerPrefix(fieldMarkerPrefix);
|
||||
}
|
||||
return viewFactory;
|
||||
}
|
||||
|
||||
private AbstractMvcViewFactory createMvcViewFactory(Expression viewId, ExpressionParser expressionParser,
|
||||
ConversionService conversionService, BinderModel binderModel) {
|
||||
if (environment == MvcEnvironment.SERVLET) {
|
||||
return new ServletMvcViewFactory(viewId, flowViewResolver, expressionParser, conversionService, binderModel);
|
||||
} else if (environment == MvcEnvironment.PORTLET) {
|
||||
|
||||
@@ -38,11 +38,7 @@ public class PortletMvcViewFactory extends AbstractMvcViewFactory {
|
||||
}
|
||||
|
||||
protected AbstractMvcView createMvcView(View view, RequestContext context) {
|
||||
PortletMvcView mvcView = new PortletMvcView(view, context);
|
||||
mvcView.setExpressionParser(getExpressionParser());
|
||||
mvcView.setConversionService(getConversionService());
|
||||
mvcView.setBinderModel(getBinderModel());
|
||||
return mvcView;
|
||||
return new PortletMvcView(view, context);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -38,11 +38,7 @@ public class ServletMvcViewFactory extends AbstractMvcViewFactory {
|
||||
}
|
||||
|
||||
protected AbstractMvcView createMvcView(View view, RequestContext context) {
|
||||
ServletMvcView mvcView = new ServletMvcView(view, context);
|
||||
mvcView.setExpressionParser(getExpressionParser());
|
||||
mvcView.setConversionService(getConversionService());
|
||||
mvcView.setBinderModel(getBinderModel());
|
||||
return mvcView;
|
||||
return new ServletMvcView(view, context);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -80,13 +80,15 @@ public abstract class AbstractMvcView implements View {
|
||||
|
||||
private ConversionService conversionService;
|
||||
|
||||
private MappingResults mappingResults;
|
||||
private String fieldMarkerPrefix = "_";
|
||||
|
||||
private boolean viewErrors;
|
||||
private String eventIdParameterName = "_eventId";
|
||||
|
||||
private String eventId;
|
||||
|
||||
private String fieldMarkerPrefix = "_";
|
||||
private MappingResults mappingResults;
|
||||
|
||||
private boolean viewErrors;
|
||||
|
||||
private BinderModel binderModel;
|
||||
|
||||
@@ -143,6 +145,15 @@ public abstract class AbstractMvcView implements View {
|
||||
this.fieldMarkerPrefix = fieldMarkerPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name of the request parameter to use to lookup user events signaled by this view. If not specified, the
|
||||
* default is <code>_eventId</code>
|
||||
* @param eventIdParameterName the event id parameter name
|
||||
*/
|
||||
public void setEventIdParameterName(String eventIdParameterName) {
|
||||
this.eventIdParameterName = eventIdParameterName;
|
||||
}
|
||||
|
||||
public void render() throws IOException {
|
||||
Map model = new HashMap();
|
||||
model.putAll(flowScopes());
|
||||
@@ -308,10 +319,7 @@ public abstract class AbstractMvcView implements View {
|
||||
ParserContext parserContext = new FluentParserContext().evaluate(model.getClass());
|
||||
Expression target = expressionParser.parseExpression(binding.getProperty(), parserContext);
|
||||
DefaultMapping mapping = new DefaultMapping(source, target);
|
||||
// TODO - this is inefficient - consider introducing a typed Binding object
|
||||
if (binding.getRequired() != null) {
|
||||
mapping.setRequired(Boolean.valueOf(binding.getRequired()).booleanValue());
|
||||
}
|
||||
mapping.setRequired(binding.getRequired());
|
||||
if (binding.getConverter() != null) {
|
||||
ConversionExecutor conversionExecutor = conversionService.getConversionExecutor(binding.getConverter(),
|
||||
String.class, target.getValueType(model));
|
||||
@@ -441,7 +449,7 @@ public abstract class AbstractMvcView implements View {
|
||||
}
|
||||
|
||||
private void determineEventId(RequestContext context) {
|
||||
eventId = WebUtils.findParameterValue(context.getRequestParameters().asMap(), "_eventId");
|
||||
eventId = WebUtils.findParameterValue(context.getRequestParameters().asMap(), eventIdParameterName);
|
||||
}
|
||||
|
||||
private static class PropertyNotFoundError implements MappingResultsCriteria {
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.webflow.mvc.view;
|
||||
import org.springframework.binding.convert.ConversionService;
|
||||
import org.springframework.binding.expression.Expression;
|
||||
import org.springframework.binding.expression.ExpressionParser;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.webflow.engine.model.BinderModel;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.View;
|
||||
@@ -40,6 +41,10 @@ public abstract class AbstractMvcViewFactory implements ViewFactory {
|
||||
|
||||
private BinderModel binderModel;
|
||||
|
||||
private String eventIdParameterName;
|
||||
|
||||
private String fieldMarkerPrefix;
|
||||
|
||||
public AbstractMvcViewFactory(Expression viewId, FlowViewResolver viewResolver, ExpressionParser expressionParser,
|
||||
ConversionService conversionService, BinderModel binderModel) {
|
||||
this.viewId = viewId;
|
||||
@@ -49,22 +54,28 @@ public abstract class AbstractMvcViewFactory implements ViewFactory {
|
||||
this.binderModel = binderModel;
|
||||
}
|
||||
|
||||
protected ExpressionParser getExpressionParser() {
|
||||
return expressionParser;
|
||||
public void setEventIdParameterName(String eventIdParameterName) {
|
||||
this.eventIdParameterName = eventIdParameterName;
|
||||
}
|
||||
|
||||
protected ConversionService getConversionService() {
|
||||
return conversionService;
|
||||
}
|
||||
|
||||
protected BinderModel getBinderModel() {
|
||||
return binderModel;
|
||||
public void setFieldMarkerPrefix(String fieldMarkerPrefix) {
|
||||
this.fieldMarkerPrefix = fieldMarkerPrefix;
|
||||
}
|
||||
|
||||
public View getView(RequestContext context) {
|
||||
String viewId = (String) this.viewId.getValue(context);
|
||||
org.springframework.web.servlet.View view = viewResolver.resolveView(viewId, context);
|
||||
return createMvcView(view, context);
|
||||
AbstractMvcView mvcView = createMvcView(view, context);
|
||||
mvcView.setExpressionParser(expressionParser);
|
||||
mvcView.setConversionService(conversionService);
|
||||
mvcView.setBinderModel(binderModel);
|
||||
if (StringUtils.hasText(eventIdParameterName)) {
|
||||
mvcView.setEventIdParameterName(eventIdParameterName);
|
||||
}
|
||||
if (StringUtils.hasText(fieldMarkerPrefix)) {
|
||||
mvcView.setFieldMarkerPrefix(fieldMarkerPrefix);
|
||||
}
|
||||
return mvcView;
|
||||
}
|
||||
|
||||
protected abstract AbstractMvcView createMvcView(org.springframework.web.servlet.View view, RequestContext context);
|
||||
|
||||
@@ -216,8 +216,7 @@ public class MvcViewTests extends TestCase {
|
||||
org.springframework.web.servlet.View mvcView = new MockView();
|
||||
AbstractMvcView view = new MockMvcView(mvcView, context);
|
||||
BinderModel binderModel = new BinderModel();
|
||||
binderModel
|
||||
.addBinding(new org.springframework.webflow.engine.model.BindingModel("stringProperty", null, "true"));
|
||||
binderModel.addBinding(new org.springframework.webflow.engine.model.BindingModel("stringProperty", null, true));
|
||||
view.setBinderModel(binderModel);
|
||||
view.processUserEvent();
|
||||
assertTrue(view.hasFlowEvent());
|
||||
|
||||
Reference in New Issue
Block a user