Handle composite constraints.
[JSR 303 TCK Result] 36 of 258 (13.95%) Pass with 15 Failures and 16 Errors.
Review at http://gwt-code-reviews.appspot.com/1231801
Review by: rchandia@google.com
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@9463 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/samples/validation/src/com/google/gwt/sample/validation/shared/Address.java b/samples/validation/src/com/google/gwt/sample/validation/shared/Address.java
index f2702d6..f340eab 100644
--- a/samples/validation/src/com/google/gwt/sample/validation/shared/Address.java
+++ b/samples/validation/src/com/google/gwt/sample/validation/shared/Address.java
@@ -27,4 +27,8 @@
@NotNull
public String street;
+ @Zip
+ public String zip;
+
+
}
diff --git a/samples/validation/src/com/google/gwt/sample/validation/shared/Zip.java b/samples/validation/src/com/google/gwt/sample/validation/shared/Zip.java
new file mode 100644
index 0000000..ffc8ec3
--- /dev/null
+++ b/samples/validation/src/com/google/gwt/sample/validation/shared/Zip.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.sample.validation.shared;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+import javax.validation.constraints.Pattern;
+import javax.validation.constraints.Size;
+
+/**
+ * Example composite constraint.
+ */
+@Pattern(regexp = "[0-9]*")
+@Size(min = 5, max = 5)
+@Constraint(validatedBy = {})
+@Documented
+@Target({ANNOTATION_TYPE, METHOD, FIELD, CONSTRUCTOR, PARAMETER})
+@Retention(RUNTIME)
+public @interface Zip {
+ /**
+ * Defines several @Zip annotations on the same element
+ *
+ * @see {@link Zip}
+ */
+ @Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
+ @Retention(RUNTIME)
+ @Documented
+ @interface List {
+ Zip[] value();
+ }
+
+ Class<?>[] groups() default {};
+
+ String message() default "Wrong zipcode";
+
+ Class<? extends Payload>[] payload() default {};
+}
\ No newline at end of file
diff --git a/samples/validationtck/test/com/google/gwt/sample/validationtck/constraints/constraintcomposition/ConstraintCompositionGwtSuite.java b/samples/validationtck/test/com/google/gwt/sample/validationtck/constraints/constraintcomposition/ConstraintCompositionGwtSuite.java
new file mode 100644
index 0000000..ed6a4ab
--- /dev/null
+++ b/samples/validationtck/test/com/google/gwt/sample/validationtck/constraints/constraintcomposition/ConstraintCompositionGwtSuite.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.sample.validationtck.constraints.constraintcomposition;
+
+import com.google.gwt.junit.tools.GWTTestSuite;
+
+import junit.framework.Test;
+
+/**
+ * Tck Tests for the {@code constraints composition} package.
+ */
+public class ConstraintCompositionGwtSuite {
+ public static Test suite() {
+ GWTTestSuite suite = new GWTTestSuite(
+ "TCK for GWT Validation, constraints composition package");
+ suite.addTestSuite(ConstraintCompositionTest.class);
+ return suite;
+ }
+}
diff --git a/samples/validationtck/test/com/google/gwt/sample/validationtck/constraints/constraintcomposition/ConstraintCompositionTest.java b/samples/validationtck/test/com/google/gwt/sample/validationtck/constraints/constraintcomposition/ConstraintCompositionTest.java
new file mode 100644
index 0000000..98e7ada
--- /dev/null
+++ b/samples/validationtck/test/com/google/gwt/sample/validationtck/constraints/constraintcomposition/ConstraintCompositionTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.sample.validationtck.constraints.constraintcomposition;
+
+import com.google.gwt.junit.client.GWTTestCase;
+
+/**
+ * Wraps
+ * {@link org.hibernate.jsr303.tck.tests.constraints.constraintcomposition.ConstraintCompositionTest}
+ * .
+ */
+public class ConstraintCompositionTest extends GWTTestCase {
+ private final org.hibernate.jsr303.tck.tests.constraints.constraintcomposition.ConstraintCompositionTest delegate =
+ new org.hibernate.jsr303.tck.tests.constraints.constraintcomposition.ConstraintCompositionTest();
+
+ @Override
+ public String getModuleName() {
+ return "com.google.gwt.sample.validationtck.constraints.constraintcomposition.TckTest";
+ }
+
+ public void testAllComposingConstraintsMustBeApplicableToAnnotatedType() {
+ delegate.testAllComposingConstraintsMustBeApplicableToAnnotatedType();
+ }
+
+ public void testAttributesDefinedOnComposingConstraints() {
+ delegate.testAttributesDefinedOnComposingConstraints();
+ }
+
+ public void testComposedConstraints() {
+ delegate.testComposedConstraints();
+ }
+
+ public void testComposedConstraintsAreRecursive() {
+ delegate.testComposedConstraintsAreRecursive();
+ }
+
+ public void testEachFailingConstraintCreatesConstraintViolation() {
+ delegate.testEachFailingConstraintCreatesConstraintViolation();
+ }
+
+ public void testGroupsDefinedOnMainAnnotationAreInherited() {
+ delegate.testGroupsDefinedOnMainAnnotationAreInherited();
+ }
+
+ public void testOnlySingleConstraintViolation() {
+ delegate.testOnlySingleConstraintViolation();
+ }
+
+ public void testOverriddenAttributesMustMatchInType() {
+ delegate.testOverriddenAttributesMustMatchInType();
+ }
+
+ public void testPayloadPropagationInComposedConstraints() {
+ delegate.testPayloadPropagationInComposedConstraints();
+ }
+
+ public void testValidationOfMainAnnotationIsAlsoApplied() {
+ delegate.testValidationOfMainAnnotationIsAlsoApplied();
+ }
+}
diff --git a/samples/validationtck/test/com/google/gwt/sample/validationtck/constraints/constraintcomposition/TckTest.gwt.xml b/samples/validationtck/test/com/google/gwt/sample/validationtck/constraints/constraintcomposition/TckTest.gwt.xml
new file mode 100644
index 0000000..a2b50cc
--- /dev/null
+++ b/samples/validationtck/test/com/google/gwt/sample/validationtck/constraints/constraintcomposition/TckTest.gwt.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.0.1//EN" "http://google-web-toolkit.googlecode.com/svn/tags/2.0.1/distro-source/core/src/gwt-module.dtd">
+<!--
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ use this file except in compliance with the License. You may obtain a copy of
+ the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ License for the specific language governing permissions and limitations under
+ the License.
+-->
+<module>
+ <inherits name="com.google.gwt.sample.validationtck.ValidationTck" />
+ <source path="">
+ <include name="*.java" />
+ <exclude name="super" />
+ </source>
+ <replace-with class="com.google.gwt.sample.validationtck.constraints.constraintcomposition.TckTestValidator">
+ <when-type-is class="javax.validation.Validator"/>
+ </replace-with>
+</module>
\ No newline at end of file
diff --git a/samples/validationtck/test/com/google/gwt/sample/validationtck/constraints/constraintcomposition/TckTestValidator.java b/samples/validationtck/test/com/google/gwt/sample/validationtck/constraints/constraintcomposition/TckTestValidator.java
new file mode 100644
index 0000000..76c1531
--- /dev/null
+++ b/samples/validationtck/test/com/google/gwt/sample/validationtck/constraints/constraintcomposition/TckTestValidator.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.sample.validationtck.constraints.constraintcomposition;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.validation.client.AbstractValidator;
+import com.google.gwt.validation.client.GwtValidation;
+
+import org.hibernate.jsr303.tck.tests.constraints.constraintcomposition.Address;
+import org.hibernate.jsr303.tck.tests.constraints.constraintcomposition.FrenchAddress;
+import org.hibernate.jsr303.tck.tests.constraints.constraintcomposition.Friend;
+import org.hibernate.jsr303.tck.tests.constraints.constraintcomposition.GermanAddress;
+import org.hibernate.jsr303.tck.tests.constraints.constraintcomposition.Shoe;
+
+import javax.validation.Validator;
+
+/**
+ * {@link Validator} implementation that uses
+ * {@link com.google.gwt.validation.client.GwtValidation GwtValidation}.
+ */
+public final class TckTestValidator extends AbstractValidator {
+ /**
+ * Marker Interface for {@link GWT#create(Class)}.
+ */
+ @GwtValidation(value = {
+ Address.class, FrenchAddress.class, Friend.class, GermanAddress.class,
+ Shoe.class
+ // TODO(nchalko) handle ConstraintDefinitionException
+ // ConstraintCompositionTest.DummyEntityWithZipCode.class
+ })
+ public static interface GwtValidator extends Validator {
+ }
+
+ public TckTestValidator() {
+ super((Validator) GWT.create(GwtValidator.class));
+ }
+}
diff --git a/user/src/com/google/gwt/validation/rebind/GwtSpecificValidatorCreator.java b/user/src/com/google/gwt/validation/rebind/GwtSpecificValidatorCreator.java
index a7efab0..4d5e720 100644
--- a/user/src/com/google/gwt/validation/rebind/GwtSpecificValidatorCreator.java
+++ b/user/src/com/google/gwt/validation/rebind/GwtSpecificValidatorCreator.java
@@ -17,6 +17,7 @@
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.UnsafeNativeLong;
+import com.google.gwt.core.ext.Generator;
import com.google.gwt.core.ext.GeneratorContext;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.TreeLogger.Type;
@@ -117,7 +118,7 @@
return jProgram.getLiteralLong(((Long) value).intValue()).toSource();
}
if (value instanceof String) {
- return '"' + ((String) value).toString().replace("\"", "\\\"") + '"';
+ return '"' + Generator.escape((String) value) + '"';
}
// TODO(nchalko) handle the rest of the literal types
throw new IllegalArgumentException(value.getClass()
@@ -726,6 +727,37 @@
sw.println("}");
}
+ private void writeValidateConstraint(SourceWriter sw, PropertyDescriptor p,
+ Class<?> elementClass, ConstraintDescriptor<?> constraint,
+ String constraintDescriptorVar) {
+ Class<? extends ConstraintValidator<? extends Annotation, ?>> validatorClass =
+ getValidatorForType(constraint, elementClass);
+ if (validatorClass == null) {
+ // TODO(nchalko) What does the spec say to do here.
+ logger.log(Type.WARN, "No ConstraintValidator of " + constraint + " for "
+ + p.getPropertyName() + " of type " + elementClass);
+
+ } else {
+ // TODO(nchalko) handle constraint.isReportAsSingleViolation()
+ // validate(context, violations, object, value, new MyValidator(),
+ // constraintDescriptor, groups);
+ sw.print("validate(context, violations, object, value, ");
+ sw.print("new "); // new one each time because validators are not
+ // thread safe
+ // TODO(nchalko) use ConstraintValidatorFactory
+ sw.print(validatorClass.getCanonicalName());
+ sw.print("(), ");
+ sw.print(constraintDescriptorVar);
+ sw.println(", groups);");
+ }
+ int count = 0;
+ for (ConstraintDescriptor<?> compositeConstraint : constraint.getComposingConstraints()) {
+ String compositeVar = constraintDescriptorVar + "_" + count++;
+ writeValidateConstraint(sw, p, elementClass, compositeConstraint,
+ compositeVar);
+ }
+ }
+
private void writeValidateFieldCall(SourceWriter sw, PropertyDescriptor p,
boolean useValue) {
String propertyName = p.getPropertyName();
@@ -933,27 +965,11 @@
if (annotation != null) {
// TODO(nchalko) check for annotation equality
- Class<? extends ConstraintValidator<? extends Annotation, ?>> validatorClass = getValidatorForType(
- constraint, elementClass);
- if (validatorClass == null) {
- // TODO(nchalko) What does the spec say to do here.
- logger.log(Type.WARN, "No ConstraintValidator of " + constraint
- + " for " + p.getPropertyName() + " of type " + elementClass);
+ String constraintDescriptorVar = constraintDescriptorVar(
+ p.getPropertyName(), count);
- } else {
- // TODO(nchalko) handle constraint.isReportAsSingleViolation() and
- // hasComposingConstraints
-
- // validate(context, violations, object, value, new MyValidator(),
- // constraintDescriptor, groups);
- sw.print("validate(context, violations, object, value, ");
- sw.print("new "); // new one each time because validators are not
- // thread safe
- sw.print(validatorClass.getCanonicalName());
- sw.print("(), ");
- sw.print(constraintDescriptorVar(p.getPropertyName(), count));
- sw.println(", groups);");
- }
+ writeValidateConstraint(sw, p, elementClass, constraint,
+ constraintDescriptorVar);
}
count++; // index starts at zero
}