diff --git a/spring-faces/src/main/java/org/springframework/faces/config/spring-faces-2.0.xsd b/spring-faces/src/main/java/org/springframework/faces/config/spring-faces-2.0.xsd index 02d1f3dc..445d1b06 100644 --- a/spring-faces/src/main/java/org/springframework/faces/config/spring-faces-2.0.xsd +++ b/spring-faces/src/main/java/org/springframework/faces/config/spring-faces-2.0.xsd @@ -73,25 +73,4 @@ When set to true, changes to a flow definition will be auto-detected and will re - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-faces/src/main/java/org/springframework/faces/config/spring-faces-2.2.xsd b/spring-faces/src/main/java/org/springframework/faces/config/spring-faces-2.2.xsd new file mode 100644 index 00000000..7955a2be --- /dev/null +++ b/spring-faces/src/main/java/org/springframework/faces/config/spring-faces-2.2.xsd @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfFlowHandlerAdapter.java b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfFlowHandlerAdapter.java index 658e60c5..18e368d7 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfFlowHandlerAdapter.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfFlowHandlerAdapter.java @@ -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); + } + } diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfViewFactoryCreator.java b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfViewFactoryCreator.java index 74c75961..2b4d9abf 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfViewFactoryCreator.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfViewFactoryCreator.java @@ -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()); } diff --git a/spring-faces/src/main/resources/META-INF/spring.schemas b/spring-faces/src/main/resources/META-INF/spring.schemas index b8044e12..a66c262c 100644 --- a/spring-faces/src/main/resources/META-INF/spring.schemas +++ b/spring-faces/src/main/resources/META-INF/spring.schemas @@ -1 +1,3 @@ -http\://www.springframework.org/schema/faces/spring-faces-2.0.xsd=org/springframework/faces/config/spring-faces-2.0.xsd \ No newline at end of file +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 \ No newline at end of file diff --git a/spring-faces/src/test/java/org/springframework/faces/config/FacesFlowBuilderServicesBeanDefinitionParserTests.java b/spring-faces/src/test/java/org/springframework/faces/config/FacesFlowBuilderServicesBeanDefinitionParserTests.java index 0205c536..44715ad7 100644 --- a/spring-faces/src/test/java/org/springframework/faces/config/FacesFlowBuilderServicesBeanDefinitionParserTests.java +++ b/spring-faces/src/test/java/org/springframework/faces/config/FacesFlowBuilderServicesBeanDefinitionParserTests.java @@ -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"); } diff --git a/spring-faces/src/test/java/org/springframework/faces/config/flow-builder-services.xml b/spring-faces/src/test/java/org/springframework/faces/config/flow-builder-services.xml index 9b556c63..c83ee6a8 100644 --- a/spring-faces/src/test/java/org/springframework/faces/config/flow-builder-services.xml +++ b/spring-faces/src/test/java/org/springframework/faces/config/flow-builder-services.xml @@ -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"> diff --git a/spring-faces/src/test/java/org/springframework/faces/config/resources.xml b/spring-faces/src/test/java/org/springframework/faces/config/resources.xml index 6a76e24b..a4b3fa17 100644 --- a/spring-faces/src/test/java/org/springframework/faces/config/resources.xml +++ b/spring-faces/src/test/java/org/springframework/faces/config/resources.xml @@ -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"> diff --git a/spring-webflow-samples/booking-faces/ivy.xml b/spring-webflow-samples/booking-faces/ivy.xml index db613820..fdfe212b 100755 --- a/spring-webflow-samples/booking-faces/ivy.xml +++ b/spring-webflow-samples/booking-faces/ivy.xml @@ -21,12 +21,12 @@ - + diff --git a/spring-webflow-samples/booking-faces/src/main/java/org/springframework/webflow/samples/booking/Booking.java b/spring-webflow-samples/booking-faces/src/main/java/org/springframework/webflow/samples/booking/Booking.java index 6a119e70..5bbc7f06 100755 --- a/spring-webflow-samples/booking-faces/src/main/java/org/springframework/webflow/samples/booking/Booking.java +++ b/spring-webflow-samples/booking-faces/src/main/java/org/springframework/webflow/samples/booking/Booking.java @@ -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()); } } diff --git a/spring-webflow-samples/booking-faces/src/main/resources/ValidationMessages.properties b/spring-webflow-samples/booking-faces/src/main/resources/ValidationMessages.properties new file mode 100644 index 00000000..0909702d --- /dev/null +++ b/spring-webflow-samples/booking-faces/src/main/resources/ValidationMessages.properties @@ -0,0 +1,2 @@ +# Custom messages for JSR-303 validation +invalidCreditCardPattern=is not a valid 16 digit card number. diff --git a/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/config/data-access-config.xml b/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/config/data-access-config.xml index 21e7f227..34de9412 100644 --- a/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/config/data-access-config.xml +++ b/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/config/data-access-config.xml @@ -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"> diff --git a/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/config/security-config.xml b/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/config/security-config.xml index e0433c15..22095f5a 100644 --- a/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/config/security-config.xml +++ b/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/config/security-config.xml @@ -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"> diff --git a/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/config/web-application-config.xml b/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/config/web-application-config.xml index f84d76bb..02cfdcde 100644 --- a/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/config/web-application-config.xml +++ b/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/config/web-application-config.xml @@ -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"> diff --git a/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/config/webflow-config.xml b/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/config/webflow-config.xml index 91474860..6948bc17 100644 --- a/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/config/webflow-config.xml +++ b/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/config/webflow-config.xml @@ -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"> - + diff --git a/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/config/webmvc-config.xml b/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/config/webmvc-config.xml index 9e0de203..4d1ec049 100644 --- a/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/config/webmvc-config.xml +++ b/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/config/webmvc-config.xml @@ -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"> diff --git a/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/flows/main/enterSearchCriteria.xhtml b/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/flows/main/enterSearchCriteria.xhtml index 346c3914..4faffdce 100644 --- a/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/flows/main/enterSearchCriteria.xhtml +++ b/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/flows/main/enterSearchCriteria.xhtml @@ -27,7 +27,7 @@ - + diff --git a/spring-webflow-samples/booking-mvc/ivy.xml b/spring-webflow-samples/booking-mvc/ivy.xml index 8fadaf96..9ba51901 100755 --- a/spring-webflow-samples/booking-mvc/ivy.xml +++ b/spring-webflow-samples/booking-mvc/ivy.xml @@ -26,6 +26,7 @@ + @@ -35,8 +36,10 @@ + + diff --git a/spring-webflow-samples/booking-mvc/pom.xml b/spring-webflow-samples/booking-mvc/pom.xml index be0f9a64..8fefcae2 100644 --- a/spring-webflow-samples/booking-mvc/pom.xml +++ b/spring-webflow-samples/booking-mvc/pom.xml @@ -157,6 +157,27 @@ org.springframework.webflow ${project.version} + + + org.hibernate + com.springsource.org.hibernate.validator + 4.1.0.GA + + + org.slf4j + com.springsource.slf4j.log4j + 1.5.6 + + + + javax.xml.bind + com.springsource.javax.xml.bind + 2.2.0 + javax.servlet diff --git a/spring-webflow-samples/booking-mvc/src/main/java/org/springframework/webflow/samples/booking/Booking.java b/spring-webflow-samples/booking-mvc/src/main/java/org/springframework/webflow/samples/booking/Booking.java index 05b60da9..b25931c7 100755 --- a/spring-webflow-samples/booking-mvc/src/main/java/org/springframework/webflow/samples/booking/Booking.java +++ b/spring-webflow-samples/booking-mvc/src/main/java/org/springframework/webflow/samples/booking/Booking.java @@ -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); diff --git a/spring-webflow-samples/booking-mvc/src/main/java/org/springframework/webflow/samples/booking/BookingDateRange.java b/spring-webflow-samples/booking-mvc/src/main/java/org/springframework/webflow/samples/booking/BookingDateRange.java new file mode 100644 index 00000000..a5cad188 --- /dev/null +++ b/spring-webflow-samples/booking-mvc/src/main/java/org/springframework/webflow/samples/booking/BookingDateRange.java @@ -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[] payload() default {}; + +} diff --git a/spring-webflow-samples/booking-mvc/src/main/java/org/springframework/webflow/samples/booking/BookingDateRangeValidator.java b/spring-webflow-samples/booking-mvc/src/main/java/org/springframework/webflow/samples/booking/BookingDateRangeValidator.java new file mode 100644 index 00000000..716a40bc --- /dev/null +++ b/spring-webflow-samples/booking-mvc/src/main/java/org/springframework/webflow/samples/booking/BookingDateRangeValidator.java @@ -0,0 +1,19 @@ +package org.springframework.webflow.samples.booking; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; + +public class BookingDateRangeValidator implements ConstraintValidator { + + 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; + } + +} diff --git a/spring-webflow-samples/booking-mvc/src/main/webapp/WEB-INF/config/data-access-config.xml b/spring-webflow-samples/booking-mvc/src/main/webapp/WEB-INF/config/data-access-config.xml index 21e7f227..fd08d966 100644 --- a/spring-webflow-samples/booking-mvc/src/main/webapp/WEB-INF/config/data-access-config.xml +++ b/spring-webflow-samples/booking-mvc/src/main/webapp/WEB-INF/config/data-access-config.xml @@ -21,9 +21,14 @@ + + + + hibernate.session_factory_name=mySessionFactory + - - + + diff --git a/spring-webflow-samples/booking-mvc/src/main/webapp/WEB-INF/config/webflow-config.xml b/spring-webflow-samples/booking-mvc/src/main/webapp/WEB-INF/config/webflow-config.xml index d6dfa19f..c2b32d89 100644 --- a/spring-webflow-samples/booking-mvc/src/main/webapp/WEB-INF/config/webflow-config.xml +++ b/spring-webflow-samples/booking-mvc/src/main/webapp/WEB-INF/config/webflow-config.xml @@ -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"> @@ -22,7 +22,8 @@ - + @@ -38,5 +39,8 @@ + + + \ No newline at end of file diff --git a/spring-webflow-samples/booking-mvc/src/main/webapp/WEB-INF/hotels/booking/booking-flow.xml b/spring-webflow-samples/booking-mvc/src/main/webapp/WEB-INF/hotels/booking/booking-flow.xml index c80c7ec1..e3b3abaf 100644 --- a/spring-webflow-samples/booking-mvc/src/main/webapp/WEB-INF/hotels/booking/booking-flow.xml +++ b/spring-webflow-samples/booking-mvc/src/main/webapp/WEB-INF/hotels/booking/booking-flow.xml @@ -15,15 +15,15 @@ - - - - - - - - - + + + + + + + + + diff --git a/spring-webflow-samples/booking-mvc/src/main/webapp/WEB-INF/hotels/booking/enterBookingDetails.jsp b/spring-webflow-samples/booking-mvc/src/main/webapp/WEB-INF/hotels/booking/enterBookingDetails.jsp index a8abff97..4416b2b0 100644 --- a/spring-webflow-samples/booking-mvc/src/main/webapp/WEB-INF/hotels/booking/enterBookingDetails.jsp +++ b/spring-webflow-samples/booking-mvc/src/main/webapp/WEB-INF/hotels/booking/enterBookingDetails.jsp @@ -22,7 +22,7 @@
-
+
diff --git a/spring-webflow-samples/booking-mvc/src/main/webapp/WEB-INF/hotels/booking/messages.properties b/spring-webflow-samples/booking-mvc/src/main/webapp/WEB-INF/hotels/booking/messages.properties index 1859927a..3d15709e 100644 --- a/spring-webflow-samples/booking-mvc/src/main/webapp/WEB-INF/hotels/booking/messages.properties +++ b/spring-webflow-samples/booking-mvc/src/main/webapp/WEB-INF/hotels/booking/messages.properties @@ -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 \ No newline at end of file diff --git a/spring-webflow-samples/booking-portlet-faces/src/main/webapp/WEB-INF/config/hotelbooking-portlet-config.xml b/spring-webflow-samples/booking-portlet-faces/src/main/webapp/WEB-INF/config/hotelbooking-portlet-config.xml index ba4a43d6..970be7e3 100644 --- a/spring-webflow-samples/booking-portlet-faces/src/main/webapp/WEB-INF/config/hotelbooking-portlet-config.xml +++ b/spring-webflow-samples/booking-portlet-faces/src/main/webapp/WEB-INF/config/hotelbooking-portlet-config.xml @@ -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"> diff --git a/spring-webflow-samples/booking-portlet-mvc/ivy.xml b/spring-webflow-samples/booking-portlet-mvc/ivy.xml index baa0c1a8..9373eb7f 100644 --- a/spring-webflow-samples/booking-portlet-mvc/ivy.xml +++ b/spring-webflow-samples/booking-portlet-mvc/ivy.xml @@ -26,14 +26,17 @@ + + + diff --git a/spring-webflow-samples/booking-portlet-mvc/pom.xml b/spring-webflow-samples/booking-portlet-mvc/pom.xml index b38b6d7d..18270a0d 100644 --- a/spring-webflow-samples/booking-portlet-mvc/pom.xml +++ b/spring-webflow-samples/booking-portlet-mvc/pom.xml @@ -117,6 +117,27 @@ org.springframework.webflow ${project.version} + + + org.hibernate + com.springsource.org.hibernate.validator + 4.1.0.GA + + + org.slf4j + com.springsource.slf4j.log4j + 1.5.6 + + + + javax.xml.bind + com.springsource.javax.xml.bind + 2.2.0 + javax.portlet diff --git a/spring-webflow-samples/booking-portlet-mvc/src/main/java/org/springframework/webflow/samples/booking/Booking.java b/spring-webflow-samples/booking-portlet-mvc/src/main/java/org/springframework/webflow/samples/booking/Booking.java index bd24b722..2cf8b8c0 100644 --- a/spring-webflow-samples/booking-portlet-mvc/src/main/java/org/springframework/webflow/samples/booking/Booking.java +++ b/spring-webflow-samples/booking-portlet-mvc/src/main/java/org/springframework/webflow/samples/booking/Booking.java @@ -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; } diff --git a/spring-webflow-samples/booking-portlet-mvc/src/main/java/org/springframework/webflow/samples/booking/BookingDateRange.java b/spring-webflow-samples/booking-portlet-mvc/src/main/java/org/springframework/webflow/samples/booking/BookingDateRange.java new file mode 100644 index 00000000..a5cad188 --- /dev/null +++ b/spring-webflow-samples/booking-portlet-mvc/src/main/java/org/springframework/webflow/samples/booking/BookingDateRange.java @@ -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[] payload() default {}; + +} diff --git a/spring-webflow-samples/booking-portlet-mvc/src/main/java/org/springframework/webflow/samples/booking/BookingDateRangeValidator.java b/spring-webflow-samples/booking-portlet-mvc/src/main/java/org/springframework/webflow/samples/booking/BookingDateRangeValidator.java new file mode 100644 index 00000000..716a40bc --- /dev/null +++ b/spring-webflow-samples/booking-portlet-mvc/src/main/java/org/springframework/webflow/samples/booking/BookingDateRangeValidator.java @@ -0,0 +1,19 @@ +package org.springframework.webflow.samples.booking; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; + +public class BookingDateRangeValidator implements ConstraintValidator { + + 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; + } + +} diff --git a/spring-webflow-samples/booking-portlet-mvc/src/main/webapp/WEB-INF/config/application-config.xml b/spring-webflow-samples/booking-portlet-mvc/src/main/webapp/WEB-INF/config/application-config.xml index 295df2e2..02faf838 100644 --- a/spring-webflow-samples/booking-portlet-mvc/src/main/webapp/WEB-INF/config/application-config.xml +++ b/spring-webflow-samples/booking-portlet-mvc/src/main/webapp/WEB-INF/config/application-config.xml @@ -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"> diff --git a/spring-webflow-samples/booking-portlet-mvc/src/main/webapp/WEB-INF/config/hotelbooking-portlet-config.xml b/spring-webflow-samples/booking-portlet-mvc/src/main/webapp/WEB-INF/config/hotelbooking-portlet-config.xml index 51b98426..94078d12 100644 --- a/spring-webflow-samples/booking-portlet-mvc/src/main/webapp/WEB-INF/config/hotelbooking-portlet-config.xml +++ b/spring-webflow-samples/booking-portlet-mvc/src/main/webapp/WEB-INF/config/hotelbooking-portlet-config.xml @@ -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"> @@ -38,11 +38,14 @@
- + + + + @@ -50,4 +53,7 @@ + + + \ No newline at end of file diff --git a/spring-webflow-samples/booking-portlet-mvc/src/main/webapp/WEB-INF/flows/booking/enterBookingDetails.jsp b/spring-webflow-samples/booking-portlet-mvc/src/main/webapp/WEB-INF/flows/booking/enterBookingDetails.jsp index d16da7fa..51508a95 100644 --- a/spring-webflow-samples/booking-portlet-mvc/src/main/webapp/WEB-INF/flows/booking/enterBookingDetails.jsp +++ b/spring-webflow-samples/booking-portlet-mvc/src/main/webapp/WEB-INF/flows/booking/enterBookingDetails.jsp @@ -9,8 +9,16 @@ - -
+ +
+ + +
+
+
+
+
+
diff --git a/spring-webflow-samples/booking-portlet-mvc/src/main/webapp/WEB-INF/flows/booking/messages.properties b/spring-webflow-samples/booking-portlet-mvc/src/main/webapp/WEB-INF/flows/booking/messages.properties new file mode 100644 index 00000000..3d15709e --- /dev/null +++ b/spring-webflow-samples/booking-portlet-mvc/src/main/webapp/WEB-INF/flows/booking/messages.properties @@ -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 \ No newline at end of file diff --git a/spring-webflow/src/main/java/org/springframework/webflow/config/FlowBuilderServicesBeanDefinitionParser.java b/spring-webflow/src/main/java/org/springframework/webflow/config/FlowBuilderServicesBeanDefinitionParser.java index 878931c6..d187d5dc 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/config/FlowBuilderServicesBeanDefinitionParser.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/config/FlowBuilderServicesBeanDefinitionParser.java @@ -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)) { diff --git a/spring-webflow/src/main/java/org/springframework/webflow/config/spring-webflow-config-2.0.xsd b/spring-webflow/src/main/java/org/springframework/webflow/config/spring-webflow-config-2.0.xsd index e315ad49..8aa63320 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/config/spring-webflow-config-2.0.xsd +++ b/spring-webflow/src/main/java/org/springframework/webflow/config/spring-webflow-config-2.0.xsd @@ -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"> diff --git a/spring-webflow/src/main/java/org/springframework/webflow/config/spring-webflow-config-2.3.xsd b/spring-webflow/src/main/java/org/springframework/webflow/config/spring-webflow-config-2.3.xsd new file mode 100644 index 00000000..74b5ff4a --- /dev/null +++ b/spring-webflow/src/main/java/org/springframework/webflow/config/spring-webflow-config-2.3.xsd @@ -0,0 +1,448 @@ + + + + + + +A XML-based DSL for configuring the Spring Web Flow 2.0 system. +]]> + + + + + + + + + +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. +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/FlowBuilderContext.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/FlowBuilderContext.java index dae6da6c..ec9131b9 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/FlowBuilderContext.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/FlowBuilderContext.java @@ -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 diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/ViewFactoryCreator.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/ViewFactoryCreator.java index 4424ec6f..5bc7480a 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/ViewFactoryCreator.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/ViewFactoryCreator.java @@ -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. diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/model/FlowModelFlowBuilder.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/model/FlowModelFlowBuilder.java index 5fac5d14..1609d946 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/model/FlowModelFlowBuilder.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/model/FlowModelFlowBuilder.java @@ -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]; diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/model/LocalFlowBuilderContext.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/model/LocalFlowBuilderContext.java index 23da90b3..bd55c800 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/model/LocalFlowBuilderContext.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/model/LocalFlowBuilderContext.java @@ -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(); + } + } + } \ No newline at end of file diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/FlowBuilderContextImpl.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/FlowBuilderContextImpl.java index d2566a86..60fd08b0 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/FlowBuilderContextImpl.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/FlowBuilderContextImpl.java @@ -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 diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/FlowBuilderServices.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/FlowBuilderServices.java index d080f19e..8252f8c1 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/FlowBuilderServices.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/FlowBuilderServices.java @@ -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; } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/builder/MvcViewFactoryCreator.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/builder/MvcViewFactoryCreator.java index 76423064..c7c4f374 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/mvc/builder/MvcViewFactoryCreator.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/builder/MvcViewFactoryCreator.java @@ -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; } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/AbstractMvcView.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/AbstractMvcView.java index 3709d768..6307466b 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/AbstractMvcView.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/AbstractMvcView.java @@ -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 { diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/AbstractMvcViewFactory.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/AbstractMvcViewFactory.java index c3dfd139..58defb58 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/AbstractMvcViewFactory.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/AbstractMvcViewFactory.java @@ -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); } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/test/MockViewFactoryCreator.java b/spring-webflow/src/main/java/org/springframework/webflow/test/MockViewFactoryCreator.java index ee81c6d6..c2cbfd3c 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/test/MockViewFactoryCreator.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/test/MockViewFactoryCreator.java @@ -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); } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/validation/ValidationHelper.java b/spring-webflow/src/main/java/org/springframework/webflow/validation/ValidationHelper.java index 3d45f384..adb363de 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/validation/ValidationHelper.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/validation/ValidationHelper.java @@ -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. *

@@ -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 diff --git a/spring-webflow/src/main/resources/META-INF/spring.schemas b/spring-webflow/src/main/resources/META-INF/spring.schemas index e4fce8cd..d7334c4c 100644 --- a/spring-webflow/src/main/resources/META-INF/spring.schemas +++ b/spring-webflow/src/main/resources/META-INF/spring.schemas @@ -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 \ No newline at end of file +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 \ No newline at end of file diff --git a/spring-webflow/src/test/java/org/springframework/webflow/config/EmptySpringValidator.java b/spring-webflow/src/test/java/org/springframework/webflow/config/EmptySpringValidator.java new file mode 100644 index 00000000..3a6fec69 --- /dev/null +++ b/spring-webflow/src/test/java/org/springframework/webflow/config/EmptySpringValidator.java @@ -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) { + } + +} diff --git a/spring-webflow/src/test/java/org/springframework/webflow/config/FlowBuilderServicesBeanDefinitionParserTests.java b/spring-webflow/src/test/java/org/springframework/webflow/config/FlowBuilderServicesBeanDefinitionParserTests.java index 0841e7c4..11b2034c 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/config/FlowBuilderServicesBeanDefinitionParserTests.java +++ b/spring-webflow/src/test/java/org/springframework/webflow/config/FlowBuilderServicesBeanDefinitionParserTests.java @@ -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"); } diff --git a/spring-webflow/src/test/java/org/springframework/webflow/config/flow-builder-services.xml b/spring-webflow/src/test/java/org/springframework/webflow/config/flow-builder-services.xml index 505fb3e2..51df5ef9 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/config/flow-builder-services.xml +++ b/spring-webflow/src/test/java/org/springframework/webflow/config/flow-builder-services.xml @@ -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"> + conversion-service="customConversionService" + validator="customValidator" + development="true" /> @@ -28,4 +30,6 @@ + + \ No newline at end of file diff --git a/spring-webflow/src/test/java/org/springframework/webflow/config/flow-executor.xml b/spring-webflow/src/test/java/org/springframework/webflow/config/flow-executor.xml index 3e3dfc8c..76015639 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/config/flow-executor.xml +++ b/spring-webflow/src/test/java/org/springframework/webflow/config/flow-executor.xml @@ -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"> diff --git a/spring-webflow/src/test/java/org/springframework/webflow/config/flow-registry.xml b/spring-webflow/src/test/java/org/springframework/webflow/config/flow-registry.xml index 14255bf9..797e322a 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/config/flow-registry.xml +++ b/spring-webflow/src/test/java/org/springframework/webflow/config/flow-registry.xml @@ -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">

Name: