SWF-1419 Add ability to plug in custom Spring Validator via FlowBuilderServices to support JSR-303 validation
This commit is contained in:
@@ -73,25 +73,4 @@ When set to true, changes to a flow definition will be auto-detected and will re
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="resources">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation
|
||||
source="java:org.springframework.faces.webflow.JsfResourceRequestHandler"><![CDATA[
|
||||
Configures a handler that uses the JSF ResourceHandler API introduced in JSF 2 to serve web application and
|
||||
classpath resources such as images, CSS and JavaScript files from well-known locations.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="order" type="xsd:int">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
Specifies the order of the HandlerMapping for the resource handler. The default order is 0.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
</xsd:schema>
|
||||
@@ -0,0 +1,97 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<xsd:schema
|
||||
xmlns="http://www.springframework.org/schema/faces"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
targetNamespace="http://www.springframework.org/schema/faces"
|
||||
elementFormDefault="qualified" attributeFormDefault="unqualified"
|
||||
version="2.2">
|
||||
|
||||
<xsd:import namespace="http://www.springframework.org/schema/beans" schemaLocation="http://www.springframework.org/schema/beans/spring-beans-3.0.xsd" />
|
||||
|
||||
<xsd:element name="flow-builder-services">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
Registers custom implementations of services needed to build flow definitions in a JSF environment.
|
||||
With this tag, you may configure a custom ConversionService, FormatterFactory, ExpressionParser, and ViewFactoryCreator implementation.
|
||||
This tag is only needed when you wish to plugin custom implementations.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="beans:identifiedType">
|
||||
<xsd:attribute name="conversion-service">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
The custom ConversionService implementation to use to convert from one type to another.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="expression-parser">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
The custom ExpressionParser implementation to use to compile expression strings into Expressions.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="view-factory-creator">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
The custom ViewFactoryCreator implementation to use produce ViewFactories capable of rendering Views.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="enable-managed-beans" type="xsd:boolean">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
When this attribute is set to true, a special EL expression parser will be enabled that allows access to JSF-managed beans
|
||||
from EL expressions in flow definitions.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="development" type="xsd:boolean">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
Puts all flows in development mode.
|
||||
When set to true, changes to a flow definition will be auto-detected and will result in a flow refresh.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="resources">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation
|
||||
source="java:org.springframework.faces.webflow.JsfResourceRequestHandler"><![CDATA[
|
||||
Configures a handler that uses the JSF ResourceHandler API introduced in JSF 2 to serve web application and
|
||||
classpath resources such as images, CSS and JavaScript files from well-known locations.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="order" type="xsd:int">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
Specifies the order of the HandlerMapping for the resource handler. The default order is 0.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
</xsd:schema>
|
||||
@@ -15,7 +15,11 @@
|
||||
*/
|
||||
package org.springframework.faces.webflow;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.js.ajax.AjaxHandler;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.webflow.mvc.servlet.FlowHandlerAdapter;
|
||||
|
||||
/**
|
||||
@@ -39,4 +43,9 @@ public class JsfFlowHandlerAdapter extends FlowHandlerAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
|
||||
throws Exception {
|
||||
return super.handle(request, response, handler);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import javax.faces.lifecycle.Lifecycle;
|
||||
import org.springframework.binding.convert.ConversionService;
|
||||
import org.springframework.binding.expression.Expression;
|
||||
import org.springframework.binding.expression.ExpressionParser;
|
||||
import org.springframework.validation.Validator;
|
||||
import org.springframework.webflow.engine.builder.BinderConfiguration;
|
||||
import org.springframework.webflow.engine.builder.ViewFactoryCreator;
|
||||
import org.springframework.webflow.execution.ViewFactory;
|
||||
@@ -36,7 +37,7 @@ public class JsfViewFactoryCreator implements ViewFactoryCreator {
|
||||
private Lifecycle lifecycle;
|
||||
|
||||
public ViewFactory createViewFactory(Expression viewIdExpression, ExpressionParser expressionParser,
|
||||
ConversionService conversionService, BinderConfiguration binderConfiguration) {
|
||||
ConversionService conversionService, BinderConfiguration binderConfiguration, Validator validator) {
|
||||
return new JsfViewFactory(viewIdExpression, getLifecycle());
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
http\://www.springframework.org/schema/faces/spring-faces-2.0.xsd=org/springframework/faces/config/spring-faces-2.0.xsd
|
||||
http\://www.springframework.org/schema/faces/spring-faces-2.0.xsd=org/springframework/faces/config/spring-faces-2.0.xsd
|
||||
http\://www.springframework.org/schema/faces/spring-faces-2.2.xsd=org/springframework/faces/config/spring-faces-2.2.xsd
|
||||
http\://www.springframework.org/schema/faces/spring-faces.xsd=org/springframework/faces/config/spring-faces-2.2.xsd
|
||||
@@ -17,6 +17,7 @@ import org.springframework.faces.model.converter.FacesConversionService;
|
||||
import org.springframework.faces.webflow.FacesSpringELExpressionParser;
|
||||
import org.springframework.faces.webflow.JSFMockHelper;
|
||||
import org.springframework.faces.webflow.JsfViewFactoryCreator;
|
||||
import org.springframework.validation.Validator;
|
||||
import org.springframework.webflow.engine.builder.BinderConfiguration;
|
||||
import org.springframework.webflow.engine.builder.ViewFactoryCreator;
|
||||
import org.springframework.webflow.engine.builder.support.FlowBuilderServices;
|
||||
@@ -78,7 +79,7 @@ public class FacesFlowBuilderServicesBeanDefinitionParserTests extends TestCase
|
||||
public static class TestViewFactoryCreator implements ViewFactoryCreator {
|
||||
|
||||
public ViewFactory createViewFactory(Expression viewIdExpression, ExpressionParser expressionParser,
|
||||
ConversionService conversionService, BinderConfiguration binderConfiguration) {
|
||||
ConversionService conversionService, BinderConfiguration binderConfiguration, Validator validator) {
|
||||
throw new UnsupportedOperationException("Auto-generated method stub");
|
||||
}
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
xmlns:faces="http://www.springframework.org/schema/faces"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/faces
|
||||
http://www.springframework.org/schema/faces/spring-faces-2.0.xsd">
|
||||
http://www.springframework.org/schema/faces/spring-faces.xsd">
|
||||
|
||||
<faces:flow-builder-services id="flowBuilderServicesDefault"/>
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:faces="http://www.springframework.org/schema/faces"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
|
||||
http://www.springframework.org/schema/faces http://www.springframework.org/schema/faces/spring-faces-2.0.xsd">
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/faces http://www.springframework.org/schema/faces/spring-faces.xsd">
|
||||
|
||||
<faces:resources />
|
||||
|
||||
|
||||
@@ -21,12 +21,12 @@
|
||||
|
||||
<dependencies>
|
||||
<!-- core dependencies -->
|
||||
<dependency org="javax.xml.bind" name="com.springsource.javax.xml.bind" rev="2.2.0" conf="compile->runtime" />
|
||||
<dependency org="com.sun.xml" name="com.springsource.com.sun.xml.bind" rev="2.2.0" conf="compile->runtime" />
|
||||
<dependency org="javax.persistence" name="com.springsource.javax.persistence" rev="1.0.0" conf="compile->runtime"/>
|
||||
<dependency org="javax.servlet" name="com.springsource.javax.servlet" rev="2.4.0" conf="provided->runtime"/>
|
||||
<dependency org="javax.servlet" name="com.springsource.javax.servlet.jsp.jstl" rev="1.2.0" conf="compile->runtime"/>
|
||||
<dependency org="javax.transaction" name="com.springsource.javax.transaction" rev="1.1.0" conf="compile->runtime"/>
|
||||
<dependency org="javax.xml.bind" name="com.springsource.javax.xml.bind" rev="2.2.0" conf="compile->runtime" />
|
||||
<dependency org="org.apache.log4j" name="com.springsource.org.apache.log4j" rev="1.2.15" conf="compile->runtime"/>
|
||||
<dependency org="org.hibernate" name="com.springsource.org.hibernate" rev="3.2.6.ga" conf="compile->runtime"/>
|
||||
<dependency org="org.hibernate" name="com.springsource.org.hibernate.annotations" rev="3.3.0.ga" conf="compile->runtime"/>
|
||||
|
||||
@@ -38,17 +38,12 @@ public class Booking implements Serializable {
|
||||
|
||||
private Hotel hotel;
|
||||
|
||||
@NotNull
|
||||
private Date checkinDate;
|
||||
|
||||
@Future
|
||||
@NotNull
|
||||
private Date checkoutDate;
|
||||
|
||||
@Pattern(regexp = "[0-9]{16}", message = "is not a 16 digit card number")
|
||||
private String creditCard;
|
||||
|
||||
@NotEmpty
|
||||
private String creditCardName;
|
||||
|
||||
private int creditCardExpiryMonth;
|
||||
@@ -68,6 +63,7 @@ public class Booking implements Serializable {
|
||||
this.hotel = hotel;
|
||||
this.user = user;
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.add(Calendar.DAY_OF_MONTH, 1);
|
||||
setCheckinDate(calendar.getTime());
|
||||
calendar.add(Calendar.DAY_OF_MONTH, 1);
|
||||
setCheckoutDate(calendar.getTime());
|
||||
@@ -99,6 +95,8 @@ public class Booking implements Serializable {
|
||||
|
||||
@Basic
|
||||
@Temporal(TemporalType.DATE)
|
||||
@Future
|
||||
@NotNull
|
||||
public Date getCheckinDate() {
|
||||
return checkinDate;
|
||||
}
|
||||
@@ -127,6 +125,8 @@ public class Booking implements Serializable {
|
||||
|
||||
@Basic
|
||||
@Temporal(TemporalType.DATE)
|
||||
@Future
|
||||
@NotNull
|
||||
public Date getCheckoutDate() {
|
||||
return checkoutDate;
|
||||
}
|
||||
@@ -135,6 +135,7 @@ public class Booking implements Serializable {
|
||||
this.checkoutDate = checkoutDate;
|
||||
}
|
||||
|
||||
@Pattern(regexp = "[0-9]{16}", message = "{invalidCreditCardPattern}")
|
||||
public String getCreditCard() {
|
||||
return creditCard;
|
||||
}
|
||||
@@ -166,6 +167,7 @@ public class Booking implements Serializable {
|
||||
this.beds = beds;
|
||||
}
|
||||
|
||||
@NotEmpty
|
||||
public String getCreditCardName() {
|
||||
return creditCardName;
|
||||
}
|
||||
@@ -202,11 +204,11 @@ public class Booking implements Serializable {
|
||||
public void validateEnterBookingDetails(ValidationContext context) {
|
||||
MessageContext messages = context.getMessageContext();
|
||||
if (checkinDate.before(today())) {
|
||||
messages.addMessage(new MessageBuilder().error().source("checkinDate").code(
|
||||
"booking.checkinDate.beforeToday").build());
|
||||
messages.addMessage(new MessageBuilder().error().source("checkinDate")
|
||||
.code("booking.checkinDate.beforeToday").build());
|
||||
} else if (checkoutDate.before(checkinDate)) {
|
||||
messages.addMessage(new MessageBuilder().error().source("checkoutDate").code(
|
||||
"booking.checkoutDate.beforeCheckinDate").build());
|
||||
messages.addMessage(new MessageBuilder().error().source("checkoutDate")
|
||||
.code("booking.checkoutDate.beforeCheckinDate").build());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
# Custom messages for JSR-303 validation
|
||||
invalidCreditCardPattern=is not a valid 16 digit card number.
|
||||
@@ -4,9 +4,9 @@
|
||||
xmlns:tx="http://www.springframework.org/schema/tx"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/tx
|
||||
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
|
||||
http://www.springframework.org/schema/tx/spring-tx.xsd">
|
||||
|
||||
<!-- Instructs Spring to perfrom declarative transaction management on annotated classes -->
|
||||
<tx:annotation-driven />
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
xmlns:security="http://www.springframework.org/schema/security"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/security
|
||||
http://www.springframework.org/schema/security/spring-security-3.0.xsd">
|
||||
http://www.springframework.org/schema/security/spring-security.xsd">
|
||||
|
||||
<!-- Configure Spring Security -->
|
||||
<security:http auto-config="true" use-expressions="true">
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/context
|
||||
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
|
||||
http://www.springframework.org/schema/context/spring-context.xsd">
|
||||
|
||||
<!-- Scans for application @Components to deploy -->
|
||||
<context:component-scan base-package="org.springframework.webflow.samples.booking" />
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
xmlns:webflow="http://www.springframework.org/schema/webflow-config"
|
||||
xmlns:faces="http://www.springframework.org/schema/faces"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
||||
http://www.springframework.org/schema/webflow-config http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd
|
||||
http://www.springframework.org/schema/faces http://www.springframework.org/schema/faces/spring-faces-2.0.xsd">
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/webflow-config http://www.springframework.org/schema/webflow-config/spring-webflow-config.xsd
|
||||
http://www.springframework.org/schema/faces http://www.springframework.org/schema/faces/spring-faces.xsd">
|
||||
|
||||
<!-- Executes flows: the central entry point into the Spring Web Flow system -->
|
||||
<webflow:flow-executor id="flowExecutor">
|
||||
<webflow:flow-executor id="flowExecutor">
|
||||
<webflow:flow-execution-listeners>
|
||||
<webflow:listener ref="facesContextListener"/>
|
||||
<webflow:listener ref="jpaFlowExecutionListener" />
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:faces="http://www.springframework.org/schema/faces"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
||||
http://www.springframework.org/schema/faces http://www.springframework.org/schema/faces/spring-faces-2.0.xsd">
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/faces http://www.springframework.org/schema/faces/spring-faces.xsd">
|
||||
|
||||
<faces:resources />
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
<h:selectOneMenu id="pageSize" value="#{searchCriteria.pageSize}">
|
||||
<f:selectItems value="#{referenceData.pageSizeOptions}" />
|
||||
</h:selectOneMenu>
|
||||
<p:commandButton id="findHotels" value="Find Hotels" action="search" update="@form" />
|
||||
<p:commandButton id="findHotels" value="Find Hotels" action="search" update="@form" ajax="false" />
|
||||
</h:panelGrid>
|
||||
<p:tooltip for="searchString" targetPosition="topRight" position="bottomLeft"
|
||||
value="Search hotels by name, address, city, or zip." style="cream" />
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
<dependency org="javax.servlet" name="com.springsource.javax.servlet.jsp" rev="2.1.0" conf="provided->runtime"/>
|
||||
<dependency org="javax.servlet" name="com.springsource.javax.servlet.jsp.jstl" rev="1.1.2" conf="compile->runtime"/>
|
||||
<dependency org="javax.transaction" name="com.springsource.javax.transaction" rev="1.1.0" conf="compile->runtime"/>
|
||||
<dependency org="javax.xml.bind" name="com.springsource.javax.xml.bind" rev="2.2.0" conf="compile->runtime" />
|
||||
<dependency org="org.apache.log4j" name="com.springsource.org.apache.log4j" rev="1.2.15" conf="compile->runtime"/>
|
||||
<dependency org="org.apache.taglibs" name="com.springsource.org.apache.taglibs.standard" rev="1.1.2" conf="compile->runtime"/>
|
||||
<dependency org="org.apache.tiles" name="com.springsource.org.apache.tiles" rev="2.1.2.osgi" conf="compile->runtime"/>
|
||||
@@ -35,8 +36,10 @@
|
||||
<dependency org="org.hibernate" name="com.springsource.org.hibernate" rev="3.2.6.ga" conf="compile->runtime"/>
|
||||
<dependency org="org.hibernate" name="com.springsource.org.hibernate.annotations" rev="3.3.0.ga" conf="compile->runtime"/>
|
||||
<dependency org="org.hibernate" name="com.springsource.org.hibernate.ejb" rev="3.3.1.ga" conf="compile->runtime"/>
|
||||
<dependency org="org.hibernate" name="com.springsource.org.hibernate.validator" rev="4.1.0.GA" conf="compile->runtime" />
|
||||
<dependency org="org.hsqldb" name="com.springsource.org.hsqldb" rev="1.8.0.9" conf="compile->runtime"/>
|
||||
<dependency org="org.joda" name="com.springsource.org.joda.time" rev="1.6.0" conf="compile->runtime"/>
|
||||
<dependency org="org.slf4j" name="com.springsource.slf4j.log4j" rev="1.5.6" />
|
||||
<dependency org="org.springframework" name="org.springframework.aop" rev="3.0.4.RELEASE" conf="compile->runtime"/>
|
||||
<dependency org="org.springframework" name="org.springframework.beans" rev="3.0.4.RELEASE" conf="compile->runtime"/>
|
||||
<dependency org="org.springframework" name="org.springframework.context" rev="3.0.4.RELEASE" conf="compile->runtime"/>
|
||||
|
||||
@@ -157,6 +157,27 @@
|
||||
<artifactId>org.springframework.webflow</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<!-- Bean Validation -->
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>com.springsource.org.hibernate.validator</artifactId>
|
||||
<version>4.1.0.GA</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>com.springsource.slf4j.log4j</artifactId>
|
||||
<version>1.5.6</version>
|
||||
</dependency>
|
||||
<!--
|
||||
JAXB is needed when running on Java 5. In this environment these dependencies have to be added
|
||||
(unless xml configuration is explicitly disabled via Configuration.ignoreXmlConfiguration)
|
||||
On Java 6 jaxb is part of the runtime environment.
|
||||
-->
|
||||
<dependency>
|
||||
<groupId>javax.xml.bind</groupId>
|
||||
<artifactId>com.springsource.javax.xml.bind</artifactId>
|
||||
<version>2.2.0</version>
|
||||
</dependency>
|
||||
<!-- Build time only dependencies -->
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
|
||||
@@ -16,17 +16,19 @@ import javax.persistence.ManyToOne;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
import javax.persistence.Transient;
|
||||
import javax.validation.constraints.Future;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import org.springframework.binding.message.MessageBuilder;
|
||||
import org.springframework.binding.message.MessageContext;
|
||||
import org.springframework.binding.validation.ValidationContext;
|
||||
import org.hibernate.validator.constraints.NotEmpty;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
/**
|
||||
* A Hotel Booking made by a User.
|
||||
*/
|
||||
@Entity
|
||||
@BookingDateRange
|
||||
public class Booking implements Serializable {
|
||||
|
||||
private Long id;
|
||||
|
||||
private User user;
|
||||
@@ -55,6 +57,7 @@ public class Booking implements Serializable {
|
||||
|
||||
public Booking() {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.add(Calendar.DAY_OF_MONTH, 1);
|
||||
setCheckinDate(calendar.getTime());
|
||||
calendar.add(Calendar.DAY_OF_MONTH, 1);
|
||||
setCheckoutDate(calendar.getTime());
|
||||
@@ -92,6 +95,8 @@ public class Booking implements Serializable {
|
||||
|
||||
@Basic
|
||||
@Temporal(TemporalType.DATE)
|
||||
@NotNull
|
||||
@Future
|
||||
public Date getCheckinDate() {
|
||||
return checkinDate;
|
||||
}
|
||||
@@ -120,6 +125,8 @@ public class Booking implements Serializable {
|
||||
|
||||
@Basic
|
||||
@Temporal(TemporalType.DATE)
|
||||
@NotNull
|
||||
@Future
|
||||
public Date getCheckoutDate() {
|
||||
return checkoutDate;
|
||||
}
|
||||
@@ -128,6 +135,7 @@ public class Booking implements Serializable {
|
||||
this.checkoutDate = checkoutDate;
|
||||
}
|
||||
|
||||
@NotEmpty
|
||||
public String getCreditCard() {
|
||||
return creditCard;
|
||||
}
|
||||
@@ -159,6 +167,7 @@ public class Booking implements Serializable {
|
||||
this.beds = beds;
|
||||
}
|
||||
|
||||
@NotEmpty
|
||||
public String getCreditCardName() {
|
||||
return creditCardName;
|
||||
}
|
||||
@@ -192,17 +201,6 @@ public class Booking implements Serializable {
|
||||
this.amenities = amenities;
|
||||
}
|
||||
|
||||
public void validateEnterBookingDetails(ValidationContext context) {
|
||||
MessageContext messages = context.getMessageContext();
|
||||
if (checkinDate.before(today())) {
|
||||
messages.addMessage(new MessageBuilder().error().source("checkinDate").code(
|
||||
"booking.checkinDate.beforeToday").build());
|
||||
} else if (checkoutDate.before(checkinDate)) {
|
||||
messages.addMessage(new MessageBuilder().error().source("checkoutDate").code(
|
||||
"booking.checkoutDate.beforeCheckinDate").build());
|
||||
}
|
||||
}
|
||||
|
||||
private Date today() {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.add(Calendar.DAY_OF_MONTH, -1);
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package org.springframework.webflow.samples.booking;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import javax.validation.Constraint;
|
||||
import javax.validation.Payload;
|
||||
|
||||
@Constraint(validatedBy = BookingDateRangeValidator.class)
|
||||
@Target({ ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.PARAMETER })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface BookingDateRange {
|
||||
|
||||
String message() default "Invalid check-in and check-out date range";
|
||||
|
||||
Class<?>[] groups() default {};
|
||||
|
||||
Class<? extends Payload>[] payload() default {};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.springframework.webflow.samples.booking;
|
||||
|
||||
import javax.validation.ConstraintValidator;
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
|
||||
public class BookingDateRangeValidator implements ConstraintValidator<BookingDateRange, Booking> {
|
||||
|
||||
public void initialize(BookingDateRange bookingDateRange) {
|
||||
}
|
||||
|
||||
public boolean isValid(Booking booking, ConstraintValidatorContext context) {
|
||||
if ((booking.getCheckinDate() != null) && (booking.getCheckoutDate() != null)
|
||||
&& booking.getCheckoutDate().before(booking.getCheckinDate())) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -21,9 +21,14 @@
|
||||
<property name="dataSource" ref="dataSource" />
|
||||
<property name="jpaVendorAdapter">
|
||||
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
|
||||
</property>
|
||||
<property name="jpaProperties">
|
||||
<value>
|
||||
hibernate.session_factory_name=mySessionFactory
|
||||
</value>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
</bean>
|
||||
|
||||
<!-- Deploys a in-memory "booking" datasource populated -->
|
||||
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
|
||||
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
xmlns:webflow="http://www.springframework.org/schema/webflow-config"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/webflow-config
|
||||
http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd">
|
||||
http://www.springframework.org/schema/webflow-config/spring-webflow-config.xsd">
|
||||
|
||||
<!-- Executes flows: the entry point into the Spring Web Flow system -->
|
||||
<webflow:flow-executor id="flowExecutor">
|
||||
@@ -22,7 +22,8 @@
|
||||
</webflow:flow-registry>
|
||||
|
||||
<!-- Plugs in a custom creator for Web Flow views -->
|
||||
<webflow:flow-builder-services id="flowBuilderServices" view-factory-creator="mvcViewFactoryCreator" development="true" />
|
||||
<webflow:flow-builder-services id="flowBuilderServices" view-factory-creator="mvcViewFactoryCreator"
|
||||
development="true" validator="validator" />
|
||||
|
||||
<!-- Configures Web Flow to use Tiles to create views for rendering; Tiles allows for applying consistent layouts to your views -->
|
||||
<bean id="mvcViewFactoryCreator" class="org.springframework.webflow.mvc.builder.MvcViewFactoryCreator">
|
||||
@@ -38,5 +39,8 @@
|
||||
|
||||
<!-- Installs a listener to apply Spring Security authorities -->
|
||||
<bean id="securityFlowExecutionListener" class="org.springframework.webflow.security.SecurityFlowExecutionListener" />
|
||||
|
||||
<!-- Bootstraps JSR-303 validation and adapts it to Spring's Validator interface -->
|
||||
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
|
||||
|
||||
</beans>
|
||||
@@ -15,15 +15,15 @@
|
||||
|
||||
<view-state id="enterBookingDetails" model="booking">
|
||||
<binder>
|
||||
<binding property="checkinDate" required="true" />
|
||||
<binding property="checkoutDate" required="true" />
|
||||
<binding property="beds" required="true" />
|
||||
<binding property="smoking" required="true" />
|
||||
<binding property="creditCard" required="true" />
|
||||
<binding property="creditCardName" required="true" />
|
||||
<binding property="creditCardExpiryMonth" required="true" />
|
||||
<binding property="creditCardExpiryYear" required="true" />
|
||||
<binding property="amenities" required="false" />
|
||||
<binding property="checkinDate" />
|
||||
<binding property="checkoutDate" />
|
||||
<binding property="beds" />
|
||||
<binding property="smoking" />
|
||||
<binding property="creditCard" />
|
||||
<binding property="creditCardName" />
|
||||
<binding property="creditCardExpiryMonth" />
|
||||
<binding property="creditCardExpiryYear" />
|
||||
<binding property="amenities" />
|
||||
</binder>
|
||||
<transition on="proceed" to="reviewBooking" />
|
||||
<transition on="cancel" to="cancel" bind="false" />
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
<div class="error">
|
||||
<spring:bind path="booking.*">
|
||||
<c:forEach items="${status.errorMessages}" var="error">
|
||||
<c:out value="${error}"/><br>
|
||||
<span><c:out value="${error}"/></span><br>
|
||||
</c:forEach>
|
||||
</spring:bind>
|
||||
</div>
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
booking.checkinDate.required=The check in date is required
|
||||
booking.checkinDate.typeMismatch=The check in date must be in the format mm-dd-yyyy
|
||||
booking.checkinDate.NotNull=The check in date is required
|
||||
booking.checkinDate.Future=The check in date must be in the future
|
||||
booking.checkinDate.beforeToday=The check in date must be a future date
|
||||
booking.checkinDate.typeMismatch=The check in date must be in the format mm-dd-yyyy
|
||||
|
||||
booking.checkoutDate.required=The check out date is required
|
||||
booking.checkoutDate.Future=The check out date must be in the future
|
||||
booking.checkoutDate.NotNull=The check out date is required
|
||||
booking.checkoutDate.typeMismatch=The check out date must be in the format mm-dd-yyyy
|
||||
booking.checkoutDate.beforeCheckinDate=The check out date must be later than the check in date
|
||||
booking.BookingDateRange=The check out date must be later than the check in date
|
||||
|
||||
booking.creditCard.required=The credit card must be a valid 16 digit number
|
||||
booking.creditCardName.required=The name on the credit card is required
|
||||
booking.creditCard.NotEmpty=The credit card must be a valid 16 digit number
|
||||
booking.creditCardName.NotEmpty=The name on the credit card is required
|
||||
|
||||
required=The {0} field is required
|
||||
NotEmpty=The {0} field is required
|
||||
NotNull=The {0} field is required
|
||||
Future=The {0} date must be in the future
|
||||
@@ -5,11 +5,11 @@
|
||||
xmlns:faces="http://www.springframework.org/schema/faces"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/webflow-config
|
||||
http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd
|
||||
http://www.springframework.org/schema/webflow-config/spring-webflow-config.xsd
|
||||
http://www.springframework.org/schema/faces
|
||||
http://www.springframework.org/schema/faces/spring-faces-2.0.xsd">
|
||||
http://www.springframework.org/schema/faces/spring-faces.xsd">
|
||||
|
||||
<!-- Maps portlet modes to handlers -->
|
||||
<bean id="portletModeHandlerMapping" class="org.springframework.web.portlet.handler.PortletModeHandlerMapping">
|
||||
|
||||
@@ -26,14 +26,17 @@
|
||||
<dependency org="javax.servlet" name="com.springsource.javax.servlet" rev="2.4.0" conf="provided->compile"/>
|
||||
<dependency org="javax.servlet" name="com.springsource.javax.servlet.jsp.jstl" rev="1.1.2" conf="compile->compile"/>
|
||||
<dependency org="javax.transaction" name="com.springsource.javax.transaction" rev="1.1.0" conf="compile->compile"/>
|
||||
<dependency org="javax.xml.bind" name="com.springsource.javax.xml.bind" rev="2.2.0" conf="compile->runtime" />
|
||||
<dependency org="org.aopalliance" name="com.springsource.org.aopalliance" rev="1.0.0" conf="compile->compile"/>
|
||||
<dependency org="org.apache.log4j" name="com.springsource.org.apache.log4j" rev="1.2.15" conf="compile->compile"/>
|
||||
<dependency org="org.apache.taglibs" name="com.springsource.org.apache.taglibs.standard" rev="1.1.2" conf="compile->compile"/>
|
||||
<dependency org="org.hibernate" name="com.springsource.org.hibernate" rev="3.2.6.ga" conf="compile->compile"/>
|
||||
<dependency org="org.hibernate" name="com.springsource.org.hibernate.annotations" rev="3.3.0.ga" conf="compile->compile"/>
|
||||
<dependency org="org.hibernate" name="com.springsource.org.hibernate.ejb" rev="3.3.1.ga" conf="compile->compile"/>
|
||||
<dependency org="org.hibernate" name="com.springsource.org.hibernate.validator" rev="4.1.0.GA" conf="compile->runtime" />
|
||||
<dependency org="org.hsqldb" name="com.springsource.org.hsqldb" rev="1.8.0.9" conf="compile->compile"/>
|
||||
<dependency org="org.joda" name="com.springsource.org.joda.time" rev="1.6.0" conf="compile->runtime"/>
|
||||
<dependency org="org.slf4j" name="com.springsource.slf4j.log4j" rev="1.5.6" />
|
||||
<dependency org="org.springframework" name="org.springframework.aop" rev="3.0.4.RELEASE" conf="compile->compile"/>
|
||||
<dependency org="org.springframework" name="org.springframework.beans" rev="3.0.4.RELEASE" conf="compile->compile"/>
|
||||
<dependency org="org.springframework" name="org.springframework.context" rev="3.0.4.RELEASE" conf="compile->compile"/>
|
||||
|
||||
@@ -117,6 +117,27 @@
|
||||
<artifactId>org.springframework.webflow</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<!-- Bean Validation -->
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>com.springsource.org.hibernate.validator</artifactId>
|
||||
<version>4.1.0.GA</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>com.springsource.slf4j.log4j</artifactId>
|
||||
<version>1.5.6</version>
|
||||
</dependency>
|
||||
<!--
|
||||
JAXB is needed when running on Java 5. In this environment these dependencies have to be added
|
||||
(unless xml configuration is explicitly disabled via Configuration.ignoreXmlConfiguration)
|
||||
On Java 6 jaxb is part of the runtime environment.
|
||||
-->
|
||||
<dependency>
|
||||
<groupId>javax.xml.bind</groupId>
|
||||
<artifactId>com.springsource.javax.xml.bind</artifactId>
|
||||
<version>2.2.0</version>
|
||||
</dependency>
|
||||
<!-- build time only dependencies -->
|
||||
<dependency>
|
||||
<groupId>javax.portlet</groupId>
|
||||
|
||||
@@ -15,13 +15,17 @@ import javax.persistence.ManyToOne;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
import javax.persistence.Transient;
|
||||
import javax.validation.constraints.Future;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import org.hibernate.validator.constraints.NotEmpty;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
/**
|
||||
* A Hotel Booking made by a User.
|
||||
*/
|
||||
@Entity
|
||||
@BookingDateRange
|
||||
public class Booking implements Serializable {
|
||||
private Long id;
|
||||
|
||||
@@ -49,6 +53,7 @@ public class Booking implements Serializable {
|
||||
|
||||
public Booking() {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.add(Calendar.DAY_OF_MONTH, 1);
|
||||
setCheckinDate(calendar.getTime());
|
||||
calendar.add(Calendar.DAY_OF_MONTH, 1);
|
||||
setCheckoutDate(calendar.getTime());
|
||||
@@ -82,6 +87,8 @@ public class Booking implements Serializable {
|
||||
|
||||
@Basic
|
||||
@Temporal(TemporalType.DATE)
|
||||
@NotNull
|
||||
@Future
|
||||
public Date getCheckinDate() {
|
||||
return checkinDate;
|
||||
}
|
||||
@@ -110,6 +117,8 @@ public class Booking implements Serializable {
|
||||
|
||||
@Basic
|
||||
@Temporal(TemporalType.DATE)
|
||||
@NotNull
|
||||
@Future
|
||||
public Date getCheckoutDate() {
|
||||
return checkoutDate;
|
||||
}
|
||||
@@ -118,6 +127,7 @@ public class Booking implements Serializable {
|
||||
this.checkoutDate = checkoutDate;
|
||||
}
|
||||
|
||||
@NotEmpty
|
||||
public String getCreditCard() {
|
||||
return creditCard;
|
||||
}
|
||||
@@ -149,6 +159,7 @@ public class Booking implements Serializable {
|
||||
this.beds = beds;
|
||||
}
|
||||
|
||||
@NotEmpty
|
||||
public String getCreditCardName() {
|
||||
return creditCardName;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package org.springframework.webflow.samples.booking;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import javax.validation.Constraint;
|
||||
import javax.validation.Payload;
|
||||
|
||||
@Constraint(validatedBy = BookingDateRangeValidator.class)
|
||||
@Target({ ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.PARAMETER })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface BookingDateRange {
|
||||
|
||||
String message() default "Invalid check-in and check-out date range";
|
||||
|
||||
Class<?>[] groups() default {};
|
||||
|
||||
Class<? extends Payload>[] payload() default {};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.springframework.webflow.samples.booking;
|
||||
|
||||
import javax.validation.ConstraintValidator;
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
|
||||
public class BookingDateRangeValidator implements ConstraintValidator<BookingDateRange, Booking> {
|
||||
|
||||
public void initialize(BookingDateRange bookingDateRange) {
|
||||
}
|
||||
|
||||
public boolean isValid(Booking booking, ConstraintValidatorContext context) {
|
||||
if ((booking.getCheckinDate() != null) && (booking.getCheckoutDate() != null)
|
||||
&& booking.getCheckoutDate().before(booking.getCheckinDate())) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,11 +5,11 @@
|
||||
xmlns:tx="http://www.springframework.org/schema/tx"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/context
|
||||
http://www.springframework.org/schema/context/spring-context-2.5.xsd
|
||||
http://www.springframework.org/schema/context/spring-context.xsd
|
||||
http://www.springframework.org/schema/tx
|
||||
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
|
||||
http://www.springframework.org/schema/tx/spring-tx.xsd">
|
||||
|
||||
<!-- Activates annotation-based bean configuration -->
|
||||
<context:annotation-config />
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
xmlns:webflow="http://www.springframework.org/schema/webflow-config"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/webflow-config
|
||||
http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd">
|
||||
http://www.springframework.org/schema/webflow-config/spring-webflow-config.xsd">
|
||||
|
||||
<!-- Maps portlet modes to handlers -->
|
||||
<bean id="portletModeHandlerMapping" class="org.springframework.web.portlet.handler.PortletModeHandlerMapping">
|
||||
@@ -38,11 +38,14 @@
|
||||
</webflow:flow-executor>
|
||||
|
||||
<!-- The registry of executable flow definitions -->
|
||||
<webflow:flow-registry id="flowRegistry">
|
||||
<webflow:flow-registry id="flowRegistry" flow-builder-services="flowBuilderServices">
|
||||
<webflow:flow-location path="/WEB-INF/flows/view/view.xml" />
|
||||
<webflow:flow-location path="/WEB-INF/flows/main/main.xml" />
|
||||
<webflow:flow-location path="/WEB-INF/flows/booking/booking.xml" />
|
||||
</webflow:flow-registry>
|
||||
|
||||
<!-- Plugs in Spring's JSR-303 validator adapter -->
|
||||
<webflow:flow-builder-services id="flowBuilderServices" development="true" validator="validator" />
|
||||
|
||||
<!-- Installs a listener that manages JPA persistence contexts for flows that require them -->
|
||||
<bean id="jpaFlowExecutionListener" class="org.springframework.webflow.persistence.JpaFlowExecutionListener">
|
||||
@@ -50,4 +53,7 @@
|
||||
<constructor-arg ref="transactionManager" />
|
||||
</bean>
|
||||
|
||||
<!-- Bootstraps JSR-303 validation and adapts it to Spring's Validator interface -->
|
||||
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
|
||||
|
||||
</beans>
|
||||
@@ -9,8 +9,16 @@
|
||||
<portlet:param name="execution" value="${flowExecutionKey}" />
|
||||
</portlet:actionURL>
|
||||
<form:form id="booking" modelAttribute="booking" action="${actionUrl}">
|
||||
<form:errors path="*" cssClass="errors" />
|
||||
<fieldset>
|
||||
<spring:hasBindErrors name="booking">
|
||||
<div class="error">
|
||||
<spring:bind path="booking.*">
|
||||
<c:forEach items="${status.errorMessages}" var="error">
|
||||
<span><c:out value="${error}"/></span><br>
|
||||
</c:forEach>
|
||||
</spring:bind>
|
||||
</div>
|
||||
</spring:hasBindErrors>
|
||||
<fieldset>
|
||||
<table>
|
||||
<tr class="field">
|
||||
<td class="label">Name:</td>
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
booking.checkinDate.NotNull=The check in date is required
|
||||
booking.checkinDate.Future=The check in date must be in the future
|
||||
booking.checkinDate.beforeToday=The check in date must be a future date
|
||||
booking.checkinDate.typeMismatch=The check in date must be in the format mm-dd-yyyy
|
||||
|
||||
booking.checkoutDate.Future=The check out date must be in the future
|
||||
booking.checkoutDate.NotNull=The check out date is required
|
||||
booking.checkoutDate.typeMismatch=The check out date must be in the format mm-dd-yyyy
|
||||
booking.BookingDateRange=The check out date must be later than the check in date
|
||||
|
||||
booking.creditCard.NotEmpty=The credit card must be a valid 16 digit number
|
||||
booking.creditCardName.NotEmpty=The name on the credit card is required
|
||||
|
||||
NotEmpty=The {0} field is required
|
||||
NotNull=The {0} field is required
|
||||
Future=The {0} date must be in the future
|
||||
@@ -45,12 +45,14 @@ class FlowBuilderServicesBeanDefinitionParser extends AbstractSingleBeanDefiniti
|
||||
private static final String DEVELOPMENT_ATTR = "development";
|
||||
private static final String EXPRESSION_PARSER_ATTR = "expression-parser";
|
||||
private static final String VIEW_FACTORY_CREATOR_ATTR = "view-factory-creator";
|
||||
private static final String VALIDATOR_ATTR = "validator";
|
||||
|
||||
// --------------------------- Bean Configuration Properties --------------------- //
|
||||
private static final String CONVERSION_SERVICE_PROPERTY = "conversionService";
|
||||
private static final String DEVELOPMENT_PROPERTY = "development";
|
||||
private static final String EXPRESSION_PARSER_PROPERTY = "expressionParser";
|
||||
private static final String VIEW_FACTORY_CREATOR_PROPERTY = "viewFactoryCreator";
|
||||
private static final String VALIDATOR_PROPERTY = "validator";
|
||||
|
||||
protected String getBeanClassName(Element element) {
|
||||
return FLOW_BUILDER_SERVICES_CLASS_NAME;
|
||||
@@ -65,6 +67,7 @@ class FlowBuilderServicesBeanDefinitionParser extends AbstractSingleBeanDefiniti
|
||||
parseConversionService(element, parserContext, builder);
|
||||
parseExpressionParser(element, parserContext, builder);
|
||||
parseViewFactoryCreator(element, parserContext, builder);
|
||||
parseValidator(element, parserContext, builder);
|
||||
parseDevelopment(element, builder);
|
||||
|
||||
parserContext.popAndRegisterContainingComponent();
|
||||
@@ -105,6 +108,13 @@ class FlowBuilderServicesBeanDefinitionParser extends AbstractSingleBeanDefiniti
|
||||
definitionBuilder.addPropertyReference(VIEW_FACTORY_CREATOR_PROPERTY, viewFactoryCreator);
|
||||
}
|
||||
|
||||
private void parseValidator(Element element, ParserContext context, BeanDefinitionBuilder definitionBuilder) {
|
||||
String validator = element.getAttribute(VALIDATOR_ATTR);
|
||||
if (StringUtils.hasText(validator)) {
|
||||
definitionBuilder.addPropertyReference(VALIDATOR_PROPERTY, validator);
|
||||
}
|
||||
}
|
||||
|
||||
private void parseDevelopment(Element element, BeanDefinitionBuilder definitionBuilder) {
|
||||
String development = element.getAttribute(DEVELOPMENT_ATTR);
|
||||
if (StringUtils.hasText(development)) {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
targetNamespace="http://www.springframework.org/schema/webflow-config"
|
||||
elementFormDefault="qualified" attributeFormDefault="unqualified"
|
||||
version="2.0.3">
|
||||
version="2.0">
|
||||
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
|
||||
@@ -0,0 +1,448 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<xsd:schema
|
||||
xmlns="http://www.springframework.org/schema/webflow-config"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
targetNamespace="http://www.springframework.org/schema/webflow-config"
|
||||
elementFormDefault="qualified" attributeFormDefault="unqualified"
|
||||
version="2.3">
|
||||
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
Spring Web Flow Configuration Schema
|
||||
Authors: Keith Donald, Jeremy Grelle, Scott Andrews
|
||||
<br>
|
||||
A XML-based DSL for configuring the Spring Web Flow 2.0 system.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
|
||||
<xsd:import namespace="http://www.springframework.org/schema/beans" schemaLocation="http://www.springframework.org/schema/beans/spring-beans-3.0.xsd" />
|
||||
|
||||
<xsd:element name="flow-registry">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
Deploys a registry of flow definitions. A flow registry is used by a flow executor to locate flows to execute.
|
||||
<br>
|
||||
Each flow definition registered in this registry is assigned a unique identifier. By default,
|
||||
this identifier is the name of the externalized resource minus its file extension. For example,
|
||||
a registry containing flow definitions built from the files "orderitem-flow.xml" and "shipping-flow.xml"
|
||||
would index those definitions by "orderitem-flow" and "shipping-flow" by default.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="beans:identifiedType">
|
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:element name="flow-location" type="flowLocationType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
Registers a flow defined at an external resource such as a .xml file.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="flow-location-pattern">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
Registers a set of flows resolved from a resource location pattern (e.g. /WEB-INF/flows/**/*-flow.xml).
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="value" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
The location pattern to resolve (e.g. /WEB-INF/flows/**/*-flow.xml)
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="flow-builder" type="flowBuilderType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
Registers a custom FlowBuilder implementation.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
<xsd:attribute name="flow-builder-services" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
A reference to a FlowBuilderServices implementation defining custom services needed to build the flows registered in this registry.
|
||||
Optional. For use when one or more custom builder services are required.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="parent" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
A reference to this registry's parent. Registries can be organized in a hierarchy. If a child registry does not contain a flow,
|
||||
its parent registry will be queried.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="base-path" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
The base path where flow definitions are found. When specified, all flow locations are relative to this path.
|
||||
Also when specified, by default flows are assigned ids equal to the the path segment between their base path and file name.
|
||||
For example, if a flow definition is located at '/WEB-INF/hotels/booking/booking-flow.xml' and the base path is '/WEB-INF',
|
||||
the remaining path to this flow is 'hotels/booking' which then becomes the flow id.
|
||||
If a flow definition is found directly on the base path, the file name minus its extension is used as the flow id.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:complexType name="flowLocationType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="flow-definition-attributes" type="flowDefinitionAttributesType" minOccurs="0">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
Meta-attributes to assign to the flow definition.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="id" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
The id assign the flow definition in this registry. Optional.
|
||||
Specify when you wish to provide a custom flow definition identifier.
|
||||
When specified, the id must be unique among all flows in this registry.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="path" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
The resource path to the externalized flow definition resource. May be a path to a single resource or a ANT-style path expression
|
||||
that matches multiple resources.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="flowBuilderType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="flow-definition-attributes" type="flowDefinitionAttributesType" minOccurs="0">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
Attributes to assign to the flow definition.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="id" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
The id assign the flow definition in this registry. Optional.
|
||||
Specify when you wish to provide a custom flow definition identifier.
|
||||
When specified, the id must be unique among all flows in this registry.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="class" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
The fully qualified class name of the FlowBuilder implementation.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:element name="flow-builder-services">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
Registers custom implementations of services needed to build flow definitions.
|
||||
With this tag, you may configure a custom ConversionService, FormatterFactory, ExpressionParser, and ViewFactoryCreator implementation.
|
||||
This tag is only needed when you wish to plugin custom implementations.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="beans:identifiedType">
|
||||
<xsd:attribute name="conversion-service">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
The custom ConversionService implementation to use to convert from one type to another.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="expression-parser">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
The custom ExpressionParser implementation to use to compile expression strings into Expressions.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="view-factory-creator">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
The custom ViewFactoryCreator implementation to use produce ViewFactories capable of rendering Views.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="validator">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation source="java:org.springframework.validation.Validator">
|
||||
<![CDATA[
|
||||
The bean name of the Validator that is to be used for validating a model declared on a view state.
|
||||
This attribute is not required, and only needs to be specified explicitly if a custom Validator needs to be configured.
|
||||
If not specified, JSR-303 validation will be installed if a JSR-303 provider is present on the classpath.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="development" type="xsd:boolean">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
Puts all flows in development mode.
|
||||
When set to true, changes to a flow definition will be auto-detected and will result in a flow refresh.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="flow-executor">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
Deploys a flow executor. A FlowExecutor executes flow definitions and acts as the entry-point into the Web Flow system.
|
||||
A flow executor launches new flow executions and resumes paused flow executions.
|
||||
Paused flow executions are stored between requests in a FlowExecutionRepository.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="beans:identifiedType">
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="flow-execution-repository" type="flowExecutionRepositoryType" minOccurs="0">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
Configures the FlowExecutionRepository used by this executor to persist flow executions.
|
||||
Specify when you want to tune the attributes of the default repository implementation.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="flow-execution-attributes" type="flowExecutionAttributesType" minOccurs="0">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
Meta attributes to assign new flow executions launched by this executor. These attributes will be associated with all flow executions,
|
||||
regardless of their underlying flow definition. Such attributes may influence flow execution behavior at runtime.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="flow-execution-listeners" type="flowExecutionListenersType" minOccurs="0">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
Registers listeners that observe the lifecycle of flow executions launched by this executor.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
<xsd:attribute name="flow-registry" type="xsd:string" default="flowRegistry">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
A reference to the FlowRegistry bean containing the flows eligible for execution by this executor.
|
||||
The default value 'flowRegistry'.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:complexType name="flowExecutionRepositoryType">
|
||||
<xsd:attribute name="max-executions" type="xsd:integer">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
The maximum number of persistent flow executions allowed per user session. The default is 5.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="max-execution-snapshots" type="xsd:integer">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
The maximum number of history snapshots allowed per flow execution. The default is 30.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="flowExecutionListenersType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="listener" type="flowExecutionListenerType" maxOccurs="unbounded">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
Registers a listener to observe the execution lifecycle of one or more flows.
|
||||
The flow definitions this listener observes may be restricted by specifying listener criteria.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="flowExecutionListenerType">
|
||||
<xsd:attribute name="ref" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
A reference to the flow execution listener implementation to register.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="criteria" type="xsd:string" default="*">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
The criteria that determines the flow definitions your listener should observe, delimited by commas or '*' for "all".
|
||||
Example: 'flow1,flow2,flow3'.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="flowExecutionAttributesType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="always-redirect-on-pause" type="alwaysRedirectOnPauseType" minOccurs="0" maxOccurs="1">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
Determines if flow executions always redirect after they pause.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="attribute" type="attributeType" minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
A single flow execution meta attribute.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="alwaysRedirectOnPauseType">
|
||||
<xsd:attribute name="value" type="xsd:boolean" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
true = always redirect on pause; false = do not, only redirect when explicitly instructed by the flow definition.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="flowDefinitionAttributesType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="attribute" type="attributeType" minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
A single flow definition meta attribute.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="attributeType">
|
||||
<xsd:attribute name="name" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
The name of the attribute.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="type" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
The attribute's type, used to perform a from-string type conversion if specified.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="value" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
The attribute value, subject to a type conversion if the 'type' attribute is defined.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
</xsd:schema>
|
||||
@@ -18,6 +18,7 @@ package org.springframework.webflow.engine.builder;
|
||||
import org.springframework.binding.convert.ConversionService;
|
||||
import org.springframework.binding.expression.ExpressionParser;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.validation.Validator;
|
||||
import org.springframework.webflow.core.collection.AttributeMap;
|
||||
import org.springframework.webflow.definition.registry.FlowDefinitionLocator;
|
||||
|
||||
@@ -70,6 +71,12 @@ public interface FlowBuilderContext {
|
||||
*/
|
||||
public ExpressionParser getExpressionParser();
|
||||
|
||||
/**
|
||||
* Returns the Validator instance to use for validating a model.
|
||||
* @return the validator
|
||||
*/
|
||||
public Validator getValidator();
|
||||
|
||||
/**
|
||||
* Returns the application context hosting the flow system.
|
||||
* @return the application context
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.webflow.engine.builder;
|
||||
import org.springframework.binding.convert.ConversionService;
|
||||
import org.springframework.binding.expression.Expression;
|
||||
import org.springframework.binding.expression.ExpressionParser;
|
||||
import org.springframework.validation.Validator;
|
||||
import org.springframework.webflow.execution.View;
|
||||
import org.springframework.webflow.execution.ViewFactory;
|
||||
|
||||
@@ -34,10 +35,11 @@ public interface ViewFactoryCreator {
|
||||
* @param expressionParser an optional expression parser to use to resolve view expressions
|
||||
* @param conversionService an optional conversion service to use to format text values
|
||||
* @param binderConfiguration information on how the rendered view binds to a model that provides its data
|
||||
* @param validator a global validator to invoke
|
||||
* @return the view factory
|
||||
*/
|
||||
public ViewFactory createViewFactory(Expression viewId, ExpressionParser expressionParser,
|
||||
ConversionService conversionService, BinderConfiguration binderConfiguration);
|
||||
ConversionService conversionService, BinderConfiguration binderConfiguration, Validator validator);
|
||||
|
||||
/**
|
||||
* Get the default id of the view to render in the provided view state by convention.
|
||||
|
||||
@@ -68,9 +68,9 @@ import org.springframework.webflow.engine.TransitionCriteria;
|
||||
import org.springframework.webflow.engine.VariableValueFactory;
|
||||
import org.springframework.webflow.engine.ViewVariable;
|
||||
import org.springframework.webflow.engine.builder.BinderConfiguration;
|
||||
import org.springframework.webflow.engine.builder.BinderConfiguration.Binding;
|
||||
import org.springframework.webflow.engine.builder.FlowBuilderContext;
|
||||
import org.springframework.webflow.engine.builder.FlowBuilderException;
|
||||
import org.springframework.webflow.engine.builder.BinderConfiguration.Binding;
|
||||
import org.springframework.webflow.engine.builder.support.AbstractFlowBuilder;
|
||||
import org.springframework.webflow.engine.model.AbstractActionModel;
|
||||
import org.springframework.webflow.engine.model.AbstractMappingModel;
|
||||
@@ -372,8 +372,8 @@ public class FlowModelFlowBuilder extends AbstractFlowBuilder {
|
||||
if (isFlowInDevelopment()) {
|
||||
builder.addPropertyValue("cacheSeconds", "0");
|
||||
}
|
||||
flowContext.registerBeanDefinition(AbstractApplicationContext.MESSAGE_SOURCE_BEAN_NAME, builder
|
||||
.getBeanDefinition());
|
||||
flowContext.registerBeanDefinition(AbstractApplicationContext.MESSAGE_SOURCE_BEAN_NAME,
|
||||
builder.getBeanDefinition());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -537,8 +537,10 @@ public class FlowModelFlowBuilder extends AbstractFlowBuilder {
|
||||
}
|
||||
MutableAttributeMap attributes = parseMetaAttributes(state.getAttributes());
|
||||
if (state.getModel() != null) {
|
||||
attributes.put("model", getLocalContext().getExpressionParser().parseExpression(state.getModel(),
|
||||
new FluentParserContext().evaluate(RequestContext.class)));
|
||||
attributes.put(
|
||||
"model",
|
||||
getLocalContext().getExpressionParser().parseExpression(state.getModel(),
|
||||
new FluentParserContext().evaluate(RequestContext.class)));
|
||||
}
|
||||
parseAndPutSecured(state.getSecured(), attributes);
|
||||
getLocalContext().getFlowArtifactFactory().createViewState(state.getId(), flow,
|
||||
@@ -626,7 +628,8 @@ public class FlowModelFlowBuilder extends AbstractFlowBuilder {
|
||||
private ViewFactory createViewFactory(Expression viewId, BinderModel binderModel) {
|
||||
BinderConfiguration binderConfiguration = createBinderConfiguration(binderModel);
|
||||
return getLocalContext().getViewFactoryCreator().createViewFactory(viewId,
|
||||
getLocalContext().getExpressionParser(), getLocalContext().getConversionService(), binderConfiguration);
|
||||
getLocalContext().getExpressionParser(), getLocalContext().getConversionService(), binderConfiguration,
|
||||
getLocalContext().getValidator());
|
||||
}
|
||||
|
||||
private BinderConfiguration createBinderConfiguration(BinderModel binderModel) {
|
||||
@@ -868,8 +871,8 @@ public class FlowModelFlowBuilder extends AbstractFlowBuilder {
|
||||
private Action parseRenderAction(RenderModel render) {
|
||||
String[] fragmentExpressionStrings = StringUtils.commaDelimitedListToStringArray(render.getFragments());
|
||||
fragmentExpressionStrings = StringUtils.trimArrayElements(fragmentExpressionStrings);
|
||||
ParserContext context = new FluentParserContext().template().evaluate(RequestContext.class).expectResult(
|
||||
String.class);
|
||||
ParserContext context = new FluentParserContext().template().evaluate(RequestContext.class)
|
||||
.expectResult(String.class);
|
||||
Expression[] fragments = new Expression[fragmentExpressionStrings.length];
|
||||
for (int i = 0; i < fragmentExpressionStrings.length; i++) {
|
||||
String fragment = fragmentExpressionStrings[i];
|
||||
|
||||
@@ -19,6 +19,7 @@ import org.springframework.binding.convert.ConversionService;
|
||||
import org.springframework.binding.expression.ExpressionParser;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.validation.Validator;
|
||||
import org.springframework.webflow.core.collection.AttributeMap;
|
||||
import org.springframework.webflow.definition.registry.FlowDefinitionLocator;
|
||||
import org.springframework.webflow.engine.builder.FlowArtifactFactory;
|
||||
@@ -55,7 +56,7 @@ class LocalFlowBuilderContext implements FlowBuilderContext {
|
||||
|
||||
public FlowDefinitionLocator getFlowDefinitionLocator() {
|
||||
if (localFlowContext.containsLocalBean("flowRegistry")) {
|
||||
return (FlowDefinitionLocator) localFlowContext.getBean("flowRegistry", FlowDefinitionLocator.class);
|
||||
return localFlowContext.getBean("flowRegistry", FlowDefinitionLocator.class);
|
||||
} else {
|
||||
return parent.getFlowDefinitionLocator();
|
||||
}
|
||||
@@ -63,7 +64,7 @@ class LocalFlowBuilderContext implements FlowBuilderContext {
|
||||
|
||||
public FlowArtifactFactory getFlowArtifactFactory() {
|
||||
if (localFlowContext.containsLocalBean("flowArtifactFactory")) {
|
||||
return (FlowArtifactFactory) localFlowContext.getBean("flowArtifactFactory", FlowArtifactFactory.class);
|
||||
return localFlowContext.getBean("flowArtifactFactory", FlowArtifactFactory.class);
|
||||
} else {
|
||||
return parent.getFlowArtifactFactory();
|
||||
}
|
||||
@@ -71,7 +72,7 @@ class LocalFlowBuilderContext implements FlowBuilderContext {
|
||||
|
||||
public ConversionService getConversionService() {
|
||||
if (localFlowContext.containsLocalBean("conversionService")) {
|
||||
return (ConversionService) localFlowContext.getBean("conversionService", ConversionService.class);
|
||||
return localFlowContext.getBean("conversionService", ConversionService.class);
|
||||
} else {
|
||||
return parent.getConversionService();
|
||||
}
|
||||
@@ -79,7 +80,7 @@ class LocalFlowBuilderContext implements FlowBuilderContext {
|
||||
|
||||
public ViewFactoryCreator getViewFactoryCreator() {
|
||||
if (localFlowContext.containsLocalBean("viewFactoryCreator")) {
|
||||
return (ViewFactoryCreator) localFlowContext.getBean("viewFactoryCreator", ViewFactoryCreator.class);
|
||||
return localFlowContext.getBean("viewFactoryCreator", ViewFactoryCreator.class);
|
||||
} else {
|
||||
return parent.getViewFactoryCreator();
|
||||
}
|
||||
@@ -87,10 +88,18 @@ class LocalFlowBuilderContext implements FlowBuilderContext {
|
||||
|
||||
public ExpressionParser getExpressionParser() {
|
||||
if (localFlowContext.containsLocalBean("expressionParser")) {
|
||||
return (ExpressionParser) localFlowContext.getBean("expressionParser", ExpressionParser.class);
|
||||
return localFlowContext.getBean("expressionParser", ExpressionParser.class);
|
||||
} else {
|
||||
return parent.getExpressionParser();
|
||||
}
|
||||
}
|
||||
|
||||
public Validator getValidator() {
|
||||
if (localFlowContext.containsLocalBean("validator")) {
|
||||
return localFlowContext.getBean("validator", Validator.class);
|
||||
} else {
|
||||
return parent.getValidator();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,6 +24,7 @@ import org.springframework.binding.convert.service.GenericConversionService;
|
||||
import org.springframework.binding.expression.ExpressionParser;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.validation.Validator;
|
||||
import org.springframework.webflow.core.collection.AttributeMap;
|
||||
import org.springframework.webflow.core.collection.CollectionUtils;
|
||||
import org.springframework.webflow.definition.registry.FlowDefinitionLocator;
|
||||
@@ -104,6 +105,10 @@ public class FlowBuilderContextImpl implements FlowBuilderContext {
|
||||
return flowBuilderServices.getApplicationContext();
|
||||
}
|
||||
|
||||
public Validator getValidator() {
|
||||
return flowBuilderServices.getValidator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method that creates the conversion service the flow builder will use. Subclasses may override. The
|
||||
* default implementation registers Web Flow-specific converters thought to be useful for most builder
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.springframework.binding.expression.ExpressionParser;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.validation.Validator;
|
||||
import org.springframework.webflow.engine.Flow;
|
||||
import org.springframework.webflow.engine.State;
|
||||
import org.springframework.webflow.engine.builder.FlowArtifactFactory;
|
||||
@@ -65,6 +66,12 @@ public class FlowBuilderServices implements ApplicationContextAware, Initializin
|
||||
*/
|
||||
private ExpressionParser expressionParser;
|
||||
|
||||
/**
|
||||
* A Validator instance to use for validating a model declared on a view state. A JSR-303 validation adapter is
|
||||
* installed by default if a JSR-303 provider is present on the classpath.
|
||||
*/
|
||||
private Validator validator;
|
||||
|
||||
/**
|
||||
* The Spring application context that provides access to the services of the application.
|
||||
*/
|
||||
@@ -107,6 +114,14 @@ public class FlowBuilderServices implements ApplicationContextAware, Initializin
|
||||
this.expressionParser = expressionParser;
|
||||
}
|
||||
|
||||
public Validator getValidator() {
|
||||
return validator;
|
||||
}
|
||||
|
||||
public void setValidator(Validator validator) {
|
||||
this.validator = validator;
|
||||
}
|
||||
|
||||
public boolean getDevelopment() {
|
||||
return development;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.validation.DefaultMessageCodesResolver;
|
||||
import org.springframework.validation.MessageCodesResolver;
|
||||
import org.springframework.validation.Validator;
|
||||
import org.springframework.web.servlet.View;
|
||||
import org.springframework.web.servlet.ViewResolver;
|
||||
import org.springframework.webflow.engine.builder.BinderConfiguration;
|
||||
@@ -169,7 +170,7 @@ public class MvcViewFactoryCreator implements ViewFactoryCreator, ApplicationCon
|
||||
}
|
||||
|
||||
public ViewFactory createViewFactory(Expression viewId, ExpressionParser expressionParser,
|
||||
ConversionService conversionService, BinderConfiguration binderConfiguration) {
|
||||
ConversionService conversionService, BinderConfiguration binderConfiguration, Validator validator) {
|
||||
if (useSpringBeanBinding) {
|
||||
expressionParser = new BeanWrapperExpressionParser(conversionService);
|
||||
}
|
||||
@@ -181,6 +182,7 @@ public class MvcViewFactoryCreator implements ViewFactoryCreator, ApplicationCon
|
||||
if (StringUtils.hasText(fieldMarkerPrefix)) {
|
||||
viewFactory.setFieldMarkerPrefix(fieldMarkerPrefix);
|
||||
}
|
||||
viewFactory.setValidator(validator);
|
||||
return viewFactory;
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ import org.springframework.core.style.ToStringCreator;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.validation.MessageCodesResolver;
|
||||
import org.springframework.validation.Validator;
|
||||
import org.springframework.web.util.WebUtils;
|
||||
import org.springframework.webflow.core.collection.AttributeMap;
|
||||
import org.springframework.webflow.core.collection.ParameterMap;
|
||||
@@ -78,6 +79,8 @@ public abstract class AbstractMvcView implements View {
|
||||
|
||||
private ConversionService conversionService;
|
||||
|
||||
private Validator validator;
|
||||
|
||||
private String fieldMarkerPrefix = "_";
|
||||
|
||||
private String eventIdParameterName = "_eventId";
|
||||
@@ -118,6 +121,10 @@ public abstract class AbstractMvcView implements View {
|
||||
this.conversionService = conversionService;
|
||||
}
|
||||
|
||||
public void setValidator(Validator validator) {
|
||||
this.validator = validator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the configuration describing how this view should bind to its model to access data for rendering.
|
||||
* @param binderConfiguration the model binder configuration
|
||||
@@ -534,12 +541,12 @@ public abstract class AbstractMvcView implements View {
|
||||
|
||||
private Map flowScopes() {
|
||||
if (requestContext.getCurrentState().isViewState()) {
|
||||
return requestContext.getConversationScope().union(requestContext.getFlowScope()).union(
|
||||
requestContext.getViewScope()).union(requestContext.getFlashScope()).union(
|
||||
requestContext.getRequestScope()).asMap();
|
||||
return requestContext.getConversationScope().union(requestContext.getFlowScope())
|
||||
.union(requestContext.getViewScope()).union(requestContext.getFlashScope())
|
||||
.union(requestContext.getRequestScope()).asMap();
|
||||
} else {
|
||||
return requestContext.getConversationScope().union(requestContext.getFlowScope()).union(
|
||||
requestContext.getFlashScope()).union(requestContext.getRequestScope()).asMap();
|
||||
return requestContext.getConversationScope().union(requestContext.getFlowScope())
|
||||
.union(requestContext.getFlashScope()).union(requestContext.getRequestScope()).asMap();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -605,8 +612,8 @@ public abstract class AbstractMvcView implements View {
|
||||
String field = error.getMapping().getTargetExpression().getExpressionString();
|
||||
Class fieldType = error.getMapping().getTargetExpression().getValueType(getModelObject());
|
||||
String[] messageCodes = messageCodesResolver.resolveMessageCodes(error.getCode(), model, field, fieldType);
|
||||
return new MessageBuilder().error().source(field).codes(messageCodes).resolvableArg(field).defaultText(
|
||||
error.getCode() + " on " + field).build();
|
||||
return new MessageBuilder().error().source(field).codes(messageCodes).resolvableArg(field)
|
||||
.defaultText(error.getCode() + " on " + field).build();
|
||||
}
|
||||
|
||||
private Boolean getValidateAttribute(TransitionDefinition transition) {
|
||||
@@ -621,8 +628,10 @@ public abstract class AbstractMvcView implements View {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Validating model");
|
||||
}
|
||||
new ValidationHelper(model, requestContext, eventId, getModelExpression().getExpressionString(),
|
||||
expressionParser, messageCodesResolver, mappingResults).validate();
|
||||
ValidationHelper helper = new ValidationHelper(model, requestContext, eventId, getModelExpression()
|
||||
.getExpressionString(), expressionParser, messageCodesResolver, mappingResults);
|
||||
helper.setValidator(validator);
|
||||
helper.validate();
|
||||
}
|
||||
|
||||
private static class PropertyNotFoundError implements MappingResultsCriteria {
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.springframework.binding.expression.Expression;
|
||||
import org.springframework.binding.expression.ExpressionParser;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.validation.MessageCodesResolver;
|
||||
import org.springframework.validation.Validator;
|
||||
import org.springframework.webflow.engine.builder.BinderConfiguration;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.View;
|
||||
@@ -40,6 +41,8 @@ public abstract class AbstractMvcViewFactory implements ViewFactory {
|
||||
|
||||
private ConversionService conversionService;
|
||||
|
||||
private Validator validator;
|
||||
|
||||
private BinderConfiguration binderConfiguration;
|
||||
|
||||
private String eventIdParameterName;
|
||||
@@ -75,6 +78,10 @@ public abstract class AbstractMvcViewFactory implements ViewFactory {
|
||||
this.fieldMarkerPrefix = fieldMarkerPrefix;
|
||||
}
|
||||
|
||||
public void setValidator(Validator validator) {
|
||||
this.validator = validator;
|
||||
}
|
||||
|
||||
public View getView(RequestContext context) {
|
||||
String viewId = (String) this.viewId.getValue(context);
|
||||
org.springframework.web.servlet.View view = viewResolver.resolveView(viewId, context);
|
||||
@@ -83,6 +90,7 @@ public abstract class AbstractMvcViewFactory implements ViewFactory {
|
||||
mvcView.setConversionService(conversionService);
|
||||
mvcView.setBinderConfiguration(binderConfiguration);
|
||||
mvcView.setMessageCodesResolver(messageCodesResolver);
|
||||
mvcView.setValidator(validator);
|
||||
if (StringUtils.hasText(eventIdParameterName)) {
|
||||
mvcView.setEventIdParameterName(eventIdParameterName);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.springframework.binding.convert.ConversionService;
|
||||
import org.springframework.binding.expression.Expression;
|
||||
import org.springframework.binding.expression.ExpressionParser;
|
||||
import org.springframework.core.style.ToStringCreator;
|
||||
import org.springframework.validation.Validator;
|
||||
import org.springframework.webflow.engine.builder.BinderConfiguration;
|
||||
import org.springframework.webflow.engine.builder.ViewFactoryCreator;
|
||||
import org.springframework.webflow.execution.Event;
|
||||
@@ -38,7 +39,7 @@ import org.springframework.webflow.execution.ViewFactory;
|
||||
class MockViewFactoryCreator implements ViewFactoryCreator {
|
||||
|
||||
public ViewFactory createViewFactory(Expression viewId, ExpressionParser expressionParser,
|
||||
ConversionService conversionService, BinderConfiguration binderConfiguration) {
|
||||
ConversionService conversionService, BinderConfiguration binderConfiguration, Validator validator) {
|
||||
return new MockViewFactory(viewId);
|
||||
}
|
||||
|
||||
|
||||
@@ -64,6 +64,8 @@ public class ValidationHelper {
|
||||
|
||||
private final MappingResults mappingResults;
|
||||
|
||||
private Validator validator;
|
||||
|
||||
/**
|
||||
* Create a throwaway validation helper object. Validation is invoked by the {@link #validate()} method.
|
||||
* <p>
|
||||
@@ -94,14 +96,24 @@ public class ValidationHelper {
|
||||
this.mappingResults = mappingResults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure a {@link Validator} to apply to the model.
|
||||
*/
|
||||
public void setValidator(Validator validator) {
|
||||
this.validator = validator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke the validators available by convention.
|
||||
*/
|
||||
public void validate() {
|
||||
if (this.validator != null) {
|
||||
invokeValidatorDefaultValidateMethod(model, this.validator);
|
||||
}
|
||||
invokeModelValidationMethod(model);
|
||||
Object validator = getModelValidator();
|
||||
if (validator != null) {
|
||||
invokeModelValidator(model, validator);
|
||||
Object modelValidator = getModelValidator();
|
||||
if (modelValidator != null) {
|
||||
invokeModelValidator(model, modelValidator);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,8 +227,8 @@ public class ValidationHelper {
|
||||
// web flow 2.0.0 to 2.0.3 compatibility only [to remove in web flow 3]
|
||||
validateMethod = findValidationMethod(model, validator, methodName, MessageContext.class);
|
||||
if (validateMethod != null) {
|
||||
ReflectionUtils.invokeMethod(validateMethod, validator, new Object[] { model,
|
||||
requestContext.getMessageContext() });
|
||||
ReflectionUtils.invokeMethod(validateMethod, validator,
|
||||
new Object[] { model, requestContext.getMessageContext() });
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -224,13 +236,21 @@ public class ValidationHelper {
|
||||
|
||||
private boolean invokeValidatorDefaultValidateMethod(Object model, Object validator) {
|
||||
if (validator instanceof Validator) {
|
||||
// supports existing validators
|
||||
// Spring Framework Validator type
|
||||
Validator springValidator = (Validator) validator;
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Invoking Spring Validator '" + ClassUtils.getShortName(validator.getClass()) + "'");
|
||||
}
|
||||
MessageContextErrors errors = new MessageContextErrors(requestContext.getMessageContext(), modelName,
|
||||
model, expressionParser, messageCodesResolver, mappingResults);
|
||||
((Validator) validator).validate(model, errors);
|
||||
if (springValidator.supports(model.getClass())) {
|
||||
MessageContextErrors errors = new MessageContextErrors(requestContext.getMessageContext(), modelName,
|
||||
model, expressionParser, messageCodesResolver, mappingResults);
|
||||
springValidator.validate(model, errors);
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Spring Validator '" + ClassUtils.getShortName(validator.getClass())
|
||||
+ "' doesn't support model class " + model.getClass());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// preferred
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
http\://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd=org/springframework/webflow/config/spring-webflow-config-2.0.xsd
|
||||
http\://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd=org/springframework/webflow/config/spring-webflow-config-2.0.xsd
|
||||
http\://www.springframework.org/schema/webflow-config/spring-webflow-config-2.3.xsd=org/springframework/webflow/config/spring-webflow-config-2.3.xsd
|
||||
http\://www.springframework.org/schema/webflow-config/spring-webflow-config.xsd=org/springframework/webflow/config/spring-webflow-config-2.3.xsd
|
||||
@@ -0,0 +1,15 @@
|
||||
package org.springframework.webflow.config;
|
||||
|
||||
import org.springframework.validation.Errors;
|
||||
import org.springframework.validation.Validator;
|
||||
|
||||
public class EmptySpringValidator implements Validator {
|
||||
|
||||
public boolean supports(Class<?> clazz) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void validate(Object target, Errors errors) {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import org.springframework.binding.expression.Expression;
|
||||
import org.springframework.binding.expression.ExpressionParser;
|
||||
import org.springframework.binding.expression.spel.SpringELExpressionParser;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.validation.Validator;
|
||||
import org.springframework.webflow.engine.builder.BinderConfiguration;
|
||||
import org.springframework.webflow.engine.builder.ViewFactoryCreator;
|
||||
import org.springframework.webflow.engine.builder.support.FlowBuilderServices;
|
||||
@@ -35,6 +36,7 @@ public class FlowBuilderServicesBeanDefinitionParserTests extends TestCase {
|
||||
assertTrue(builderServices.getExpressionParser() instanceof SpringELExpressionParser);
|
||||
assertTrue(builderServices.getViewFactoryCreator() instanceof MvcViewFactoryCreator);
|
||||
assertTrue(builderServices.getConversionService() instanceof DefaultConversionService);
|
||||
assertNull(builderServices.getValidator());
|
||||
assertFalse(builderServices.getDevelopment());
|
||||
}
|
||||
|
||||
@@ -44,6 +46,7 @@ public class FlowBuilderServicesBeanDefinitionParserTests extends TestCase {
|
||||
assertTrue(builderServices.getExpressionParser() instanceof SpringELExpressionParser);
|
||||
assertTrue(builderServices.getViewFactoryCreator() instanceof TestViewFactoryCreator);
|
||||
assertTrue(builderServices.getConversionService() instanceof TestConversionService);
|
||||
assertTrue(builderServices.getValidator() instanceof EmptySpringValidator);
|
||||
assertTrue(builderServices.getDevelopment());
|
||||
}
|
||||
|
||||
@@ -54,13 +57,14 @@ public class FlowBuilderServicesBeanDefinitionParserTests extends TestCase {
|
||||
assertTrue(builderServices.getExpressionParser() instanceof SpringELExpressionParser);
|
||||
assertTrue(((SpringELExpressionParser) builderServices.getExpressionParser()).getConversionService() instanceof TestConversionService);
|
||||
assertTrue(builderServices.getViewFactoryCreator() instanceof MvcViewFactoryCreator);
|
||||
assertNull(builderServices.getValidator());
|
||||
assertFalse(builderServices.getDevelopment());
|
||||
}
|
||||
|
||||
public static class TestViewFactoryCreator implements ViewFactoryCreator {
|
||||
|
||||
public ViewFactory createViewFactory(Expression viewIdExpression, ExpressionParser expressionParser,
|
||||
ConversionService conversionService, BinderConfiguration binderConfiguration) {
|
||||
ConversionService conversionService, BinderConfiguration binderConfiguration, Validator validator) {
|
||||
throw new UnsupportedOperationException("Auto-generated method stub");
|
||||
}
|
||||
|
||||
|
||||
@@ -4,16 +4,18 @@
|
||||
xmlns:webflow="http://www.springframework.org/schema/webflow-config"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/webflow-config
|
||||
http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd">
|
||||
http://www.springframework.org/schema/webflow-config/spring-webflow-config.xsd">
|
||||
|
||||
<webflow:flow-builder-services id="flowBuilderServicesDefault"/>
|
||||
|
||||
<webflow:flow-builder-services id="flowBuilderServicesAllCustom"
|
||||
expression-parser="customExpressionParser"
|
||||
view-factory-creator="customViewFactoryCreator"
|
||||
conversion-service="customConversionService" development="true" />
|
||||
conversion-service="customConversionService"
|
||||
validator="customValidator"
|
||||
development="true" />
|
||||
|
||||
<webflow:flow-builder-services id="flowBuilderServicesConversionServiceCustom"
|
||||
conversion-service="customConversionService" />
|
||||
@@ -28,4 +30,6 @@
|
||||
|
||||
<bean id="customConversionService" class="org.springframework.webflow.config.FlowBuilderServicesBeanDefinitionParserTests$TestConversionService"/>
|
||||
|
||||
<bean id="customValidator" class="org.springframework.webflow.config.EmptySpringValidator" />
|
||||
|
||||
</beans>
|
||||
@@ -4,9 +4,9 @@
|
||||
xmlns:webflow="http://www.springframework.org/schema/webflow-config"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/webflow-config
|
||||
http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd">
|
||||
http://www.springframework.org/schema/webflow-config/spring-webflow-config.xsd">
|
||||
|
||||
<webflow:flow-executor id="flowExecutor" flow-registry="flowRegistry">
|
||||
<webflow:flow-execution-repository max-executions="1" max-execution-snapshots="2"/>
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
xmlns:webflow="http://www.springframework.org/schema/webflow-config"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/webflow-config
|
||||
http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd">
|
||||
http://www.springframework.org/schema/webflow-config/spring-webflow-config.xsd">
|
||||
|
||||
<webflow:flow-registry id="flowRegistry" parent="parentRegistry">
|
||||
<webflow:flow-location id="flow" path="org/springframework/webflow/config/flow.xml">
|
||||
|
||||
Reference in New Issue
Block a user