Updated Branches: refs/heads/5.3 7c95c161e -> 9c5f7f0d0
FIXED - TAP5-2101: BeanEditor should always provide a new BeanValidationContext (JSR-303) - apply Luca Menegus' patch, merge BeanEditor over from master Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/9c5f7f0d Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/9c5f7f0d Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/9c5f7f0d Branch: refs/heads/5.3 Commit: 9c5f7f0d0980ab21867e24fc48b0e17b1db67c13 Parents: 7c95c16 Author: kaosko <[email protected]> Authored: Sat Apr 13 22:34:15 2013 -0700 Committer: kaosko <[email protected]> Committed: Sat Apr 13 22:34:15 2013 -0700 ---------------------------------------------------------------------- .../TapestryBeanValidationIntegrationTests.java | 14 +++++ .../org/example/testapp/entities/ComplexBean.java | 44 +++++++++++++++ .../testapp/entities/SomeOtherSimpleBean.java | 21 +++++++ .../example/testapp/entities/SomeSimpleBean.java | 21 +++++++ .../org/example/testapp/pages/ComplexBeanDemo.java | 14 +++++ .../src/test/webapp/ComplexBeanDemo.tml | 19 ++++++ tapestry-beanvalidator/src/test/webapp/Index.tml | 3 + .../tapestry5/corelib/components/BeanEditor.java | 30 +++++----- 8 files changed, 151 insertions(+), 15 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/9c5f7f0d/tapestry-beanvalidator/src/test/java/org/apache/tapestry5/beanvalidator/integration/TapestryBeanValidationIntegrationTests.java ---------------------------------------------------------------------- diff --git a/tapestry-beanvalidator/src/test/java/org/apache/tapestry5/beanvalidator/integration/TapestryBeanValidationIntegrationTests.java b/tapestry-beanvalidator/src/test/java/org/apache/tapestry5/beanvalidator/integration/TapestryBeanValidationIntegrationTests.java index 658077d..1d686c4 100644 --- a/tapestry-beanvalidator/src/test/java/org/apache/tapestry5/beanvalidator/integration/TapestryBeanValidationIntegrationTests.java +++ b/tapestry-beanvalidator/src/test/java/org/apache/tapestry5/beanvalidator/integration/TapestryBeanValidationIntegrationTests.java @@ -203,6 +203,20 @@ public class TapestryBeanValidationIntegrationTests extends SeleniumTestCase assertTextPresent("Login Name size must be between 7 and 10", "Login Name must match \"[0-9]+\""); } + @Test + public void beaneditor_validation() throws Exception + { + openLinks("ComplexBean Demo"); + + // Test JSR-303 validator + + clickAndWait(SUBMIT); + + assertTextPresent("Simple Not Null Property may not be null", + "Min Value must be greater than or equal to 6", "Not Null String may not be null"); + + } + protected final void assertBubbleMessage(String fieldId, String expected) { String popupId = fieldId + "_errorpopup"; http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/9c5f7f0d/tapestry-beanvalidator/src/test/java/org/example/testapp/entities/ComplexBean.java ---------------------------------------------------------------------- diff --git a/tapestry-beanvalidator/src/test/java/org/example/testapp/entities/ComplexBean.java b/tapestry-beanvalidator/src/test/java/org/example/testapp/entities/ComplexBean.java new file mode 100644 index 0000000..beaa840 --- /dev/null +++ b/tapestry-beanvalidator/src/test/java/org/example/testapp/entities/ComplexBean.java @@ -0,0 +1,44 @@ +package org.example.testapp.entities; + +import javax.validation.constraints.NotNull; + +public class ComplexBean +{ + + private SomeSimpleBean someSimpleBean; + private SomeOtherSimpleBean someOtherSimpleBean; + + @NotNull + private String simpleNotNullProperty; + + public SomeSimpleBean getSomeSimpleBean() + { + return someSimpleBean; + } + + public void setSomeSimpleBean(SomeSimpleBean someSimpleBean) + { + this.someSimpleBean = someSimpleBean; + } + + public SomeOtherSimpleBean getSomeOtherSimpleBean() + { + return someOtherSimpleBean; + } + + public void setSomeOtherSimpleBean(SomeOtherSimpleBean someOtherSimpleBean) + { + this.someOtherSimpleBean = someOtherSimpleBean; + } + + public String getSimpleNotNullProperty() + { + return simpleNotNullProperty; + } + + public void setSimpleNotNullProperty(String simpleNotNullProperty) + { + this.simpleNotNullProperty = simpleNotNullProperty; + } + +} http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/9c5f7f0d/tapestry-beanvalidator/src/test/java/org/example/testapp/entities/SomeOtherSimpleBean.java ---------------------------------------------------------------------- diff --git a/tapestry-beanvalidator/src/test/java/org/example/testapp/entities/SomeOtherSimpleBean.java b/tapestry-beanvalidator/src/test/java/org/example/testapp/entities/SomeOtherSimpleBean.java new file mode 100644 index 0000000..9a262f3 --- /dev/null +++ b/tapestry-beanvalidator/src/test/java/org/example/testapp/entities/SomeOtherSimpleBean.java @@ -0,0 +1,21 @@ +package org.example.testapp.entities; + +import javax.validation.constraints.NotNull; + +public class SomeOtherSimpleBean +{ + + @NotNull + private String notNullString; + + public String getNotNullString() + { + return notNullString; + } + + public void setNotNullString(String notNullString) + { + this.notNullString = notNullString; + } + +} http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/9c5f7f0d/tapestry-beanvalidator/src/test/java/org/example/testapp/entities/SomeSimpleBean.java ---------------------------------------------------------------------- diff --git a/tapestry-beanvalidator/src/test/java/org/example/testapp/entities/SomeSimpleBean.java b/tapestry-beanvalidator/src/test/java/org/example/testapp/entities/SomeSimpleBean.java new file mode 100644 index 0000000..1564112 --- /dev/null +++ b/tapestry-beanvalidator/src/test/java/org/example/testapp/entities/SomeSimpleBean.java @@ -0,0 +1,21 @@ +package org.example.testapp.entities; + +import javax.validation.constraints.Min; + +public class SomeSimpleBean +{ + + @Min(6) + private int minValue; + + public int getMinValue() + { + return minValue; + } + + public void setMinValue(int minValue) + { + this.minValue = minValue; + } + +} http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/9c5f7f0d/tapestry-beanvalidator/src/test/java/org/example/testapp/pages/ComplexBeanDemo.java ---------------------------------------------------------------------- diff --git a/tapestry-beanvalidator/src/test/java/org/example/testapp/pages/ComplexBeanDemo.java b/tapestry-beanvalidator/src/test/java/org/example/testapp/pages/ComplexBeanDemo.java new file mode 100644 index 0000000..f7b2623 --- /dev/null +++ b/tapestry-beanvalidator/src/test/java/org/example/testapp/pages/ComplexBeanDemo.java @@ -0,0 +1,14 @@ +package org.example.testapp.pages; + +import org.apache.tapestry5.annotations.Persist; +import org.apache.tapestry5.annotations.Property; +import org.example.testapp.entities.ComplexBean; + +public class ComplexBeanDemo +{ + + @Property + @Persist + private ComplexBean complexBean; + +} http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/9c5f7f0d/tapestry-beanvalidator/src/test/webapp/ComplexBeanDemo.tml ---------------------------------------------------------------------- diff --git a/tapestry-beanvalidator/src/test/webapp/ComplexBeanDemo.tml b/tapestry-beanvalidator/src/test/webapp/ComplexBeanDemo.tml new file mode 100644 index 0000000..c701b1f --- /dev/null +++ b/tapestry-beanvalidator/src/test/webapp/ComplexBeanDemo.tml @@ -0,0 +1,19 @@ +<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd"> + <body> + <t:form clientValidation="false" validate="complexBean"> + <t:errors/> + + <br/> + <t:BeanEditor object="complexBean" /> + + <br/> + <t:BeanEditor object="complexBean.someSimpleBean" /> + + <br/> + <t:BeanEditor object="complexBean.someOtherSimpleBean" /> + + <br/> + <input type="submit" value="Go"/> + </t:form> + </body> +</html> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/9c5f7f0d/tapestry-beanvalidator/src/test/webapp/Index.tml ---------------------------------------------------------------------- diff --git a/tapestry-beanvalidator/src/test/webapp/Index.tml b/tapestry-beanvalidator/src/test/webapp/Index.tml index da8978e..0970c96 100644 --- a/tapestry-beanvalidator/src/test/webapp/Index.tml +++ b/tapestry-beanvalidator/src/test/webapp/Index.tml @@ -24,6 +24,9 @@ <li> <t:pagelink page="OnPrepareDemo">OnPrepare Demo</t:pagelink> </li> + <li> + <t:pagelink page="ComplexBeanDemo">ComplexBean Demo</t:pagelink> + </li> </ul> </body> </html> http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/9c5f7f0d/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanEditor.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanEditor.java b/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanEditor.java index 6bbfa31..94c37b9 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanEditor.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanEditor.java @@ -23,12 +23,12 @@ import org.apache.tapestry5.annotations.Parameter; import org.apache.tapestry5.annotations.Property; import org.apache.tapestry5.annotations.SupportsInformalParameters; import org.apache.tapestry5.beaneditor.BeanModel; -import org.apache.tapestry5.corelib.internal.InternalMessages; import org.apache.tapestry5.internal.BeanValidationContext; import org.apache.tapestry5.internal.BeanValidationContextImpl; import org.apache.tapestry5.internal.beaneditor.BeanModelUtils; import org.apache.tapestry5.ioc.annotations.Inject; import org.apache.tapestry5.ioc.internal.util.TapestryException; +import org.apache.tapestry5.plastic.PlasticUtils; import org.apache.tapestry5.services.BeanEditContext; import org.apache.tapestry5.services.BeanModelSource; import org.apache.tapestry5.services.Environment; @@ -166,6 +166,8 @@ public class BeanEditor */ private Object cachedObject; + private BeanValidationContext originalBeanValidationContext; + // Needed for testing as well public Object getObject() @@ -209,14 +211,10 @@ public class BeanEditor } catch (Exception ex) { - String message = InternalMessages.failureInstantiatingObject(model.getBeanType(), - resources.getCompleteId(), ex); + String message = String.format("Exception instantiating instance of %s (for component '%s'): %s", + PlasticUtils.toTypeName(model.getBeanType()), resources.getCompleteId(), ex); throw new TapestryException(message, resources.getLocation(), ex); } - - // If 'object' parameter is bound to a null-value BeanValidationContext is empty. - // This prevents JSR-303 javascript validators to be rendered properly . - refreshBeanValidationContext(); } BeanEditContext context = new BeanEditContext() @@ -235,20 +233,22 @@ public class BeanEditor cachedObject = object; environment.push(BeanEditContext.class, context); + // Always provide a new BeanValidationContext + originalBeanValidationContext = environment.push(BeanValidationContext.class, + new BeanValidationContextImpl(object)); + } void cleanupEnvironment() { environment.pop(BeanEditContext.class); - } - - private void refreshBeanValidationContext() - { - if (environment.peek(BeanValidationContext.class) != null) + environment.pop(BeanValidationContext.class); + // Restore the original BeanValidationContext as it might still be useful to the enclosing + // form + if (originalBeanValidationContext != null) { - environment.pop(BeanValidationContext.class); - - environment.push(BeanValidationContext.class, new BeanValidationContextImpl(object)); + environment.push(BeanValidationContext.class, originalBeanValidationContext); + originalBeanValidationContext = null; } }
