Public: First take at GWT validation that actually validates on the client side.
Review at http://gwt-code-reviews.appspot.com/863801
Review by: robertvawter@google.com
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@8952 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/build.xml b/build.xml
index f1403d4..8ca3bdf 100755
--- a/build.xml
+++ b/build.xml
@@ -174,6 +174,7 @@
<classpath>
<pathelement location="${gwt.build.out}/tools/api-checker/bin"/>
<fileset dir="${gwt.build.lib}" includes="gwt-user.jar,gwt-dev.jar" />
+ <pathelement location="${gwt.tools.lib}//hibernate/validator/hibernate-validator-4.1.0.Final.jar" />
<pathelement location="${gwt.tools.lib}/javax/validation/validation-api-1.0.0.GA.jar" />
<pathelement path="${java.class.path}"/>
<pathelement location="${gwt.tools.lib}/apache/ant-1.6.5.jar" />
diff --git a/eclipse/samples/Validation/.classpath b/eclipse/samples/Validation/.classpath
index b67ec19..f36f38b 100644
--- a/eclipse/samples/Validation/.classpath
+++ b/eclipse/samples/Validation/.classpath
@@ -2,9 +2,13 @@
<classpath>
<classpathentry kind="src" path="core/src"/>
<classpathentry kind="src" output="war" path="core/war"/>
+ <classpathentry kind="src" path="gwt-gen"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry combineaccessrules="false" kind="src" path="/gwt-user"/>
- <classpathentry kind="var" path="GWT_TOOLS/lib/javax/validation/validation-api-1.0.0.GA-sources.jar"/>
- <classpathentry kind="var" path="GWT_TOOLS/lib/javax/validation/validation-api-1.0.0.GA.jar" sourcepath="/GWT_TOOLS/lib/javax/validation/validation-api-1.0.0.GA-sources.jar"/>
+ <classpathentry kind="var" path="GWT_TOOLS/lib/apache/log4j/log4j-1.2.16.jar"/>
+ <classpathentry kind="var" path="GWT_TOOLS/lib/hibernate/validator/hibernate-validator-4.1.0.Final.jar" sourcepath="/GWT_TOOLS/lib/hibernate/validator/hibernate-validator-4.1.0.Final-sources.jar"/>
+ <classpathentry kind="var" path="GWT_TOOLS/lib/slf4j/slf4j-api/slf4j-api-1.6.1.jar"/>
+ <classpathentry kind="var" path="GWT_TOOLS/lib/slf4j/slf4j-log4j12/slf4j-log4j12-1.6.1.jar"/>
+ <classpathentry kind="var" path="GWT_TOOLS/lib/hibernate/validator/hibernate-validator-4.1.0.Final-sources.jar"/>
<classpathentry kind="output" path="war/WEB-INF/classes"/>
</classpath>
diff --git a/eclipse/user/.classpath b/eclipse/user/.classpath
index 605bfdf..5075ee1 100644
--- a/eclipse/user/.classpath
+++ b/eclipse/user/.classpath
@@ -39,6 +39,11 @@
<classpathentry exported="true" kind="var" path="GWT_TOOLS/lib/javax/validation/validation-api-1.0.0.GA.jar" sourcepath="/GWT_TOOLS/lib/javax/validation/validation-api-1.0.0.GA-sources.jar"/>
<classpathentry exported="true" kind="var" path="GWT_TOOLS/lib/javax/validation/validation-api-1.0.0.GA-sources.jar"/>
<classpathentry kind="var" path="GWT_TOOLS/lib/jetty/jetty-6.1.11.jar" sourcepath="/GWT_TOOLS/lib/jetty/jetty-6.1.11-src.zip"/>
+ <classpathentry kind="var" path="GWT_TOOLS/lib/hibernate/validator/hibernate-validator-4.1.0.Final-sources.jar"/>
+ <classpathentry kind="var" path="GWT_TOOLS/lib/hibernate/validator/hibernate-validator-4.1.0.Final.jar" sourcepath="/GWT_TOOLS/lib/hibernate/validator/hibernate-validator-4.1.0.Final-sources.jar"/>
+ <classpathentry kind="var" path="GWT_TOOLS/lib/apache/log4j/log4j-1.2.16.jar"/>
+ <classpathentry kind="var" path="GWT_TOOLS/lib/slf4j/slf4j-api/slf4j-api-1.6.1.jar"/>
+ <classpathentry kind="var" path="GWT_TOOLS/lib/slf4j/slf4j-log4j12/slf4j-log4j12-1.6.1.jar"/>
<classpathentry kind="var" path="GWT_TOOLS/lib/guava/guava-r06/guava-r06-rebased.jar"/>
<classpathentry kind="var" path="GWT_TOOLS/lib/streamhtmlparser/streamhtmlparser-jsilver-r10/streamhtmlparser-jsilver-r10-1.5-rebased.jar"/>
<classpathentry kind="output" path="bin"/>
diff --git a/samples/common.ant.xml b/samples/common.ant.xml
index 0152144..829e22b 100755
--- a/samples/common.ant.xml
+++ b/samples/common.ant.xml
@@ -65,6 +65,7 @@
<pathelement location="${gwt.dev.jar}" />
<pathelement location="${gwt.tools.lib}/jsr107cache/jsr107cache-1.1.jar"/>
<pathelement location="${gwt.tools.lib}/javax/validation/validation-api-1.0.0.GA.jar"/>
+ <pathelement location="${gwt.tools.lib}/hibernate/validator/hibernate-validator-4.1.0.Final.jar" />
<path refid="gae.extraclasspath" />
</classpath>
</gwt.javac>
@@ -83,9 +84,26 @@
<mkdir dir="${sample.build}/war" />
<gwt.timer name="${sample.upper} with ${gwt.samples.localworkers} localWorkers">
<java dir="${sample.build}" classname="com.google.gwt.dev.Compiler"
- classpath="${sample.path}:${sample.build}/war/WEB-INF/classes:${gwt.user.jar}:${gwt.dev.jar}:${gwt.tools.lib}/javax/validation/validation-api-1.0.0.GA.jar:${gwt.tools.lib}/javax/validation/validation-api-1.0.0.GA-sources.jar"
- fork="yes" failonerror="true">
- <jvmarg value="-Xmx256M"/>
+ fork="yes" failonerror="true">
+ <classpath>
+ <pathelement path="${sample.path}" />
+ <pathelement location="${sample.build}/war/WEB-INF/classes" />
+ <pathelement location="${gwt.user.jar}" />
+ <pathelement location="${gwt.dev.jar}" />
+ <pathelement location="${gwt.tools.lib}/apache/log4j/log4j-1.2.16.jar" />
+ <pathelement location="${gwt.tools.lib}/javax/validation/validation-api-1.0.0.GA.jar" />
+ <pathelement location="${gwt.tools.lib}/javax/validation/validation-api-1.0.0.GA-sources.jar" />
+ <pathelement location="${gwt.tools.lib}/hibernate/validator/hibernate-validator-4.1.0.Final.jar" />
+ <pathelement location="${gwt.tools.lib}/hibernate/validator/hibernate-validator-4.1.0.Final-sources.jar" />
+ <pathelement location="${gwt.tools.lib}/slf4j/slf4j-api/slf4j-api-1.6.1.jar" />
+ <pathelement location="${gwt.tools.lib}/slf4j/slf4j-log4j12/slf4j-log4j12-1.6.1.jar" />
+ <!-- Needed for JDK 1.5-->
+ <pathelement location="${gwt.tools.lib}/javax/activation/activation-1.1.jar" />
+ <pathelement location="${gwt.tools.lib}/javax/xml/bind/jaxb-api-2.1.jar" />
+ <pathelement location="${gwt.tools.lib}/sun/jaxb/jaxb-impl.2.1.3.jar" />
+ <pathelement location="${gwt.tools.lib}/javax/xml/stream/staxb-api-1.0-2.jar" />
+ </classpath>
+ <jvmarg value="-Xmx256M" />
<arg value="-localWorkers" />
<arg value="${gwt.samples.localworkers}" />
<arg value="-war" />
diff --git a/samples/validation/src/com/google/gwt/sample/validation/Validation.gwt.xml b/samples/validation/src/com/google/gwt/sample/validation/Validation.gwt.xml
index 8b74b57..55dc76a 100644
--- a/samples/validation/src/com/google/gwt/sample/validation/Validation.gwt.xml
+++ b/samples/validation/src/com/google/gwt/sample/validation/Validation.gwt.xml
@@ -16,7 +16,7 @@
<inherits name='com.google.gwt.rpc.RPC'/>
<inherits name='com.google.gwt.user.User'/>
<inherits name='com.google.gwt.user.theme.standard.Standard'/>
- <inherits name='com.google.gwt.validation.Validation'/>
+ <inherits name='org.hibernate.validator.HibernateValidator'/>
<entry-point class='com.google.gwt.sample.validation.client.Validation'/>
diff --git a/samples/validation/src/com/google/gwt/sample/validation/client/GreetingService.java b/samples/validation/src/com/google/gwt/sample/validation/client/GreetingService.java
index 41f61f4..c54f455 100644
--- a/samples/validation/src/com/google/gwt/sample/validation/client/GreetingService.java
+++ b/samples/validation/src/com/google/gwt/sample/validation/client/GreetingService.java
@@ -4,9 +4,9 @@
* 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
diff --git a/samples/validation/src/com/google/gwt/sample/validation/client/GreetingServiceAsync.java b/samples/validation/src/com/google/gwt/sample/validation/client/GreetingServiceAsync.java
index cbc3b97..dda64fb 100644
--- a/samples/validation/src/com/google/gwt/sample/validation/client/GreetingServiceAsync.java
+++ b/samples/validation/src/com/google/gwt/sample/validation/client/GreetingServiceAsync.java
@@ -4,7 +4,7 @@
* 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
diff --git a/samples/validation/src/com/google/gwt/sample/validation/client/SampleValidator.java b/samples/validation/src/com/google/gwt/sample/validation/client/SampleValidator.java
index 14f8bb5..5f8c74c 100644
--- a/samples/validation/src/com/google/gwt/sample/validation/client/SampleValidator.java
+++ b/samples/validation/src/com/google/gwt/sample/validation/client/SampleValidator.java
@@ -19,11 +19,25 @@
import com.google.gwt.validation.client.GwtValidation;
import javax.validation.Validator;
+import javax.validation.groups.Default;
/**
* Validator marker for the Valiation Sample project. Only the classes listed in
* the {@link GwtValidation} annotation can be validated.
*/
-@GwtValidation(Person.class)
+@GwtValidation(value = Person.class,
+ groups = {
+ Default.class, SampleValidator.ClientGroup.class})
public interface SampleValidator extends Validator {
+ /**
+ * Client Validation Group
+ */
+ public interface ClientGroup {
+ }
+
+ /**
+ * Server Validation Group
+ */
+ public interface ServerGroup {
+ }
}
diff --git a/samples/validation/src/com/google/gwt/sample/validation/client/Validation.java b/samples/validation/src/com/google/gwt/sample/validation/client/Validation.java
index 6a33243..86bb36e 100644
--- a/samples/validation/src/com/google/gwt/sample/validation/client/Validation.java
+++ b/samples/validation/src/com/google/gwt/sample/validation/client/Validation.java
@@ -4,7 +4,7 @@
* 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
@@ -30,12 +30,10 @@
*/
private final GreetingServiceAsync greetingService = GWT.create(GreetingService.class);
-
/**
* This is the entry point method.
*/
public void onModuleLoad() {
-
Person person = new Person();
ValidationView view = new ValidationView(person, greetingService);
RootPanel.get("view").add(view);
diff --git a/samples/validation/src/com/google/gwt/sample/validation/server/GreetingServiceImpl.java b/samples/validation/src/com/google/gwt/sample/validation/server/GreetingServiceImpl.java
index 00a2bd8..3ee9de7 100644
--- a/samples/validation/src/com/google/gwt/sample/validation/server/GreetingServiceImpl.java
+++ b/samples/validation/src/com/google/gwt/sample/validation/server/GreetingServiceImpl.java
@@ -4,7 +4,7 @@
* 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
diff --git a/samples/validation/src/com/google/gwt/sample/validation/shared/NoOp.java b/samples/validation/src/com/google/gwt/sample/validation/shared/NoOp.java
new file mode 100644
index 0000000..197a655
--- /dev/null
+++ b/samples/validation/src/com/google/gwt/sample/validation/shared/NoOp.java
@@ -0,0 +1,46 @@
+/*
+ * 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.ElementType.TYPE;
+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;
+
+/**
+ * Test constaint that is always valid
+ */
+@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE})
+@Retention(RUNTIME)
+@Documented
+@Constraint(validatedBy = {NoOpValidator.class})
+public @interface NoOp {
+ String message() default "Hey, this can't fail!";
+
+ Class<?>[] groups() default {};
+
+ Class<? extends Payload>[] payload() default {};
+}
\ No newline at end of file
diff --git a/samples/validation/src/com/google/gwt/sample/validation/shared/NoOpValidator.java b/samples/validation/src/com/google/gwt/sample/validation/shared/NoOpValidator.java
new file mode 100644
index 0000000..348befe
--- /dev/null
+++ b/samples/validation/src/com/google/gwt/sample/validation/shared/NoOpValidator.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.validation.shared;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+
+/**
+ * This is always valid.
+ */
+public class NoOpValidator implements ConstraintValidator<NoOp, Object> {
+
+ public void initialize(NoOp constraintAnnotation) {
+ }
+
+ public boolean isValid(Object value, ConstraintValidatorContext context) {
+ return true;
+ }
+}
diff --git a/samples/validation/src/com/google/gwt/sample/validation/shared/Person.java b/samples/validation/src/com/google/gwt/sample/validation/shared/Person.java
index 27d196b..82a68eb 100644
--- a/samples/validation/src/com/google/gwt/sample/validation/shared/Person.java
+++ b/samples/validation/src/com/google/gwt/sample/validation/shared/Person.java
@@ -23,6 +23,7 @@
/**
* A sample bean to show validation on.
*/
+@NoOp
public class Person implements IsSerializable {
@NotNull
diff --git a/samples/validation/war/WEB-INF/lib/gwt-servlet.jar b/samples/validation/war/WEB-INF/lib/gwt-servlet.jar
new file mode 100644
index 0000000..bc41164
--- /dev/null
+++ b/samples/validation/war/WEB-INF/lib/gwt-servlet.jar
Binary files differ
diff --git a/samples/validation/war/favicon.ico b/samples/validation/war/favicon.ico
index 25c8d88..d7ccc73 100644
--- a/samples/validation/war/favicon.ico
+++ b/samples/validation/war/favicon.ico
Binary files differ
diff --git a/user/build.xml b/user/build.xml
index 88b61c6..60319ea 100755
--- a/user/build.xml
+++ b/user/build.xml
@@ -56,14 +56,15 @@
<pathelement location="${gwt.build}/out/dev/bin-test" />
<pathelement location="test-super" />
<pathelement location="test_i18n_${gwt.i18n.test.InnerClassChar}" />
+ <pathelement location="${gwt.tools.lib}/apache/log4j/log4j-1.2.16.jar" />
<pathelement location="${gwt.tools.lib}/cglib/cglib-2.2.jar"/>
<pathelement location="${gwt.tools.lib}/easymock/easymock.jar"/>
<pathelement location="${gwt.tools.lib}/easymock/easymockclassextension.jar"/>
<pathelement location="${gwt.tools.lib}/objectweb/asm-3.1.jar"/>
<pathelement location="${gwt.tools.lib}/javax/validation/validation-api-1.0.0.GA.jar" />
<pathelement location="${gwt.tools.lib}/javax/validation/validation-api-1.0.0.GA-sources.jar" />
- <pathelement location="${gwt.tools.lib}/apache/log4j/log4j-1.2.16.jar" />
<pathelement location="${gwt.tools.lib}/hibernate/validator/hibernate-validator-4.1.0.Final.jar" />
+ <pathelement location="${gwt.tools.lib}/hibernate/validator/hibernate-validator-4.1.0.Final-sources.jar" />
<pathelement location="${gwt.tools.lib}/slf4j/slf4j-api/slf4j-api-1.6.1.jar" />
<pathelement location="${gwt.tools.lib}/slf4j/slf4j-log4j12/slf4j-log4j12-1.6.1.jar" />
<pathelement location="${gwt.tools}/redist/json/r2_20080312/json-1.5.jar" />
@@ -85,6 +86,9 @@
<pathelement location="${gwt.tools.lib}/javax/validation/validation-api-1.0.0.GA.jar" />
<!-- The source is included so validation is available from client code -->
<pathelement location="${gwt.tools.lib}/javax/validation/validation-api-1.0.0.GA-sources.jar" />
+ <!-- Hibernate is included until we can provide the super source as an third party jar" -->
+ <pathelement location="${gwt.tools.lib}/hibernate/validator/hibernate-validator-4.1.0.Final.jar" />
+ <pathelement location="${gwt.tools.lib}/hibernate/validator/hibernate-validator-4.1.0.Final-sources.jar" />
<pathelement location="${gwt.dev.jar}" />
</classpath>
</gwt.javac>
@@ -142,6 +146,7 @@
<exclude name="javax/validation/super/javax/validation/MessageInterpolator.java"/>
<exclude name="javax/validation/super/javax/validation/Configuration.java"/>
<exclude name="javax/validation/super/javax/validation/Validation.java"/>
+ <exclude name="org/hibernate/validator/super/org/hibernate/validator/constraints/ScriptAssert.java"/>
</fileset>
<fileset dir="super/com/google/gwt/emul" />
<fileset dir="super/com/google/gwt/junit/translatable" />
diff --git a/user/src/com/google/gwt/validation/client/constraints/NotGwtCompatibleValidator.java b/user/src/com/google/gwt/validation/client/constraints/NotGwtCompatibleValidator.java
new file mode 100644
index 0000000..d963323
--- /dev/null
+++ b/user/src/com/google/gwt/validation/client/constraints/NotGwtCompatibleValidator.java
@@ -0,0 +1,58 @@
+/*
+ * 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.validation.client.constraints;
+
+import java.lang.annotation.Annotation;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+
+/**
+ * Masks a {@link ConstraintValidator} that is not GWT compatible. This
+ * validator always fails.
+ * <p>
+ * Extend this class and implement it as GWT super class. Use validation groups
+ * to keep this constraint from being validated on the client.
+ *
+ * <p>
+ * In a super source directory override your validator like this:
+ *
+ * <pre>
+ * public class MyValidator extends
+ * NotGwtCompatibleValidator <MyConstraint, MyType>{
+ * }
+ * </pre>
+ *
+ * @param <A> the constraint to validate
+ * @param <T> the type to validate
+ */
+public abstract class NotGwtCompatibleValidator<A extends Annotation, T>
+ implements
+ ConstraintValidator<A, T> {
+
+
+ public final void initialize(A constraintAnnotation) {
+ }
+
+ /**
+ * Always fails.
+ */
+ public final boolean isValid(T value, ConstraintValidatorContext context) {
+ // TODO (nchalko) add a custom message
+ return false;
+ }
+
+}
diff --git a/user/src/com/google/gwt/validation/client/impl/AbstractGwtSpecificValidator.java b/user/src/com/google/gwt/validation/client/impl/AbstractGwtSpecificValidator.java
index 3894f33..34a1a5e 100644
--- a/user/src/com/google/gwt/validation/client/impl/AbstractGwtSpecificValidator.java
+++ b/user/src/com/google/gwt/validation/client/impl/AbstractGwtSpecificValidator.java
@@ -16,6 +16,9 @@
package com.google.gwt.validation.client.impl;
import java.lang.annotation.Annotation;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
import java.util.Set;
import javax.validation.ConstraintValidator;
@@ -32,6 +35,31 @@
GwtSpecificValidator<G> {
/**
+ * Builds attributes one at a time.
+ * <p>
+ * Used to create a attribute map for annotations.
+ */
+ public static final class AttributeBuilder {
+ private final HashMap<String, Object> tempMap = new HashMap<String, Object>();
+
+ private AttributeBuilder() {
+ }
+
+ public Map<String, Object> build() {
+ return Collections.unmodifiableMap(tempMap);
+ }
+
+ public AttributeBuilder put(String key, Object value) {
+ tempMap.put(key, value);
+ return this;
+ }
+ }
+
+ public static AttributeBuilder attributeBuilder() {
+ return new AttributeBuilder();
+ }
+
+ /**
* @param <A>
* @param <T>
* @param <V>
@@ -45,7 +73,7 @@
*/
protected <A extends Annotation, T, V> void validate(
GwtValidationContext<T> context, Set<ConstraintViolation<T>> violations,
- G object, V value, ConstraintValidator<A, V> validator,
+ G object, V value, ConstraintValidator<A, ? super V> validator,
ConstraintDescriptorImpl<A> constraintDescriptor, Class<?>[] groups) {
validator.initialize(constraintDescriptor.getAnnotation());
ConstraintValidatorContextImpl<A, V> constraintValidatorContext =
diff --git a/user/src/com/google/gwt/validation/client/impl/AbstractGwtValidator.java b/user/src/com/google/gwt/validation/client/impl/AbstractGwtValidator.java
index e5b7487..5e5a552 100644
--- a/user/src/com/google/gwt/validation/client/impl/AbstractGwtValidator.java
+++ b/user/src/com/google/gwt/validation/client/impl/AbstractGwtValidator.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -15,6 +15,10 @@
*/
package com.google.gwt.validation.client.impl;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
import javax.validation.ValidationException;
import javax.validation.Validator;
@@ -25,7 +29,34 @@
*/
public abstract class AbstractGwtValidator implements Validator {
+ private final Set<Class<?>> validGroups;
+
+ /**
+ *
+ * @param groups list of valid groups. An empty list defaults to just the
+ * {@link javax.validation.groups.Default} group.
+ */
+ public AbstractGwtValidator(Class<?>... groups) {
+ validGroups = new HashSet<Class<?>>(Arrays.asList(groups));
+ }
+
public <T> T unwrap(Class<T> type) {
throw new ValidationException();
}
+
+ protected void checkGroups(Class<?>... groups) {
+ // an empty list of valid groups means all groups are valid.
+ if (!validGroups.isEmpty()
+ && !validGroups.containsAll(Arrays.asList(groups))) {
+ throw new IllegalArgumentException(this.getClass()
+ + " only processes the following groups " + validGroups);
+ }
+ }
+
+ protected void checkNotNull(Object object, String name)
+ throws IllegalArgumentException {
+ if (object == null) {
+ throw new IllegalArgumentException(name + " can not be null.");
+ }
+ }
}
diff --git a/user/src/com/google/gwt/validation/client/impl/ConstraintDescriptorImpl.java b/user/src/com/google/gwt/validation/client/impl/ConstraintDescriptorImpl.java
index 5ef4804..2485a3d 100644
--- a/user/src/com/google/gwt/validation/client/impl/ConstraintDescriptorImpl.java
+++ b/user/src/com/google/gwt/validation/client/impl/ConstraintDescriptorImpl.java
@@ -15,7 +15,10 @@
*/
package com.google.gwt.validation.client.impl;
+
import java.lang.annotation.Annotation;
+import java.util.Arrays;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -47,7 +50,7 @@
private boolean reportAsSingleViolation;
public ConstraintDescriptorImpl<T> build() {
- return new ConstraintDescriptorImpl<T>(
+ return new ConstraintDescriptorImpl<T>(//
annotation, //
groups, //
payload, //
@@ -79,16 +82,37 @@
return this;
}
+ /**
+ * @param classes
+ * @return
+ */
+ public Builder<T> setConstraintValidatorClasses(
+ Class<? extends ConstraintValidator<T, ?>>[] constraintValidatorClasses) {
+ List<Class<? extends ConstraintValidator<T, ?>>> list = Arrays.asList(constraintValidatorClasses);
+ setConstraintValidatorClasses(list);
+ return this;
+ }
+
public Builder<T> setGroups(Set<Class<?>> groups) {
this.groups = groups;
return this;
}
+ public Builder<T> setGroups(Class<?>[] classes) {
+ setGroups(new HashSet<Class<?>>(Arrays.asList(classes)));
+ return this;
+ }
+
public Builder<T> setPayload(Set<Class<? extends Payload>> payload) {
this.payload = payload;
return this;
}
+ public Builder<T> setPayload(Class<? extends Payload>[] classes) {
+ setPayload(new HashSet<Class<? extends Payload>>(Arrays.asList(classes)));
+ return this;
+ }
+
public Builder<T> setReportAsSingleViolation(boolean reportAsSingleViolation) {
this.reportAsSingleViolation = reportAsSingleViolation;
return this;
diff --git a/user/src/com/google/gwt/validation/rebind/AbstractCreator.java b/user/src/com/google/gwt/validation/rebind/AbstractCreator.java
index 24c1111..c40ebc6 100644
--- a/user/src/com/google/gwt/validation/rebind/AbstractCreator.java
+++ b/user/src/com/google/gwt/validation/rebind/AbstractCreator.java
@@ -17,6 +17,7 @@
import com.google.gwt.core.ext.GeneratorContext;
import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JPackage;
import com.google.gwt.user.rebind.AbstractSourceCreator;
@@ -46,7 +47,7 @@
this.validatorType = validatorType;
}
- public final String create() {
+ public final String create() throws UnableToCompleteException {
SourceWriter sourceWriter = getSourceWriter(logger, context);
if (sourceWriter != null) {
writeClassBody(sourceWriter);
@@ -55,6 +56,12 @@
return getQualifiedName();
}
+ protected void addImports(ClassSourceFileComposerFactory composerFactory, Class<?>... imports) {
+ for (Class<?> imp : imports) {
+ composerFactory.addImport(imp.getCanonicalName());
+ }
+ }
+
protected abstract void compose(ClassSourceFileComposerFactory composerFactory);
protected final String getPackage() {
@@ -63,7 +70,8 @@
return packageName;
}
- protected abstract void writeClassBody(SourceWriter sourceWriter);
+ protected abstract void writeClassBody(SourceWriter sourceWriter)
+ throws UnableToCompleteException;
private String getQualifiedName() {
String packageName = getPackage();
diff --git a/user/src/com/google/gwt/validation/rebind/BeanHelper.java b/user/src/com/google/gwt/validation/rebind/BeanHelper.java
index 97e52ea..021c7c3 100644
--- a/user/src/com/google/gwt/validation/rebind/BeanHelper.java
+++ b/user/src/com/google/gwt/validation/rebind/BeanHelper.java
@@ -17,19 +17,35 @@
import com.google.gwt.core.ext.typeinfo.JClassType;
+import javax.validation.metadata.BeanDescriptor;
+
/**
* A simple struct for the various values associated with a Bean that can be
* validated.
*/
final class BeanHelper {
+ private final BeanDescriptor beanDescriptor;
private final JClassType jClass;
- public BeanHelper(JClassType jClass) {
+ public BeanHelper(JClassType jClass,
+ BeanDescriptor beanDescriptor) {
super();
+ this.beanDescriptor = beanDescriptor;
this.jClass = jClass;
}
+ public BeanDescriptor getBeanDescriptor() {
+ return beanDescriptor;
+ }
+
+ /*
+ * The server side validator needs an actual class.
+ */
+ public Class<?> getClazz() throws ClassNotFoundException {
+ return Class.forName(jClass.getQualifiedSourceName());
+ }
+
public String getDescriptorName() {
return jClass.getName() + "Descriptor";
@@ -51,4 +67,4 @@
public String toString() {
return getTypeCanonicalName();
}
-}
\ No newline at end of file
+}
diff --git a/user/src/com/google/gwt/validation/rebind/GwtSpecificValidatorCreator.java b/user/src/com/google/gwt/validation/rebind/GwtSpecificValidatorCreator.java
index be6098a..f6a7500 100644
--- a/user/src/com/google/gwt/validation/rebind/GwtSpecificValidatorCreator.java
+++ b/user/src/com/google/gwt/validation/rebind/GwtSpecificValidatorCreator.java
@@ -18,19 +18,33 @@
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.ext.GeneratorContext;
import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JClassType;
+import com.google.gwt.core.ext.typeinfo.JType;
+import com.google.gwt.core.ext.typeinfo.NotFoundException;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
+import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
import com.google.gwt.user.rebind.SourceWriter;
import com.google.gwt.validation.client.impl.AbstractGwtSpecificValidator;
+import com.google.gwt.validation.client.impl.ConstraintDescriptorImpl;
import com.google.gwt.validation.client.impl.GwtBeanDescriptor;
import com.google.gwt.validation.client.impl.GwtValidationContext;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Collection;
import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
+import javax.validation.ConstraintValidator;
import javax.validation.ConstraintViolation;
-import javax.validation.metadata.BeanDescriptor;
+import javax.validation.Payload;
+import javax.validation.Validator;
+import javax.validation.metadata.ConstraintDescriptor;
+import javax.validation.metadata.PropertyDescriptor;
/**
* Creates a {@link com.google.gwt.validation.client.GwtSpecificValidator}.
@@ -40,42 +54,122 @@
public class GwtSpecificValidatorCreator extends AbstractCreator {
- final JClassType beanType;
+ /**
+ * Returns the literal value of an object that is suitable for inclusion in
+ * Java Source code.
+ *
+ * <p>
+ * Supports all types that {@link Annotation) value can have.
+ *
+ *
+ * @throws IllegalArgumentException if the type of the object does not have a java literal form.
+ */
+ public static String asLiteral(Object value) throws IllegalArgumentException {
+ Class<?> clazz = value.getClass();
+ JProgram jProgram = new JProgram();
+
+ if (clazz.isArray()) {
+ StringBuilder sb = new StringBuilder();
+ Object[] array = (Object[]) value;
+
+ sb.append("new " + clazz.getComponentType().getCanonicalName() + "[] ");
+ sb.append("{");
+ boolean first = true;
+ for (Object object : array) {
+ if (first) {
+ first = false;
+ } else {
+ sb.append(",");
+ }
+ sb.append(asLiteral(object));
+ }
+ sb.append("}");
+ return sb.toString();
+ }
+
+ if (value instanceof Class) {
+ return ((Class<?>) ((Class<?>) value)).getCanonicalName() + ".class";
+ }
+ if (value instanceof Double) {
+ return jProgram.getLiteralDouble(((Double) value).doubleValue()).toSource();
+ }
+ if (value instanceof Integer) {
+ return jProgram.getLiteralInt(((Integer) value).intValue()).toSource();
+ }
+ if (value instanceof String) {
+ return '"' + ((String) value).toString().replace("\"", "\\\"") + '"';
+ }
+ // TODO(nchalko) handle the rest of the literal types
+ throw new IllegalArgumentException(value.getClass()
+ + " is can not be represented as a Java Literal.");
+ }
private BeanHelper beanHelper;
+ private final JClassType beanType;
private final TypeOracle oracle;
+ private final Validator serverSideValidator;
+
public GwtSpecificValidatorCreator(JClassType validatorType,
JClassType beanType, BeanHelper beanHelper, TreeLogger logger,
- GeneratorContext context) {
+ GeneratorContext context, Validator serverSideValidator) {
super(context, logger, validatorType);
this.oracle = context.getTypeOracle();
this.beanType = beanType;
this.beanHelper = beanHelper;
+ this.serverSideValidator = serverSideValidator;
+ }
+
+ protected <T> T[] asArray(Collection<?> collection, T[] array) {
+ if (collection == null) {
+ return null;
+ }
+ return collection.toArray(array);
+ }
+
+ protected String asGetter(PropertyDescriptor p) {
+ return "get" + capitalizeFirstLetter(p.getPropertyName());
+ }
+
+ protected String capitalizeFirstLetter(String propertyName) {
+ if (propertyName == null) {
+ return null;
+ }
+ if (propertyName.length() == 0) {
+ return "";
+ }
+ String cap = propertyName.substring(0, 1).toUpperCase();
+ if (propertyName.length() > 1) {
+ cap += propertyName.substring(1);
+ }
+ return cap;
}
@Override
protected void compose(ClassSourceFileComposerFactory composerFactory) {
- Class<?>[] imports = new Class<?>[]{
- GWT.class,
- GwtBeanDescriptor.class,
- GwtValidationContext.class,
- Set.class,
- HashSet.class,
- ConstraintViolation.class,
- BeanDescriptor.class,
- };
- for (Class<?> imp : imports) {
- composerFactory.addImport(imp.getCanonicalName());
- }
-
+ addImports(composerFactory, GWT.class, GwtBeanDescriptor.class,
+ GwtValidationContext.class, Set.class, HashSet.class,
+ ConstraintViolation.class, Annotation.class);
composerFactory.setSuperclass(AbstractGwtSpecificValidator.class.getCanonicalName()
+ "<" + beanType.getQualifiedSourceName() + ">");
-
composerFactory.addImplementedInterface(validatorType.getName());
}
+ protected String constraintDescriptorVar(String name, int count) {
+ String s = name + "_c" + count;
+ return s;
+ }
+
+ protected Class<? extends ConstraintValidator<? extends Annotation, ?>> getValidatorForType(
+ ConstraintDescriptor<? extends Annotation> constraint, Class<?> clazz) {
+ // TODO(nchalko) implement per spec
+ Class<? extends ConstraintValidator<? extends Annotation, ?>> validatorClass = constraint.getConstraintValidatorClasses().get(
+ 0);
+ return validatorClass;
+ }
+
@Override
- protected void writeClassBody(SourceWriter sw) {
+ protected void writeClassBody(SourceWriter sw)
+ throws UnableToCompleteException {
writeFields(sw);
sw.println();
writeValidate(sw);
@@ -85,21 +179,167 @@
writeValidateValue(sw);
sw.println();
writeGetDescriptor(sw);
+ sw.println();
+ writePropertyValidtors(sw);
}
- protected void writeNewViolations(SourceWriter sw) {
- // Set<ConstraintViolation<T>> violations = new
- // HashSet<ConstraintViolation<T>>();
- sw.println("Set<ConstraintViolation<T>> violations = new HashSet<ConstraintViolation<T>>();");
+ protected void writeConstraintDescriptor(SourceWriter sw,
+ ConstraintDescriptor<? extends Annotation> constraint,
+ String constraintDescripotorVar) throws UnableToCompleteException {
+ Class<? extends Annotation> annotationType = constraint.getAnnotation().annotationType();
+
+ // First list all composing constraints
+ int count = 0;
+ for (ConstraintDescriptor<?> composingConstraint : constraint.getComposingConstraints()) {
+ writeConstraintDescriptor(sw, composingConstraint,
+ constraintDescripotorVar + "_" + count++);
+ }
+
+ // ConstraintDescriptorImpl<MyAnnotation> constraintDescriptor = ;
+ sw.print(ConstraintDescriptorImpl.class.getCanonicalName());
+ sw.print("<");
+
+ sw.print(annotationType.getCanonicalName());
+ sw.print(">");
+
+ sw.println(" " + constraintDescripotorVar + " = ");
+ sw.indent();
+ sw.indent();
+
+ // ConstraintDescriptorImpl.<MyConstraint> builder()
+ sw.print(ConstraintDescriptorImpl.class.getCanonicalName());
+ sw.print(".<");
+
+ sw.print(annotationType.getCanonicalName());
+ sw.println("> builder()");
+ sw.indent();
+ sw.indent();
+
+ // .setAnnotation(new MyAnnotation )
+ sw.println(".setAnnotation( ");
+ sw.indent();
+ sw.indent();
+ writeNewAnnotation(sw, constraint);
+ sw.println(")");
+ sw.outdent();
+ sw.outdent();
+
+ // .setAttributes(builder()
+ sw.println(".setAttributes(attributeBuilder()");
+ sw.indent();
+
+ for (Map.Entry<String, Object> entry : constraint.getAttributes().entrySet()) {
+ // .put(key, value)
+ sw.print(".put(");
+ sw.print(asLiteral(entry.getKey()));
+ sw.print(", ");
+ sw.print(asLiteral(entry.getValue()));
+ sw.println(")");
+ }
+
+ // .build())
+ sw.println(".build())");
+ sw.outdent();
+
+ // .setConstraintValidatorClasses(classes )
+ sw.print(".setConstraintValidatorClasses(");
+ sw.print(asLiteral(asArray(constraint.getConstraintValidatorClasses(),
+ new Class[0])));
+ sw.println(")");
+
+ // .getGroups(groups)
+ sw.print(".setGroups(");
+ Set<Class<?>> groups = constraint.getGroups();
+ sw.print(asLiteral(asArray(groups, new Class<?>[0])));
+ sw.println(")");
+
+ // .setPayload(payload)
+ sw.print(".setPayload(");
+ Set<Class<? extends Payload>> payload = constraint.getPayload();
+ sw.print(asLiteral(asArray(payload, new Class[0])));
+ sw.println(")");
+
+ // .setsetReportAsSingleViolation(boolean )
+ sw.print(".setReportAsSingleViolation(");
+ sw.print(Boolean.valueOf(constraint.isReportAsSingleViolation()).toString());
+ sw.println(")");
+
+ // .build();
+ sw.println(".build();");
+ sw.outdent();
+ sw.outdent();
+
+ sw.outdent();
+ sw.outdent();
+ sw.println();
+ }
+
+ protected void writeValidateInterfaces(SourceWriter sw, Class<?> clazz) {
+ for (Class<?> type : clazz.getInterfaces()) {
+ if (serverSideValidator.getConstraintsForClass(type).isBeanConstrained()) {
+ // MyInterface_GwtSpecificValidator validator =
+ // GWT.create(MyInterface_GwtSpecificValidator);
+ // TODO (nchalko) validate interface. This Requires the
+ // MyInterface_GwtSpecficValidator
+ // interface to already be generated.
+ sw.print("//TODO(nchalko) GWT.create(");
+ sw.print(type.getCanonicalName());
+ sw.println("_GwtSpecificValidator);");
+
+ // voilations.add(validator.validate(context,this,groups));
+ }
+
+ writeValidateInterfaces(sw, type);
+ }
+ }
+
+/**
+ * @param beanHelper2
+ * @param p
+ * @return
+ */
+private boolean hasGetter(PropertyDescriptor p) {
+ JType[] paramTypes = new JType[]{};
+ try {
+ beanType.getMethod(asGetter(p), paramTypes);
+ return true;
+ } catch (NotFoundException e) {
+ return false;
+ }
+
+}
+
+ private String validateMethodName(PropertyDescriptor p) {
+ return "validateProperty_" + p.getPropertyName();
}
/**
* @param sourceWriter
+ * @throws UnableToCompleteException
*/
- private void writeFields(SourceWriter sw) {
+ private void writeFields(SourceWriter sw) throws UnableToCompleteException {
// MyBeanDescriptor beanDescriptor = GWT.create(MyBeanDescriptor);
sw.println(GwtBeanDescriptor.class.getCanonicalName());
- sw.println(" beanDescriptor = null; // GWT.create");
+ // TODO(nchalko) implement BeanDescriptor Generator
+ sw.println(" beanDescriptor = null; //TODO(nchalko) GWT.create");
+
+ // Create a variable for each constraint of each property
+ for (PropertyDescriptor p : beanHelper.getBeanDescriptor().getConstrainedProperties()) {
+ int count = 0;
+ for (ConstraintDescriptor<?> constraint : p.getConstraintDescriptors()) {
+ count++; // index starts at one.
+ writeConstraintDescriptor(sw, constraint,
+ constraintDescriptorVar(p.getPropertyName(), count));
+ }
+ }
+
+ // Create a variable for each constraint of this class.
+ int count = 0;
+ for (ConstraintDescriptor<?> constraint : beanHelper.getBeanDescriptor().getConstraintDescriptors()) {
+ count++; // index starts at one.
+ writeConstraintDescriptor(sw, constraint,
+ constraintDescriptorVar("this", count));
+ }
}
private void writeGetDescriptor(SourceWriter sw) {
@@ -109,13 +349,78 @@
sw.println("getConstraints() {");
sw.indent();
- // return beanDescriptor;
+ // return beanDescriptor;
sw.println("return beanDescriptor;");
sw.outdent();
sw.println("}");
}
+ private void writeNewAnnotation(SourceWriter sw,
+ ConstraintDescriptor<? extends Annotation> constraint)
+ throws UnableToCompleteException {
+ Annotation annotation = constraint.getAnnotation();
+ Class<? extends Annotation> annotationType = annotation.annotationType();
+
+ // new MyAnnotation () {
+ sw.print("new ");
+ sw.print(annotationType.getCanonicalName());
+ sw.println("(){");
+ sw.indent();
+ sw.indent();
+
+ // public Class<? extends Annotation> annotationType() { return
+ // MyAnnotation.class; }
+ sw.print("public Class<? extends Annotation> annotationType() { return ");
+ sw.print(annotationType.getCanonicalName());
+ sw.println(".class; }");
+
+ for (Method method : annotationType.getMethods()) {
+ // method.isAbstract would be better
+ if (method.getDeclaringClass().equals(annotation.annotationType())) {
+ // public returnType method() { return value ;}
+ sw.print("public ");
+ sw.print(method.getReturnType().getCanonicalName()); // TODO handle
+ // generics
+ sw.print(" ");
+ sw.print(method.getName());
+ sw.print("() { return ");
+
+ try {
+ Object value = method.invoke(annotation);
+ sw.print(asLiteral(value));
+ } catch (IllegalArgumentException e) {
+ throw error(logger, e);
+ } catch (IllegalAccessException e) {
+ throw error(logger, e);
+ } catch (InvocationTargetException e) {
+ throw error(logger, e);
+ }
+ sw.println(";}");
+ }
+ }
+
+ sw.outdent();
+ sw.outdent();
+ sw.println("}");
+ }
+
+ private void writeNewViolations(SourceWriter sw) {
+ // Set<ConstraintViolation<T>> violations = new
+ // HashSet<ConstraintViolation<T>>();
+ sw.println("Set<ConstraintViolation<T>> violations = new HashSet<ConstraintViolation<T>>();");
+ }
+
+ /**
+ * @param sw
+ */
+ private void writePropertyValidtors(SourceWriter sw) {
+ for (PropertyDescriptor p : beanHelper.getBeanDescriptor().getConstrainedProperties()) {
+ writeValidatePropertyMethod(sw, p);
+ sw.println();
+ }
+ }
+
private void writeValidate(SourceWriter sw) {
// public <T> Set<ConstraintViolation<T>> validate(
sw.println("public <T> Set<ConstraintViolation<T>> validate(");
@@ -130,8 +435,77 @@
writeNewViolations(sw);
- // TODO(nchalko) loop over all constraints
+ if (beanHelper.getBeanDescriptor().isBeanConstrained()) {
+ // /// For each group
+
+ // TODO(nchalko) handle the sequence in the AbstractValidator
+ // Let the GwtSpecificValidators only take a single group.
+
+ // See JSR 303 section 3.5
+ // all reachable fields
+ // all reachable getters (both) at once
+
+ Set<PropertyDescriptor> properties = beanHelper.getBeanDescriptor().getConstrainedProperties();
+
+ for (PropertyDescriptor p : properties) {
+ writeValidatePropertyCall(sw, p);
+ }
+
+ // all class level constraints
+ // including super classes
+ // including super interfaces
+
+ int count = 0;
+ Class<?> clazz = null;
+ try {
+ clazz = beanHelper.getClazz();
+ } catch (ClassNotFoundException e) {
+ error(logger, e);
+ }
+ for (ConstraintDescriptor<?> constraint : beanHelper.getBeanDescriptor().findConstraints().getConstraintDescriptors()) {
+ count++; // index starts at 1
+ Class<? extends ConstraintValidator<? extends Annotation, ?>> validatorClass = getValidatorForType(
+ constraint, clazz);
+ // TODO(nchalko) handle constraint.isReportAsSingleViolation() and
+ // hasComposingConstraints
+
+ // validate(context, violations, object, value, validator,
+ // constraintDescriptor, groups);
+ sw.print("validate(context, violations, null, object, ");
+ // new MyValidtor();
+ sw.print("new ");
+ sw.print(validatorClass.getCanonicalName());
+ sw.print("(), "); // new one each time because validators are not thread
+ // safe
+ sw.print(constraintDescriptorVar("this", count));
+ sw.println(", groups);");
+ }
+
+ // validate all super classes and interfaces
+
+ Class<?> superClass = clazz.getSuperclass();
+ writeValidateInterfaces(sw, clazz);
+ while (superClass != null) {
+ if (serverSideValidator.getConstraintsForClass(superClass).isBeanConstrained()) {
+ // MySuper_GwtSpecificValidator validator =
+ // GWT.create(MySuper_GwtSpecificValidator);
+ sw.print("// GWT.create(");
+ sw.print(superClass.getCanonicalName());
+ sw.println("_GwtSpecificValidator);");
+ }
+ writeValidateInterfaces(sw, superClass);
+ superClass = superClass.getSuperclass();
+ }
+
+ // all reachable and cascadable associations
+
+ // TODO(nchalko) validationg the object graph will require top level
+ // interfaces for the classes
+ // that already generated
+
+ beanType.getFields();
+ }
// return violations;
sw.println("return violations;");
@@ -155,7 +529,38 @@
writeNewViolations(sw);
- // TODO(nchalko) case statement for propertyName
+ // TODO(nchalko) check if it is a valid propertyName
+
+ for (PropertyDescriptor property : beanHelper.getBeanDescriptor().getConstrainedProperties()) {
+ // if (propertyName.equals(myPropety)) {
+ sw.print("if (propertyName.equals(\"");
+ sw.print(property.getPropertyName());
+ sw.println("\")) {");
+ sw.indent();
+
+ // validate_myProperty
+ writeValidatePropertyCall(sw, property);
+
+ // }
+ sw.outdent();
+ sw.print("} else ");
+ }
+
+ // {
+ sw.println("{");
+ sw.indent();
+
+ // throw new IllegalArgumentException(propertyName
+ // +"is not a valid property of myClass");
+ sw.print("throw new ");
+ sw.print(IllegalArgumentException.class.getCanonicalName());
+ sw.print("( propertyName +\" is not a valid property of ");
+ sw.print(beanType.getQualifiedSourceName());
+ sw.println("\");");
+
+ // }
+ sw.outdent();
+ sw.println("}");
// return violations;
sw.println("return violations;");
@@ -164,6 +569,64 @@
sw.println("}");
}
+ private void writeValidatePropertyCall(SourceWriter sw, PropertyDescriptor p) {
+ String propertyName = p.getPropertyName();
+ // validateProperty_<<field>>(context, object, object.getLastName(),
+ // groups));
+ sw.print(validateMethodName(p));
+ sw.print("(context, ");
+ sw.print("violations, ");
+ sw.print("object, ");
+ sw.print("object.");
+ if (hasGetter(p)) {
+ sw.print(asGetter(p) + "()");
+ } else {
+ sw.print(propertyName);
+ }
+ sw.print(", ");
+ sw.println("groups);");
+ }
+
+ private void writeValidatePropertyMethod(SourceWriter sw, PropertyDescriptor p) {
+ // private final <T> void validateProperty_<p>(
+ sw.print("private final <T> void ");
+ sw.print(validateMethodName(p));
+ sw.println("(");
+
+ // GwtValidationContext<T> context, Set<ConstraintViolation<T>> violations,
+ // BeanType object, <Type> value, Class<?>... groups) {
+ sw.indent();
+ sw.indent();
+ sw.println("GwtValidationContext<T> context,");
+ sw.println("Set<ConstraintViolation<T>> violations,");
+ sw.println(beanHelper.getTypeCanonicalName() + " object,");
+ sw.print(p.getElementClass().getCanonicalName());
+ sw.println(" value,");
+ sw.println("Class<?>... groups) {");
+ sw.outdent();
+ int count = 0;
+ for (ConstraintDescriptor<?> constraint : p.getConstraintDescriptors()) {
+ count++; // index starts at 1
+ Class<? extends ConstraintValidator<? extends Annotation, ?>> validatorClass = getValidatorForType(
+ constraint, p.getElementClass());
+ // TODO(nchalko) handle constraint.isReportAsSingleViolation() and
+ // hasComposingConstraints
+
+ // validate(context, violations, object, value, validator,
+ // constraintDescriptor, groups);
+ sw.print("validate(context, violations, object, value, ");
+ // new MyValidtor();
+ sw.print("new ");
+ sw.print(validatorClass.getCanonicalName());
+ sw.print("(), "); // new one each time because validators are not thread
+ // safe
+ sw.print(constraintDescriptorVar(p.getPropertyName(), count));
+ sw.println(", groups);");
+ }
+ sw.outdent();
+ sw.println("}");
+ }
+
private void writeValidateValue(SourceWriter sw) {
// public <T> Set<ConstraintViolation<T>> validate(
sw.println("public <T> Set<ConstraintViolation<T>> validateValue(");
@@ -181,7 +644,47 @@
writeNewViolations(sw);
- // TODO(nchalko) case statement for propertyName
+ // TODO(nchalko) check if it is a valid propertyName
+
+ for (PropertyDescriptor property : beanHelper.getBeanDescriptor().getConstrainedProperties()) {
+ // if (propertyName.equals(myPropety)) {
+ sw.print("if (propertyName.equals(\"");
+ sw.print(property.getPropertyName());
+ sw.println("\")) {");
+ sw.indent();
+
+ // validateProperty_<<field>>(context, (MyType) null,
+ // object.getLastName(),
+ // groups));
+ sw.print(validateMethodName(property));
+ sw.print("(context, ");
+ sw.print("violations, ");
+ sw.print("null, ");
+ sw.print("(");
+ sw.print(property.getElementClass().getCanonicalName());
+ sw.print(") value, ");
+ sw.println("groups);");
+
+ // }
+ sw.outdent();
+ sw.print("} else ");
+ }
+
+ // {
+ sw.println("{");
+ sw.indent();
+
+ // throw new IllegalArgumentException(propertyName
+ // +"is not a valid property of myClass");
+ sw.print("throw new ");
+ sw.print(IllegalArgumentException.class.getCanonicalName());
+ sw.print("( propertyName +\" is not a valid property of ");
+ sw.print(beanType.getQualifiedSourceName());
+ sw.println("\");");
+
+ // }
+ sw.outdent();
+ sw.println("}");
// return violations;
sw.println("return violations;");
diff --git a/user/src/com/google/gwt/validation/rebind/GwtSpecificValidatorGenerator.java b/user/src/com/google/gwt/validation/rebind/GwtSpecificValidatorGenerator.java
index 71cee0f..0f59f7c 100644
--- a/user/src/com/google/gwt/validation/rebind/GwtSpecificValidatorGenerator.java
+++ b/user/src/com/google/gwt/validation/rebind/GwtSpecificValidatorGenerator.java
@@ -24,6 +24,9 @@
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.validation.client.impl.GwtSpecificValidator;
+import javax.validation.Validation;
+import javax.validation.Validator;
+
/**
* Generates a {@link com.google.gwt.validation.client.GwtSpecificValidator}.
* <p>
@@ -31,6 +34,8 @@
*/
public class GwtSpecificValidatorGenerator extends Generator {
+ private final Validator serverSideValidor = Validation.buildDefaultValidatorFactory().getValidator();
+
@Override
public String generate(TreeLogger logger, GeneratorContext context,
String typeName) throws UnableToCompleteException {
@@ -59,7 +64,7 @@
}
AbstractCreator creator = new GwtSpecificValidatorCreator(validatorType,
- beanType, beanHelper, logger, context);
+ beanType, beanHelper, logger, context, serverSideValidor);
return creator.create();
}
diff --git a/user/src/com/google/gwt/validation/rebind/ValidatorCreator.java b/user/src/com/google/gwt/validation/rebind/ValidatorCreator.java
index e64949c..8d52981 100644
--- a/user/src/com/google/gwt/validation/rebind/ValidatorCreator.java
+++ b/user/src/com/google/gwt/validation/rebind/ValidatorCreator.java
@@ -19,7 +19,6 @@
import com.google.gwt.core.ext.GeneratorContext;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.typeinfo.JClassType;
-import com.google.gwt.core.ext.typeinfo.JPackage;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
import com.google.gwt.user.rebind.SourceWriter;
@@ -29,19 +28,20 @@
import com.google.gwt.validation.client.impl.GwtSpecificValidator;
import com.google.gwt.validation.client.impl.GwtValidationContext;
-import java.io.PrintWriter;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import javax.validation.ConstraintViolation;
+import javax.validation.Validation;
+import javax.validation.Validator;
import javax.validation.metadata.BeanDescriptor;
/**
* Class that creates the validator for the given input class.
*/
-public class ValidatorCreator {
+public class ValidatorCreator extends AbstractCreator {
// stash the map in a ThreadLocal, since each GWT module lives in its own
// thread in DevMode
@@ -61,68 +61,53 @@
}
private final Map<JClassType, BeanHelper> beansToValidate = new HashMap<JClassType, BeanHelper>();
- private final GeneratorContext context;
- private final TreeLogger logger;
- private final JClassType validatorType;
+ private final GwtValidation gwtValidation;
+ private final Validator serverSideValidor = Validation.buildDefaultValidatorFactory().getValidator();
- public ValidatorCreator(JClassType validatorType,
- GwtValidation gwtValidation, TreeLogger logger,
+ public ValidatorCreator(JClassType validatorType, //
+ GwtValidation gwtValidation, //
+ TreeLogger logger, //
GeneratorContext context) {
- this.validatorType = validatorType;
- this.logger = logger;
- this.context = context;
+ super(context, logger, validatorType);
+ this.gwtValidation = gwtValidation;
TypeOracle oracle = context.getTypeOracle();
for (Class<?> clazz : gwtValidation.value()) {
JClassType jClass = oracle.findType(clazz.getCanonicalName());
- BeanHelper helper = new BeanHelper(jClass);
+ BeanHelper helper = new BeanHelper(jClass,
+ serverSideValidor.getConstraintsForClass(clazz));
beansToValidate.put(jClass, helper);
}
threadLocalHelperMap.get().putAll(beansToValidate);
}
- public String create() {
- SourceWriter sourceWriter = getSourceWriter(logger, context);
- if (sourceWriter != null) {
+ @Override
+ protected void compose(ClassSourceFileComposerFactory composerFactory) {
+ addImports(composerFactory,
+ GWT.class,
+ GwtBeanDescriptor.class,
+ GwtSpecificValidator.class,
+ GwtValidationContext.class,
+ Set.class,
+ ConstraintViolation.class,
+ BeanDescriptor.class);
+ composerFactory.setSuperclass(AbstractGwtValidator.class.getCanonicalName());
+ composerFactory.addImplementedInterface(this.validatorType.getQualifiedSourceName());
+ }
+
+ @Override
+ protected void writeClassBody(SourceWriter sourceWriter) {
writeTypeSupport(sourceWriter);
+ sourceWriter.println();
+ writeConstructor(sourceWriter);
+ sourceWriter.println();
writeValidate(sourceWriter);
+ sourceWriter.println();
writeValidateProperty(sourceWriter);
+ sourceWriter.println();
writeValidateValue(sourceWriter);
+ sourceWriter.println();
writeGetConstraintsForClass(sourceWriter);
-
- sourceWriter.commit(logger);
- }
- return getQaulifiedName();
- }
-
- protected void writeContext(SourceWriter sourceWriter, BeanHelper bean,
- String objectName) {
- sourceWriter.print(GwtValidationContext.class.getCanonicalName()
- + "<T> context = new " + GwtValidationContext.class.getCanonicalName()
- + "<T>(" + objectName + ",");
- sourceWriter.println(bean.getValidatorInstanceName()
- + ".getConstraints());");
- }
-
- protected void writeGetConstraintsForClass(SourceWriter sourceWriter) {
- sourceWriter.println("public BeanDescriptor getConstraintsForClass(Class<?> clazz) {");
- sourceWriter.indent();
- sourceWriter.println("return null;");
- sourceWriter.outdent();
- sourceWriter.println("}");
- sourceWriter.println();
- }
-
- protected void writeIfEqulsBeanType(SourceWriter sourceWriter, BeanHelper bean) {
- sourceWriter.println("if (object.getClass().equals("
- + bean.getTypeCanonicalName() + ".class)) {");
- }
-
- protected void writeThrowIllegalArgumnet(SourceWriter sourceWriter) {
- sourceWriter.print("throw new IllegalArgumentException(\""
- + this.validatorType.getName() + " can only validate ");
- sourceWriter.print(beansToValidate.toString());
- sourceWriter.println("\");");
}
protected void writeTypeSupport(SourceWriter sw) {
@@ -142,47 +127,129 @@
sw.print("private final " + bean.getValidatorName() + " ");
sw.print(bean.getValidatorInstanceName());
- sw.print(" = GWT.create(" + bean.getValidatorName() + ".class);");
- sw.println();
+ sw.println(" = GWT.create(" + bean.getValidatorName() + ".class);");
}
}
- protected void writeValidate(SourceWriter sw) {
+ private String getQaulifiedName() {
+ return validatorType.getQualifiedSourceName() + "Impl";
+ }
+
+ private String getSimpleName() {
+ return validatorType.getSimpleSourceName() + "Impl";
+ }
+
+ private void writeConstructor(SourceWriter sw) {
+ // public MyValidator() {
+ sw.println("public " + getSimpleName() + "() {");
+ sw.indent();
+
+ // super( <<groups>>);
+ sw.print("super(");
+ boolean first = true;
+ for (Class<?> group : gwtValidation.groups()) {
+ if (!first) {
+ sw.print(", ");
+ } else {
+ first = false;
+ }
+ sw.print(group.getCanonicalName() + ".class");
+ }
+ sw.println(");");
+
+ sw.outdent();
+ sw.println("}");
+ }
+
+ private void writeContext(SourceWriter sw, BeanHelper bean, String objectName) {
+ // GwtValidationContext<T> context =
+ // new GwtValidationContext<T>(object,myBeanValidator.getConstraints());
+ sw.print(GwtValidationContext.class.getSimpleName());
+ sw.print("<T> context =");
+ sw.print(" new " + GwtValidationContext.class.getSimpleName());
+ sw.print("<T>(" + objectName + ", ");
+ sw.print(bean.getValidatorInstanceName());
+ sw.print(".getConstraints()");
+ sw.println(");");
+ }
+
+ private void writeGetConstraintsForClass(SourceWriter sourceWriter) {
+ sourceWriter.println("public BeanDescriptor getConstraintsForClass(Class<?> clazz) {");
+ sourceWriter.indent();
+ sourceWriter.println("return null;");
+ sourceWriter.outdent();
+ sourceWriter.println("}");
+ }
+
+ private void writeIfEqulsBeanType(SourceWriter sourceWriter, BeanHelper bean) {
+ sourceWriter.println("if (object.getClass().equals("
+ + bean.getTypeCanonicalName() + ".class)) {");
+ }
+
+ private void writeThrowIllegalArgumnet(SourceWriter sourceWriter) {
+ sourceWriter.print("throw new IllegalArgumentException(\""
+ + this.validatorType.getName() + " can only validate ");
+ sourceWriter.print(beansToValidate.toString());
+ sourceWriter.println("\");");
+ }
+
+ private void writeValidate(SourceWriter sw) {
+ // public <T> Set<ConstraintViolation<T>> validate(T object, Class<?>...
+ // groups) {
sw.println("public <T> Set<ConstraintViolation<T>> validate(T object, Class<?>... groups) {");
sw.indent();
+
+ sw.println("checkNotNull(object, \"object\");");
+ sw.println("checkNotNull(groups, \"groups\");");
+ sw.println("checkGroups(groups);");
+
for (BeanHelper bean : beansToValidate.values()) {
writeValidate(sw, bean);
}
+
writeThrowIllegalArgumnet(sw);
- sw.outdent(); // class
+
+ sw.outdent();
sw.println("}");
- sw.println();
}
- protected void writeValidate(SourceWriter sw, BeanHelper bean) {
+ private void writeValidate(SourceWriter sw, BeanHelper bean) {
writeIfEqulsBeanType(sw, bean);
sw.indent();
+
writeContext(sw, bean, "object");
- sw.print("return " + bean.getValidatorInstanceName()
- + ".validate(context, (" + bean.getTypeCanonicalName() + ") object, ");
+
+ // return personValidator.validate(context, (<<MyBean>>) object, groups);
+ sw.print("return ");
+ sw.print(bean.getValidatorInstanceName() + ".validate(");
+ sw.print("context, ");
+ sw.print("(" + bean.getTypeCanonicalName() + ") object, ");
sw.println("groups);");
- sw.outdent(); // if
+
+ sw.outdent();
sw.println("}");
}
- protected void writeValidateProperty(SourceWriter sw) {
+ private void writeValidateProperty(SourceWriter sw) {
sw.println("public <T> Set<ConstraintViolation<T>> validateProperty(T object,String propertyName, Class<?>... groups) {");
sw.indent();
+
+ sw.println("checkNotNull(object, \"object\");");
+ sw.println("checkNotNull(propertyName, \"propertyName\");");
+ sw.println("checkNotNull(groups, \"groups\");");
+ sw.println("checkGroups(groups);");
+
for (BeanHelper bean : beansToValidate.values()) {
writeValidateProperty(sw, bean);
}
+
writeThrowIllegalArgumnet(sw);
+
sw.outdent();
sw.println("}");
- sw.println();
}
- protected void writeValidateProperty(SourceWriter sw, BeanHelper bean) {
+ private void writeValidateProperty(SourceWriter sw, BeanHelper bean) {
writeIfEqulsBeanType(sw, bean);
sw.indent();
writeContext(sw, bean, "object");
@@ -194,19 +261,26 @@
sw.println("}");
}
- protected void writeValidateValue(SourceWriter sw) {
+ private void writeValidateValue(SourceWriter sw) {
sw.println("public <T> Set<ConstraintViolation<T>> validateValue(Class<T> beanType, String propertyName, Object value, Class<?>... groups) {");
sw.indent();
+
+ sw.println("checkNotNull(beanType, \"beanType\");");
+ sw.println("checkNotNull(propertyName, \"propertyName\");");
+ sw.println("checkNotNull(groups, \"groups\");");
+ sw.println("checkGroups(groups);");
+
for (BeanHelper bean : beansToValidate.values()) {
writeValidateValue(sw, bean);
}
+
writeThrowIllegalArgumnet(sw);
+
sw.outdent();
sw.println("}");
- sw.println();
}
- protected void writeValidateValue(SourceWriter sw, BeanHelper bean) {
+ private void writeValidateValue(SourceWriter sw, BeanHelper bean) {
sw.println("if (beanType.getClass().equals(" + bean.getTypeCanonicalName()
+ ".class)) {");
sw.indent();
@@ -217,43 +291,4 @@
sw.outdent(); // if
sw.println("}");
}
-
- private String getQaulifiedName() {
- return validatorType.getQualifiedSourceName() + "Impl";
- }
-
- private String getSimpleName() {
- return validatorType.getSimpleSourceName() + "Impl";
- }
-
- private SourceWriter getSourceWriter(TreeLogger logger, GeneratorContext ctx) {
- JPackage serviceIntfPkg = validatorType.getPackage();
- String packageName = serviceIntfPkg == null ? "" : serviceIntfPkg.getName();
- String simpleName = getSimpleName();
- PrintWriter printWriter = ctx.tryCreate(logger, packageName, simpleName);
- if (printWriter == null) {
- return null;
- }
-
- ClassSourceFileComposerFactory composerFactory = new ClassSourceFileComposerFactory(
- packageName, simpleName);
-
- String[] imports = new String[]{
- GWT.class.getCanonicalName(),
- GwtBeanDescriptor.class.getCanonicalName(),
- GwtSpecificValidator.class.getCanonicalName(),
- GwtValidationContext.class.getCanonicalName(),
- Set.class.getCanonicalName(),
- ConstraintViolation.class.getCanonicalName(),
- BeanDescriptor.class.getCanonicalName()};
- for (String imp : imports) {
- composerFactory.addImport(imp);
- }
-
- composerFactory.setSuperclass(AbstractGwtValidator.class.getCanonicalName());
- SourceWriter sourceWriter = composerFactory.createSourceWriter(ctx,
- printWriter);
-
- return sourceWriter;
- }
}
diff --git a/user/src/org/hibernate/validator/HibernateValidator.gwt.xml b/user/src/org/hibernate/validator/HibernateValidator.gwt.xml
new file mode 100644
index 0000000..b469c70
--- /dev/null
+++ b/user/src/org/hibernate/validator/HibernateValidator.gwt.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module>
+<!--
+Import this module to use Hibernate Validator during the compilation of validation classes for
+gwt clients.
+ -->
+ <inherits name='com.google.gwt.validation.Validation' />
+ <source path="constraints">
+ <exclude name="impl/scriptassert/" />
+ <exclude name="super/" />
+ </source>
+ <source path="engine">
+ <include name="NodeImpl.java"/>
+ </source>
+ <super-source path="super" />
+</module>
\ No newline at end of file
diff --git a/user/src/org/hibernate/validator/README.txt b/user/src/org/hibernate/validator/README.txt
new file mode 100644
index 0000000..26e3292
--- /dev/null
+++ b/user/src/org/hibernate/validator/README.txt
@@ -0,0 +1,13 @@
+The Hibernate Validator module is used to:
+
+1) generate client side validators.
+2) super source hibernate specific constraints
+3) super source hibernate classes needed to return ConstraintViolations from the server to the client.
+
+
+Maintenance Notes.
+Test using samples/validation.
+
+
+NOTE
+(nchalko) all of should be pushed back to hibernate.
\ No newline at end of file
diff --git a/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/ScriptAssert.java b/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/ScriptAssert.java
new file mode 100644
index 0000000..260a80e
--- /dev/null
+++ b/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/ScriptAssert.java
@@ -0,0 +1,136 @@
+// $Id: ScriptAssert.java 19327 2010-04-30 08:11:15Z hardy.ferentschik $
+/*
+ * JBoss, Home of Professional Open Source Copyright 2010, Red Hat, Inc. and/or
+ * its affiliates, and individual contributors by the @authors tag. See the
+ * copyright.txt in the distribution for a full listing of individual
+ * contributors.
+ *
+ * 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.
+ */
+// MODIFIED BY GOOGLE
+package org.hibernate.validator.constraints;
+
+import org.hibernate.validator.constraints.impl.ScriptAssertValidator;
+
+import static java.lang.annotation.ElementType.TYPE;
+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.ConstraintDeclarationException;
+import javax.validation.Payload;
+
+/**
+ * <p>
+ * A class-level constraint, that evaluates a script expression against the
+ * annotated element. This constraint can be used to implement validation
+ * routines, that depend on multiple attributes of the annotated element.
+ * </p>
+ * <p>
+ * For evaluation of expressions the Java Scripting API as defined by <a
+ * href="http://jcp.org/en/jsr/detail?id=223">JSR 223</a>
+ * ("Scripting for the Java<sup>TM</sup> Platform") is used. Therefore an
+ * implementation of that API must part of the class path. This is automatically
+ * the case when running on Java 6. For older Java versions, the JSR 223 RI can
+ * be added manually to the class path.
+ * </p>
+ * The expressions to be evaluated can be written in any scripting or expression
+ * language, for which a JSR 223 compatible engine can be found in the class
+ * path. The following listing shows an example using the JavaScript engine,
+ * which comes with Java 6: </p>
+ * <p/>
+ *
+ * <pre>
+ * @ScriptAssert(lang = "javascript", script = "_this.startDate.before(_this.endDate)")
+ * public class CalendarEvent {
+ * <p/>
+ * private Date startDate;
+ * <p/>
+ * private Date endDate;
+ * <p/>
+ * //...
+ * <p/>
+ * }
+ * </pre>
+ * <p>
+ * Using a real expression language in conjunction with a shorter object alias
+ * allows for very compact expressions:
+ * </p>
+ *
+ * <pre>
+ * @ScriptAssert(lang = "jexl", script = "_.startDate < _.endDate", alias = "_")
+ * public class CalendarEvent {
+ * <p/>
+ * private Date startDate;
+ * <p/>
+ * private Date endDate;
+ * <p/>
+ * //...
+ * <p/>
+ * }
+ * </pre>
+ * <p>
+ * Accepts any type.
+ * </p>
+ *
+ * @author Gunnar Morling
+ */
+@Target({TYPE})
+@Retention(RUNTIME)
+@Constraint(validatedBy = ScriptAssertValidator.class)
+@Documented
+public @interface ScriptAssert {
+
+ String message() default "{org.hibernate.validator.constraints.ScriptAssert.message}";
+
+ Class<?>[] groups() default {};
+
+ Class<? extends Payload>[] payload() default {};
+
+ /**
+ * @return The name of the script language used by this constraint as expected
+ * by the JSR 223 {@link javax.script.ScriptEngineManager}. A
+ * {@link ConstraintDeclarationException} will be thrown upon script
+ * evaluation, if no engine for the given language could be found.
+ */
+ String lang();
+
+ /**
+ * @return The script to be executed. The script must return
+ * <code>Boolean.TRUE</code>, if the annotated element could
+ * successfully be validated, otherwise <code>Boolean.FALSE</code>.
+ * Returning null or any type other than Boolean will cause a
+ * {@link ConstraintDeclarationException} upon validation. Any
+ * exception occurring during script evaluation will be wrapped into a
+ * ConstraintDeclarationException, too. Within the script, the
+ * validated object can be accessed from the
+ * {@link javax.script.ScriptContext script context} using the name
+ * specified in the <code>alias</code> attribute.
+ */
+ String script();
+
+ /**
+ * @return The name, under which the annotated element shall be registered
+ * within the script context. Defaults to "_this".
+ */
+ String alias() default "_this";
+
+ /**
+ * Defines several {@code @ScriptAssert} annotations on the same element.
+ */
+ @Target({TYPE})
+ @Retention(RUNTIME)
+ @Documented
+ public @interface List {
+ ScriptAssert[] value();
+ }
+}
diff --git a/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/EmailValidator.java b/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/EmailValidator.java
new file mode 100644
index 0000000..46ed562
--- /dev/null
+++ b/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/EmailValidator.java
@@ -0,0 +1,27 @@
+/*
+ * 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 org.hibernate.validator.constraints.impl;
+
+import com.google.gwt.validation.client.constraints.NotGwtCompatibleValidator;
+
+import org.hibernate.validator.constraints.Email;
+
+/**
+ * This Validator is not GWT complatible.
+ */
+public class EmailValidator extends NotGwtCompatibleValidator<Email, String> {
+ // TODO(nchalko) make compatible
+}
diff --git a/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/FutureValidatorForCalendar.java b/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/FutureValidatorForCalendar.java
new file mode 100644
index 0000000..7cbf05e
--- /dev/null
+++ b/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/FutureValidatorForCalendar.java
@@ -0,0 +1,27 @@
+/*
+ * 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 org.hibernate.validator.constraints.impl;
+
+import com.google.gwt.validation.client.constraints.NotGwtCompatibleValidator;
+
+import javax.validation.constraints.Future;
+
+/**
+ * This Validator is not GWT complatible.
+ */
+public class FutureValidatorForCalendar extends
+ NotGwtCompatibleValidator<Future, Object> {
+}
diff --git a/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/PastValidatorForCalendar.java b/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/PastValidatorForCalendar.java
new file mode 100644
index 0000000..1dba9e2
--- /dev/null
+++ b/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/PastValidatorForCalendar.java
@@ -0,0 +1,27 @@
+/*
+ * 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 org.hibernate.validator.constraints.impl;
+
+import com.google.gwt.validation.client.constraints.NotGwtCompatibleValidator;
+
+import javax.validation.constraints.Past;
+
+/**
+ * This Validator is not GWT complatible.
+ */
+public class PastValidatorForCalendar extends
+ NotGwtCompatibleValidator<Past, Object> {
+}
diff --git a/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/PatternValidator.java b/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/PatternValidator.java
new file mode 100644
index 0000000..aaf3e92
--- /dev/null
+++ b/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/PatternValidator.java
@@ -0,0 +1,23 @@
+/*
+ * 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 org.hibernate.validator.constraints.impl;
+
+/**
+ * Override the Hibernate implementation with the GWT version.
+ */
+public class PatternValidator extends
+ com.google.gwt.validation.client.constraints.PatternValidator {
+}
diff --git a/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/ScriptAssertValidator.java b/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/ScriptAssertValidator.java
new file mode 100644
index 0000000..48bdc3a
--- /dev/null
+++ b/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/ScriptAssertValidator.java
@@ -0,0 +1,27 @@
+/*
+ * 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 org.hibernate.validator.constraints.impl;
+
+import com.google.gwt.validation.client.constraints.NotGwtCompatibleValidator;
+
+import org.hibernate.validator.constraints.Email;
+
+/**
+ * This Validator is not GWT complatible.
+ */
+public class ScriptAssertValidator extends
+ NotGwtCompatibleValidator<Email, String> {
+}
diff --git a/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/SizeValidatorForArray.java b/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/SizeValidatorForArray.java
new file mode 100644
index 0000000..5ed12e4
--- /dev/null
+++ b/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/SizeValidatorForArray.java
@@ -0,0 +1,23 @@
+/*
+ * 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 org.hibernate.validator.constraints.impl;
+
+/**
+ * Override the Hibernate implementation with the GWT version.
+ */
+public class SizeValidatorForArray extends
+ com.google.gwt.validation.client.constraints.SizeValidatorForArrayOfObject {
+}
diff --git a/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/SizeValidatorForArraysOfBoolean.java b/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/SizeValidatorForArraysOfBoolean.java
new file mode 100644
index 0000000..a26c805
--- /dev/null
+++ b/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/SizeValidatorForArraysOfBoolean.java
@@ -0,0 +1,23 @@
+/*
+ * 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 org.hibernate.validator.constraints.impl;
+
+/**
+ * Override the Hibernate implementation with the GWT version.
+ */
+public class SizeValidatorForArraysOfBoolean extends
+ com.google.gwt.validation.client.constraints.SizeValidatorForArrayOfBoolean {
+}
diff --git a/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/SizeValidatorForArraysOfByte.java b/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/SizeValidatorForArraysOfByte.java
new file mode 100644
index 0000000..228fdd9
--- /dev/null
+++ b/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/SizeValidatorForArraysOfByte.java
@@ -0,0 +1,23 @@
+/*
+ * 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 org.hibernate.validator.constraints.impl;
+
+/**
+ * Override the Hibernate implementation with the GWT version.
+ */
+public class SizeValidatorForArraysOfByte extends
+ com.google.gwt.validation.client.constraints.SizeValidatorForArrayOfByte {
+}
diff --git a/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/SizeValidatorForArraysOfChar.java b/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/SizeValidatorForArraysOfChar.java
new file mode 100644
index 0000000..8a1f3c2
--- /dev/null
+++ b/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/SizeValidatorForArraysOfChar.java
@@ -0,0 +1,23 @@
+/*
+ * 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 org.hibernate.validator.constraints.impl;
+
+/**
+ * Override the Hibernate implementation with the GWT version.
+ */
+public class SizeValidatorForArraysOfChar extends
+ com.google.gwt.validation.client.constraints.SizeValidatorForArrayOfChar {
+}
diff --git a/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/SizeValidatorForArraysOfDouble.java b/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/SizeValidatorForArraysOfDouble.java
new file mode 100644
index 0000000..4e4beb8
--- /dev/null
+++ b/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/SizeValidatorForArraysOfDouble.java
@@ -0,0 +1,23 @@
+/*
+ * 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 org.hibernate.validator.constraints.impl;
+
+/**
+ * Override the Hibernate implementation with the GWT version.
+ */
+public class SizeValidatorForArraysOfDouble extends
+ com.google.gwt.validation.client.constraints.SizeValidatorForArrayOfDouble {
+}
diff --git a/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/SizeValidatorForArraysOfFloat.java b/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/SizeValidatorForArraysOfFloat.java
new file mode 100644
index 0000000..8d87589
--- /dev/null
+++ b/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/SizeValidatorForArraysOfFloat.java
@@ -0,0 +1,23 @@
+/*
+ * 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 org.hibernate.validator.constraints.impl;
+
+/**
+ * Override the Hibernate implementation with the GWT version.
+ */
+public class SizeValidatorForArraysOfFloat extends
+ com.google.gwt.validation.client.constraints.SizeValidatorForArrayOfFloat {
+}
diff --git a/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/SizeValidatorForArraysOfInt.java b/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/SizeValidatorForArraysOfInt.java
new file mode 100644
index 0000000..d875240
--- /dev/null
+++ b/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/SizeValidatorForArraysOfInt.java
@@ -0,0 +1,23 @@
+/*
+ * 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 org.hibernate.validator.constraints.impl;
+
+/**
+ * Override the Hibernate implementation with the GWT version.
+ */
+public class SizeValidatorForArraysOfInt extends
+ com.google.gwt.validation.client.constraints.SizeValidatorForArrayOfInt {
+}
diff --git a/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/SizeValidatorForArraysOfLong.java b/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/SizeValidatorForArraysOfLong.java
new file mode 100644
index 0000000..55bf45d
--- /dev/null
+++ b/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/SizeValidatorForArraysOfLong.java
@@ -0,0 +1,23 @@
+/*
+ * 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 org.hibernate.validator.constraints.impl;
+
+/**
+ * Override the Hibernate implementation with the GWT version.
+ */
+public class SizeValidatorForArraysOfLong extends
+ com.google.gwt.validation.client.constraints.SizeValidatorForArrayOfLong {
+}
diff --git a/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/SizeValidatorForArraysOfShort.java b/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/SizeValidatorForArraysOfShort.java
new file mode 100644
index 0000000..bd50c7d
--- /dev/null
+++ b/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/SizeValidatorForArraysOfShort.java
@@ -0,0 +1,23 @@
+/*
+ * 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 org.hibernate.validator.constraints.impl;
+
+/**
+ * Override the Hibernate implementation with the GWT version.
+ */
+public class SizeValidatorForArraysOfShort extends
+ com.google.gwt.validation.client.constraints.SizeValidatorForArrayOfShort {
+}
diff --git a/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/URLValidator.java b/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/URLValidator.java
new file mode 100644
index 0000000..bf01353
--- /dev/null
+++ b/user/src/org/hibernate/validator/super/org/hibernate/validator/constraints/impl/URLValidator.java
@@ -0,0 +1,27 @@
+/*
+ * 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 org.hibernate.validator.constraints.impl;
+
+import com.google.gwt.validation.client.constraints.NotGwtCompatibleValidator;
+
+import org.hibernate.validator.constraints.URL;
+
+/**
+ * This Validator is not GWT complatible.
+ */
+public class URLValidator extends
+ NotGwtCompatibleValidator<URL, Object> {
+}
diff --git a/user/test/com/google/gwt/validation/example/ValidationExample.gwt.xml b/user/test/com/google/gwt/validation/example/ValidationExample.gwt.xml
index 0dddb0f..a659123 100644
--- a/user/test/com/google/gwt/validation/example/ValidationExample.gwt.xml
+++ b/user/test/com/google/gwt/validation/example/ValidationExample.gwt.xml
@@ -17,6 +17,6 @@
-->
<module>
<inherits name="com.google.gwt.user.User" />
- <inherits name="com.google.gwt.validation.Validation" />
+ <inherits name="org.hibernate.validator.HibernateValidator" />
<source path="client" />
</module>
\ No newline at end of file
diff --git a/user/test/com/google/gwt/validation/example/client/Author.java b/user/test/com/google/gwt/validation/example/client/Author.java
index eadf824..fc84f893f 100644
--- a/user/test/com/google/gwt/validation/example/client/Author.java
+++ b/user/test/com/google/gwt/validation/example/client/Author.java
@@ -23,8 +23,10 @@
public class Author {
private String firstName;
+
@NotEmpty(message = "lastname must not be null")
private String lastName;
+
@Size(max = 30)
private String company;
diff --git a/user/test/com/google/gwt/validation/example/client/AuthorTest.java b/user/test/com/google/gwt/validation/example/client/AuthorTest.java
index 2be400a..9450609 100644
--- a/user/test/com/google/gwt/validation/example/client/AuthorTest.java
+++ b/user/test/com/google/gwt/validation/example/client/AuthorTest.java
@@ -17,13 +17,17 @@
import com.google.gwt.core.client.GWT;
import com.google.gwt.junit.client.GWTTestCase;
+import com.google.gwt.validation.example.client.ExampleGwtValidator.ClientGroup;
+import com.google.gwt.validation.example.client.ExampleGwtValidator.ServerGroup;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validator;
+import javax.validation.groups.Default;
/**
* Tests for {@link Author}.
@@ -39,6 +43,49 @@
return "com.google.gwt.validation.example.ValidationExample";
}
+ // TODO(nchalko) handle more than one validator
+
+ // @GwtValidation(value = Author.class, groups =
+ // {ExampleGwtValidator.ClientGroup.class})
+ // public interface NotDefaultValidator extends Validator {
+ // }
+
+ // public void testNotDefaultValidtor_EmptyNotDefualt() throws Exception {
+ // NotDefaultValidator other = GWT.create(NotDefaultValidator.class);
+ // Set<ConstraintViolation<Author>> violations = other.validate(author);
+ // assertContentsAnyOrder("valid author", violations);
+ // }
+
+ public void testGroup_empty() throws Exception {
+ initValidAuthor();
+ Set<ConstraintViolation<Author>> violations = validator.validate(author);
+ assertContentsAnyOrder("valid author", violations);
+ }
+
+ public void testGroup_default() throws Exception {
+ initValidAuthor();
+ Set<ConstraintViolation<Author>> violations = validator.validate(author,
+ Default.class);
+ assertContentsAnyOrder("valid author", violations);
+ }
+
+ public void testGroup_clientGroup() throws Exception {
+ initValidAuthor();
+ Set<ConstraintViolation<Author>> violations = validator.validate(author,
+ ClientGroup.class);
+ assertContentsAnyOrder("valid author", violations);
+ }
+
+ public void testGroup_serverGroup() throws Exception {
+ initValidAuthor();
+ try {
+ validator.validate(author, ServerGroup.class);
+ fail("Expected a " + IllegalArgumentException.class);
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
public void testValidate_string() {
try {
validator.validate("some string");
@@ -48,11 +95,24 @@
}
public void testValidate_valid() {
+ initValidAuthor();
+ Set<ConstraintViolation<Author>> violations = validator.validate(author);
+ assertContentsAnyOrder("valid author", violations);
+ }
+
+ public void testValidate_companySize31() {
+ initValidAuthor();
+ author.setCompany("1234567890123456789012345678901");
+ Set<ConstraintViolation<Author>> violations = validator.validate(author);
+ assertContentsAnyOrder("company size 31", toMessage(violations),
+ "{javax.validation.constraints.Size.message}"
+ );
+ }
+
+ protected void initValidAuthor() {
author.setFirstName("John");
author.setLastName("Smith");
author.setCompany("Google");
- Set<ConstraintViolation<Author>> violations = validator.validate(author);
- assertContentsAnyOrder("valid author", violations);
}
public void testValidateProperty_object() {
@@ -67,8 +127,7 @@
try {
validator.validateValue(String.class, "notValid", "value");
fail("Expected a " + IllegalArgumentException.class);
- } catch (IllegalArgumentException e) {
- // expected
+ } catch (IllegalArgumentException expected) {
}
}
@@ -82,11 +141,19 @@
author = new Author();
validator = createValidator();
}
+
+ private <T> List<String> toMessage(Set<ConstraintViolation<T>> violations) {
+ List<String> messages = new ArrayList<String>();
+ for (ConstraintViolation<T> violation : violations) {
+ messages.add(violation.getMessage());
+ }
+ return messages;
+ }
private <T> void assertContentsAnyOrder(String message,
Iterable<T> actual, T... expected) {
- List<T> expectedList = Arrays.asList(expected);
+ List<T> expectedList = new ArrayList<T>(Arrays.asList(expected));
message += "Expected to find " + expectedList + " but found " + actual;
for (T a : actual) {
if (expectedList.contains(a)) {
diff --git a/user/test/com/google/gwt/validation/example/client/ExampleGwtValidator.java b/user/test/com/google/gwt/validation/example/client/ExampleGwtValidator.java
index 46a6922..82d79d6 100644
--- a/user/test/com/google/gwt/validation/example/client/ExampleGwtValidator.java
+++ b/user/test/com/google/gwt/validation/example/client/ExampleGwtValidator.java
@@ -16,14 +16,29 @@
package com.google.gwt.validation.example.client;
import com.google.gwt.validation.client.GwtValidation;
+import com.google.gwt.validation.example.client.ExampleGwtValidator.ClientGroup;
import javax.validation.Validator;
+import javax.validation.groups.Default;
/**
* Example top level class to create a {@link Validator}.
*
* GWT.create instances of this class
*/
-@GwtValidation(Author.class)
+@GwtValidation(
+ value = {Author.class},
+ groups = {Default.class, ClientGroup.class})
public interface ExampleGwtValidator extends Validator {
+ /**
+ * The Client Validation Group
+ */
+ public interface ClientGroup {
+ }
+
+ /**
+ * The Server Validation Group
+ */
+ public interface ServerGroup {
+ }
}
diff --git a/user/test/com/google/gwt/validation/example/client/NotEmpty.java b/user/test/com/google/gwt/validation/example/client/NotEmpty.java
index f88465c..e21489c 100644
--- a/user/test/com/google/gwt/validation/example/client/NotEmpty.java
+++ b/user/test/com/google/gwt/validation/example/client/NotEmpty.java
@@ -29,6 +29,7 @@
import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
+import javax.validation.Payload;
import javax.validation.ReportAsSingleViolation;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
@@ -49,6 +50,8 @@
Class<?>[] groups() default {};
+ Class<? extends Payload>[] payload() default {};
+
/**
* From the JSR 303 spec.
*/