Author: hardy.ferentschik
Date: 2008-10-02 06:39:39 -0400 (Thu, 02 Oct 2008)
New Revision: 15247
Added:
validator/trunk/hibernate-validator/
validator/trunk/hibernate-validator/pom.xml
validator/trunk/hibernate-validator/src/
validator/trunk/hibernate-validator/src/main/
validator/trunk/hibernate-validator/src/main/java/
validator/trunk/hibernate-validator/src/main/java/org/
validator/trunk/hibernate-validator/src/main/java/org/hibernate/
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/HibernateValidatorBuilder.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/Version.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/Length.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/LengthConstraint.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NotEmpty.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NotEmptyConstraint.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NotNull.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NotNullConstraint.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/Pattern.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/PatternConstraint.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/Patterns.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ContextImpl.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MetaDataProvider.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MetaDataProviderImpl.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidationContext.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorMetaData.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ConstraintDescriptorImpl.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ConstraintFactoryImpl.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ElementDescriptorImpl.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/HibernateValidationProvider.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/InvalidConstraintImpl.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ResourceBundleMessageResolver.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ValidatorBuilderImpl.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ValidatorFactoryImpl.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/IdentitySet.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/LoggerFactory.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/PropertyIterator.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/ReflectionHelper.java
validator/trunk/hibernate-validator/src/main/resources/
validator/trunk/hibernate-validator/src/main/resources/META-INF/
validator/trunk/hibernate-validator/src/main/resources/META-INF/services/
validator/trunk/hibernate-validator/src/main/resources/META-INF/services/javax.validation.spi.ValidationProvider
validator/trunk/hibernate-validator/src/main/resources/org/
validator/trunk/hibernate-validator/src/main/resources/org/hibernate/
validator/trunk/hibernate-validator/src/main/resources/org/hibernate/validation/
validator/trunk/hibernate-validator/src/main/resources/org/hibernate/validation/ValidationMessages.properties
validator/trunk/hibernate-validator/src/site/
validator/trunk/hibernate-validator/src/site/site.xml
validator/trunk/hibernate-validator/src/test/
validator/trunk/hibernate-validator/src/test/java/
validator/trunk/hibernate-validator/src/test/java/org/
validator/trunk/hibernate-validator/src/test/java/org/hibernate/
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/bootstrap/
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/bootstrap/ValidationTest.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/LengthConstraintTest.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/NotEmptyConstraintTest.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/NotNullConstraintTest.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/PatternConstraintTest.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Actor.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Address.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Animal.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Author.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Book.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Boy.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Customer.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Dictonary.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Engine.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/EnglishDictonary.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Female.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Male.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Order.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Person.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Unconstraint.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/constraint/
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/constraint/NoGroups.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/constraint/NoGroupsConstraint.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/constraint/NoMessage.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/constraint/NoMessageConstraint.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/ValidatorImplTest.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/impl/
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/impl/ResourceBundleMessageResolverTest.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/IdentitySetTest.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/PropertyIteratorTest.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/ReflectionHelperTest.java
validator/trunk/hibernate-validator/src/test/resources/
validator/trunk/hibernate-validator/src/test/resources/log4j.properties
validator/trunk/pom.xml
validator/trunk/src/
validator/trunk/src/site/
validator/trunk/src/site/site.xml
validator/trunk/validation-api/
validator/trunk/validation-api/pom.xml
validator/trunk/validation-api/src/
validator/trunk/validation-api/src/main/
validator/trunk/validation-api/src/main/java/
validator/trunk/validation-api/src/main/java/javax/
validator/trunk/validation-api/src/main/java/javax/validation/
validator/trunk/validation-api/src/main/java/javax/validation/Constraint.java
validator/trunk/validation-api/src/main/java/javax/validation/ConstraintDescriptor.java
validator/trunk/validation-api/src/main/java/javax/validation/ConstraintFactory.java
validator/trunk/validation-api/src/main/java/javax/validation/ConstraintValidator.java
validator/trunk/validation-api/src/main/java/javax/validation/Context.java
validator/trunk/validation-api/src/main/java/javax/validation/ElementDescriptor.java
validator/trunk/validation-api/src/main/java/javax/validation/GroupSequence.java
validator/trunk/validation-api/src/main/java/javax/validation/GroupSequences.java
validator/trunk/validation-api/src/main/java/javax/validation/InvalidConstraint.java
validator/trunk/validation-api/src/main/java/javax/validation/MessageResolver.java
validator/trunk/validation-api/src/main/java/javax/validation/StandardConstraint.java
validator/trunk/validation-api/src/main/java/javax/validation/StandardConstraintDescriptor.java
validator/trunk/validation-api/src/main/java/javax/validation/Valid.java
validator/trunk/validation-api/src/main/java/javax/validation/Validation.java
validator/trunk/validation-api/src/main/java/javax/validation/ValidationException.java
validator/trunk/validation-api/src/main/java/javax/validation/ValidationProviderResolver.java
validator/trunk/validation-api/src/main/java/javax/validation/Validator.java
validator/trunk/validation-api/src/main/java/javax/validation/ValidatorBuilder.java
validator/trunk/validation-api/src/main/java/javax/validation/ValidatorFactory.java
validator/trunk/validation-api/src/main/java/javax/validation/bootstrap/
validator/trunk/validation-api/src/main/java/javax/validation/bootstrap/DefaultValidationProviderResolver.java
validator/trunk/validation-api/src/main/java/javax/validation/bootstrap/GenericBuilderFactory.java
validator/trunk/validation-api/src/main/java/javax/validation/bootstrap/SpecializedBuilderFactory.java
validator/trunk/validation-api/src/main/java/javax/validation/spi/
validator/trunk/validation-api/src/main/java/javax/validation/spi/BootstrapState.java
validator/trunk/validation-api/src/main/java/javax/validation/spi/ValidationProvider.java
validator/trunk/validation-api/src/main/java/javax/validation/spi/ValidatorBuilderImplementor.java
validator/trunk/validation-api/src/main/resources/
validator/trunk/validation-api/src/site/
validator/trunk/validation-api/src/site/site.xml
validator/trunk/validation-api/src/test/
validator/trunk/validation-api/src/test/java/
validator/trunk/validation-api/src/test/resources/
Modified:
validator/trunk/hibernate-validator-legacy/
Log:
Imported the bean validation code from
https://svn.jboss.org/repos/beancheck. I just
copied the current state. The history of the bean validation code is not available.
Property changes on: validator/trunk/hibernate-validator
___________________________________________________________________
Name: svn:ignore
+ target
Added: validator/trunk/hibernate-validator/pom.xml
===================================================================
--- validator/trunk/hibernate-validator/pom.xml (rev 0)
+++ validator/trunk/hibernate-validator/pom.xml 2008-10-02 10:39:39 UTC (rev 15247)
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<project
xmlns="http://maven.apache.org/POM/4.0.0"
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <artifactId>hibernate-validator-parent</artifactId>
+ <groupId>org.hibernate</groupId>
+ <version>1.0.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.hibernate</groupId>
+ <artifactId>hibernate-validator</artifactId>
+ <name>Hibernate Validator</name>
+ <distributionManagement>
+ <site>
+ <id>local</id>
+ <url>file:///Users/hardy/Sites/${artifactId}</url>
+ </site>
+ </distributionManagement>
+ <dependencies>
+ <dependency>
+ <groupId>javax.validation</groupId>
+ <artifactId>validation-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <scope>runtime</scope>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>commons-collections</groupId>
+ <artifactId>commons-collections</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/HibernateValidatorBuilder.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/HibernateValidatorBuilder.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/HibernateValidatorBuilder.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,12 @@
+package org.hibernate.validation;
+
+import javax.validation.ValidatorBuilder;
+
+/**
+ * Uniquely identify Hibernate Validator in the Bean Validation bootstrap strategy
+ * Also contains Hibernate Validator specific configurations
+ *
+ * @author Emmanuel Bernard
+ */
+public interface HibernateValidatorBuilder extends
ValidatorBuilder<HibernateValidatorBuilder> {
+}
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/Version.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/Version.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/Version.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,61 @@
+// $Id: Version.java 105 2008-09-29 12:37:32Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation;
+
+import java.net.URL;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
+import org.slf4j.Logger;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class Version {
+ private static final Logger log = org.hibernate.validation.util.LoggerFactory.make();
+
+ static {
+ Class clazz = Version.class;
+ String classFileName = clazz.getSimpleName() + ".class";
+ String classFilePath = clazz.getCanonicalName().replace( '.', '/' )
+ + ".class";
+ String pathToThisClass =
+ clazz.getResource( classFileName ).toString();
+ String pathToManifest = pathToThisClass.substring( 0, pathToThisClass.indexOf(
classFilePath ) - 1 )
+ + "/META-INF/MANIFEST.MF";
+ log.trace( "Manifest file {}", pathToManifest );
+ Manifest manifest = null;
+ String version;
+ try {
+ manifest = new Manifest( new URL( pathToManifest ).openStream() );
+ }
+ catch ( Exception e ) {
+ log.warn( "Unable to determine version of Hibernate Validator" );
+ }
+ if ( manifest == null ) {
+ version = "?";
+ }
+ else {
+ version = manifest.getMainAttributes().getValue(
Attributes.Name.IMPLEMENTATION_VERSION );
+ }
+ log.info( "Hibernate Commons Annotations {}", version );
+ }
+
+ public static void touch() {
+ }
+}
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/Length.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/Length.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/Length.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,46 @@
+// $Id: Length.java 105 2008-09-29 12:37:32Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.constraints;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+import javax.validation.ConstraintValidator;
+
+/**
+ * Validate that the string is between min and max included
+ *
+ * @author Emmanuel Bernard
+ */
+@Documented
+(a)ConstraintValidator(LengthConstraint.class)
+@Target({ METHOD, FIELD, TYPE })
+@Retention(RUNTIME)
+public @interface Length {
+ public abstract int min() default 0;
+
+ public abstract int max() default Integer.MAX_VALUE;
+
+ public abstract String message() default "{validator.length}";
+
+ public abstract String[] groups() default { };
+}
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/LengthConstraint.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/LengthConstraint.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/LengthConstraint.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,64 @@
+// $Id: LengthConstraint.java 110 2008-09-29 23:46:37Z epbernard $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.constraints;
+
+import javax.validation.Constraint;
+import javax.validation.StandardConstraint;
+import javax.validation.StandardConstraintDescriptor;
+import javax.validation.Context;
+
+/**
+ * Check that a string's length is between min and max.
+ *
+ * @author Emmanuel Bernard
+ * @author Gavin King
+ */
+public class LengthConstraint implements Constraint<Length>, StandardConstraint {
+ private int min;
+ private int max;
+
+ public void initialize(Length parameters) {
+ min = parameters.min();
+ max = parameters.max();
+ }
+
+ public boolean isValid(Object value, Context context) {
+ if ( value == null ) {
+ return true;
+ }
+ if ( !( value instanceof String ) ) {
+ throw new IllegalArgumentException( "Expected String type." );
+ }
+ String string = ( String ) value;
+ int length = string.length();
+ return length >= min && length <= max;
+ }
+
+ public StandardConstraintDescriptor getStandardConstraints() {
+ return new StandardConstraintDescriptor() {
+ public Integer getLength() {
+ if ( max == Integer.MAX_VALUE ) {
+ return null;
+ }
+ else {
+ return max;
+ }
+ }
+ };
+ }
+}
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NotEmpty.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NotEmpty.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NotEmpty.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,39 @@
+// $Id: NotEmpty.java 105 2008-09-29 12:37:32Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.constraints;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+import javax.validation.ConstraintValidator;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@Documented
+(a)ConstraintValidator(NotEmptyConstraint.class)
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface NotEmpty {
+ public abstract String message() default "{validator.notEmpty}";
+
+ public abstract String[] groups() default { };
+}
\ No newline at end of file
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NotEmptyConstraint.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NotEmptyConstraint.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NotEmptyConstraint.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,43 @@
+// $Id: NotEmptyConstraint.java 110 2008-09-29 23:46:37Z epbernard $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.constraints;
+
+import javax.validation.Constraint;
+import javax.validation.Context;
+
+/**
+ * @author Hardy Ferentschik
+ * @todo Extend to not only support strings, but also collections and maps. Needs to be
specified first though.
+ */
+public class NotEmptyConstraint implements Constraint<NotEmpty> {
+
+ public void initialize(NotEmpty parameters) {
+ }
+
+ public boolean isValid(Object object, Context context) {
+ if ( object == null ) {
+ return true;
+ }
+ if ( !( object instanceof String ) ) {
+ throw new IllegalArgumentException( "Expected String type." );
+ }
+ String string = ( String ) object;
+ int length = string.length();
+ return length > 0;
+ }
+}
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NotNull.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NotNull.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NotNull.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,39 @@
+// $Id: NotNull.java 105 2008-09-29 12:37:32Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.constraints;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+import javax.validation.ConstraintValidator;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@Documented
+(a)ConstraintValidator(NotNullConstraint.class)
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface NotNull {
+ public abstract String message() default "{validator.notNull}";
+
+ public abstract String[] groups() default { };
+}
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NotNullConstraint.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NotNullConstraint.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NotNullConstraint.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,36 @@
+// $Id: NotNullConstraint.java 110 2008-09-29 23:46:37Z epbernard $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.constraints;
+
+import javax.validation.Constraint;
+import javax.validation.Context;
+
+/**
+ * Validate that the object is not <code>null</code>.
+ *
+ * @author Emmanuel Bernard
+ */
+public class NotNullConstraint implements Constraint<NotNull> {
+
+ public void initialize(NotNull parameters) {
+ }
+
+ public boolean isValid(Object object, Context context) {
+ return object != null;
+ }
+}
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/Pattern.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/Pattern.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/Pattern.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,50 @@
+// $Id: Pattern.java 105 2008-09-29 12:37:32Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.constraints;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+import javax.validation.ConstraintValidator;
+
+/**
+ * @author Hardy Ferentschik
+ */
+@Documented
+(a)ConstraintValidator(PatternConstraint.class)
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface Pattern {
+ public abstract String message() default "{validator.pattern}";
+
+ public abstract String[] groups() default { };
+
+ /**
+ * @return the regular expression the annotated string must match.
+ */
+ String regex();
+
+ /**
+ * @return Additioanl regular expression processing flags. Default is 0.
+ */
+ int flags() default 0;
+}
+
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/PatternConstraint.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/PatternConstraint.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/PatternConstraint.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,49 @@
+// $Id: PatternConstraint.java 110 2008-09-29 23:46:37Z epbernard $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.constraints;
+
+import java.util.regex.Matcher;
+import javax.validation.Constraint;
+import javax.validation.Context;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class PatternConstraint implements Constraint<Pattern> {
+
+ private java.util.regex.Pattern pattern;
+
+ public void initialize(Pattern parameters) {
+ pattern = java.util.regex.Pattern.compile(
+ parameters.regex(),
+ parameters.flags()
+ );
+ }
+
+ public boolean isValid(Object value, Context context) {
+ if ( value == null ) {
+ return true;
+ }
+ if ( !( value instanceof String ) ) {
+ throw new IllegalArgumentException( "Expected String type." );
+ }
+ String string = ( String ) value;
+ Matcher m = pattern.matcher( string );
+ return m.matches();
+ }
+}
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/Patterns.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/Patterns.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/Patterns.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,35 @@
+// $Id: Patterns.java 105 2008-09-29 12:37:32Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.constraints;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * @author Hardy Ferentschik
+ */
+@Documented
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface Patterns {
+ Pattern[] value();
+}
\ No newline at end of file
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ContextImpl.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ContextImpl.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ContextImpl.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,69 @@
+package org.hibernate.validation.engine;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Collections;
+import javax.validation.Context;
+import javax.validation.ConstraintDescriptor;
+
+import org.hibernate.validation.impl.ConstraintDescriptorImpl;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class ContextImpl implements Context {
+ private final ConstraintDescriptor constraintDescriptor;
+ private final List<ErrorMessage> errorMessages;
+ private boolean defaultDisabled;
+
+ public ContextImpl(ConstraintDescriptorImpl constraintDescriptor) {
+ this.constraintDescriptor = constraintDescriptor;
+ this.errorMessages = new ArrayList<ErrorMessage>(3);
+ }
+
+ public void disableDefaultError() {
+ defaultDisabled = true;
+ }
+
+ public String getDefaultErrorMessage() {
+ return ( String ) constraintDescriptor.getParameters().get("message");
+ }
+
+ public void addError(String message) {
+ //FIXME get the default property if property-level
+ errorMessages.add( new ErrorMessage( message, null ) );
+ }
+
+ public void addError(String message, String property) {
+ //FIXME: make sure the property is valid
+ errorMessages.add( new ErrorMessage( message, property ) );
+ }
+
+ public List<ErrorMessage> getErrorMessages() {
+ List<ErrorMessage> returnedErrorMessages = new ArrayList<ErrorMessage>(
errorMessages.size() + 1 );
+ Collections.copy( returnedErrorMessages, errorMessages );
+ if ( ! defaultDisabled ) {
+ //FIXME get the default property if property-level
+ returnedErrorMessages.add( new ErrorMessage( getDefaultErrorMessage(), null) );
+ }
+ return returnedErrorMessages;
+ }
+
+ public static class ErrorMessage {
+ private final String message;
+ private final String property;
+
+ private ErrorMessage(String message, String property) {
+ this.message = message;
+ this.property = property;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public String getProperty() {
+ return property;
+ }
+ }
+}
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MetaDataProvider.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MetaDataProvider.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MetaDataProvider.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,79 @@
+// $Id: MetaDataProvider.java 105 2008-09-29 12:37:32Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.engine;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Member;
+import java.util.List;
+import java.util.Map;
+import javax.validation.ElementDescriptor;
+
+/**
+ * Interface defining the meta data about the constraints defined in a given bean.
+ *
+ * @author Hardy Ferentschik
+ */
+public interface MetaDataProvider<T> {
+
+ /**
+ * @return the class of the bean.
+ */
+ Class<T> getBeanClass();
+
+ /**
+ * @return an instance of <code>ElementDescriptor</code> describing the bean
this meta data applies for.
+ */
+ ElementDescriptor getBeanDescriptor();
+
+ /**
+ * @return A list of all cascaded fields (fields annotated with @Valid).
+ */
+ List<Field> getCascadedFields();
+
+ /**
+ * @return A list of all cascaded methods (methods annotated with @Valid).
+ */
+ List<Method> getCascadedMethods();
+
+ /**
+ * @return A list of all cascaded methods and fields (methods/fields annotated with
@Valid).
+ */
+ List<Member> getCascadedMembers();
+
+ /**
+ * @return A map mapping defined group sequence names to a list of groups.
+ */
+ Map<String, List<String>> getGroupSequences();
+
+ /**
+ * @return A list of <code>ValidatorMetaData</code> instances encapsulating
the information of all the constraints
+ * defined on the bean.
+ */
+ List<ValidatorMetaData> getConstraintMetaDataList();
+
+ /**
+ * @return A map keying the property name of a constraint to its
<code>ElementDescriptor</code>.
+ *
+ * @todo Maybe needs to be removed since this data structure is ambigious. There could
be conflicts between field and
+ * methods.
+ */
+ Map<String, ElementDescriptor> getPropertyDescriptors();
+
+ ElementDescriptor getPropertyDescriptors(String property);
+}
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MetaDataProviderImpl.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MetaDataProviderImpl.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MetaDataProviderImpl.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,473 @@
+// $Id: MetaDataProviderImpl.java 105 2008-09-29 12:37:32Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.engine;
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.validation.Constraint;
+import javax.validation.ConstraintFactory;
+import javax.validation.ConstraintValidator;
+import javax.validation.ElementDescriptor;
+import javax.validation.GroupSequence;
+import javax.validation.GroupSequences;
+import javax.validation.Valid;
+import javax.validation.ValidationException;
+
+import org.slf4j.Logger;
+
+import org.hibernate.validation.impl.ConstraintDescriptorImpl;
+import org.hibernate.validation.impl.ConstraintFactoryImpl;
+import org.hibernate.validation.impl.ElementDescriptorImpl;
+import org.hibernate.validation.util.LoggerFactory;
+import org.hibernate.validation.util.ReflectionHelper;
+
+
+/**
+ * This class encapsulates all meta data needed for validation. Implementations of
<code>Validator</code> interface can
+ * instantiate an instance of this class and delegate the metadata extraction to it.
+ *
+ * @author Hardy Ferentschik
+ */
+
+public class MetaDataProviderImpl<T> implements MetaDataProvider<T> {
+
+ private static final Logger log = LoggerFactory.make();
+
+ /**
+ * The root bean class for this validator.
+ */
+ private final Class<T> beanClass;
+
+ /**
+ * The main element descriptor for <code>beanClass</code>.
+ */
+ private ElementDescriptorImpl beanDescriptor;
+
+ /**
+ * List of constraints.
+ */
+ private List<ValidatorMetaData> constraintMetaDataList = new
ArrayList<ValidatorMetaData>();
+
+ /**
+ * List of cascaded fields.
+ */
+ private List<Field> cascadedFields = new ArrayList<Field>();
+
+ /**
+ * List of cascaded methods.
+ */
+ private List<Method> cascadedMethods = new ArrayList<Method>();
+
+ /**
+ * Maps field and method names to their <code>ElementDescriptorImpl</code>.
+ * FIXME This model is problematic as you can have conflicting names for fields and
methods
+ */
+ private Map<String, ElementDescriptor> propertyDescriptors = new
HashMap<String, ElementDescriptor>();
+
+ /**
+ * Factory to create acutal constraint instances from the annotated
fields/method/class.
+ */
+ private ConstraintFactory constraintFactory = new ConstraintFactoryImpl();
+
+ /**
+ * Maps group sequence names to the list of group/sequence names.
+ */
+ private Map<String, List<String>> groupSequences = new HashMap<String,
List<String>>();
+
+ public MetaDataProviderImpl(Class<T> beanClass, ConstraintFactory
constraintFactory) {
+ this.beanClass = beanClass;
+ this.constraintFactory = constraintFactory;
+ createMetaData();
+ }
+
+ /**
+ * Create bean desciptor, find all classes/subclasses/interfaces which have to be taken
in consideration
+ * for this validator and create meta data.
+ */
+ private void createMetaData() {
+ beanDescriptor = new ElementDescriptorImpl( ElementType.TYPE, beanClass, false,
"" );
+ List<Class> classes = new ArrayList<Class>();
+ computeClassHierarchy( beanClass, classes );
+ for ( Class current : classes ) {
+ initClass( current );
+ }
+ }
+
+ /**
+ * Get all superclasses and interfaces recursively.
+ *
+ * @param clazz The class to start the seatch with.
+ * @param classes List of classes to which to add all found super classes and
interfaces.
+ */
+ private void computeClassHierarchy(Class clazz, List<Class> classes) {
+ if ( log.isTraceEnabled() ) {
+ log.trace( "Processing: {}", clazz );
+ }
+ for ( Class current = clazz; current != null; current = current.getSuperclass() ) {
+ if ( classes.contains( current ) ) {
+ return;
+ }
+ classes.add( current );
+ for ( Class currentInterface : current.getInterfaces() ) {
+ computeClassHierarchy( currentInterface, classes );
+ }
+ }
+ }
+
+ private void initClass(Class clazz) {
+ initGroupSequences( clazz );
+ initClassConstraints( clazz );
+ initMethodConstraints( clazz );
+ initFieldConstraints( clazz );
+ }
+
+ private void initGroupSequences(Class<?> clazz) {
+ GroupSequence groupSequenceAnnotation = clazz.getAnnotation( GroupSequence.class );
+ if ( groupSequenceAnnotation != null ) {
+ addGroupSequence( groupSequenceAnnotation );
+ }
+
+ GroupSequences groupSequencesAnnotation = clazz.getAnnotation( GroupSequences.class );
+ if ( groupSequencesAnnotation != null ) {
+ for ( GroupSequence group : groupSequencesAnnotation.value() ) {
+ addGroupSequence( group );
+ }
+ }
+
+ for ( Map.Entry<String, List<String>> mapEntry : groupSequences.entrySet()
) {
+ List<String> groupNames = mapEntry.getValue();
+ List<String> expandedGroupNames = new ArrayList<String>();
+ for ( String groupName : groupNames ) {
+ expandedGroupNames.addAll( expandGroupSequenceNames( groupName ) );
+ }
+ groupSequences.put( mapEntry.getKey(), expandedGroupNames );
+ }
+ if ( log.isDebugEnabled() && !groupSequences.isEmpty() ) {
+ log.debug( "Expanded groups sequences: {}", groupSequences );
+ }
+ }
+
+ private List<String> expandGroupSequenceNames(String group) {
+ List<String> groupList = new ArrayList<String>();
+ if ( groupSequences.containsKey( group ) ) {
+ for ( String s : groupSequences.get( group ) ) {
+ groupList.addAll( expandGroupSequenceNames( s ) );
+ }
+ }
+ else {
+ groupList.add( group );
+ }
+ if ( log.isTraceEnabled() ) {
+ log.trace( "Expanded {} to {}", group, groupList.toString() );
+ }
+ return groupList;
+ }
+
+ private void addGroupSequence(GroupSequence groupSequence) {
+ if ( groupSequences.containsKey( groupSequence.name() ) ) {
+ throw new ValidationException( "Encountered duplicate sequence name: " +
groupSequence.name() );
+ }
+ groupSequences.put( groupSequence.name(), Arrays.asList( groupSequence.sequence() ) );
+ }
+
+ private void initFieldConstraints(Class clazz) {
+ for ( Field field : clazz.getDeclaredFields() ) {
+ List<ConstraintDescriptorImpl> fieldMetadata = getFieldLevelMetadata( field );
+ for ( ConstraintDescriptorImpl constraintDescription : fieldMetadata ) {
+ ReflectionHelper.setAccessibility( field );
+ ValidatorMetaData metaData = new ValidatorMetaData( field, constraintDescription );
+ constraintMetaDataList.add( metaData );
+ }
+ if ( field.isAnnotationPresent( Valid.class ) ) {
+ cascadedFields.add( field );
+ }
+ }
+ }
+
+ private void initMethodConstraints(Class clazz) {
+ for ( Method method : clazz.getDeclaredMethods() ) {
+ List<ConstraintDescriptorImpl> methodMetadata = getMethodLevelMetadata( method
);
+ for ( ConstraintDescriptorImpl constraintDescription : methodMetadata ) {
+ ReflectionHelper.setAccessibility( method );
+ ValidatorMetaData metaData = new ValidatorMetaData( method, constraintDescription );
+ constraintMetaDataList.add( metaData );
+ }
+ if ( method.isAnnotationPresent( Valid.class ) ) {
+ cascadedMethods.add( method );
+ }
+ }
+ }
+
+ private void initClassConstraints(Class clazz) {
+ List<ConstraintDescriptorImpl> classMetadata = getClassLevelMetadata( clazz );
+ for ( ConstraintDescriptorImpl constraintDescription : classMetadata ) {
+ ValidatorMetaData metaData = new ValidatorMetaData( clazz, constraintDescription );
+ constraintMetaDataList.add( metaData );
+ }
+ }
+
+ /**
+ * Examines the given annotation to see whether it is a single or multi valued
constraint annotation.
+ *
+ * @param annotation The annotation to examine.
+ *
+ * @return A list of constraint descriptors or the empty list in case
<code>annotation</code> is neither a
+ * single nor multi value annotation.
+ */
+ private <A extends Annotation> List<ConstraintDescriptorImpl>
findConstraintAnnotations(A annotation) {
+ List<ConstraintDescriptorImpl> constraintDescriptors = new
ArrayList<ConstraintDescriptorImpl>();
+
+ List<Annotation> constraintCandidates = new ArrayList<Annotation>();
+ constraintCandidates.add( annotation );
+
+ // check if we have a multi value constraint
+ Annotation[] annotations = getMultiValueConstraintsCandidates( annotation );
+ constraintCandidates.addAll( Arrays.asList( annotations ) );
+
+ for ( Annotation constraintCandiate : constraintCandidates ) {
+ ConstraintValidator constraintValidator = constraintCandiate.annotationType()
+ .getAnnotation( ConstraintValidator.class );
+ if ( constraintValidator != null ) {
+ final ConstraintDescriptorImpl constraintDescriptor = buildConstraintDescriptor(
constraintCandiate );
+ constraintDescriptors.add( constraintDescriptor );
+ }
+ }
+ return constraintDescriptors;
+ }
+
+ @SuppressWarnings("unchecked")
+ private <A extends Annotation> ConstraintDescriptorImpl
buildConstraintDescriptor(A annotation) {
+ getMessage( annotation ); // called to make sure there is a message
+ String[] groups = getGroups( annotation );
+ for ( String groupName : groups ) {
+ if ( groupSequences.containsKey( groupName ) ) {
+ throw new ValidationException( groupName + " is illegally used as group and
sequence name." );
+ }
+ }
+
+ Constraint<A> constraint;
+ ConstraintValidator constraintValidator = annotation.annotationType()
+ .getAnnotation( ConstraintValidator.class );
+ try {
+ //unchecked
+ constraint = constraintFactory.getInstance( constraintValidator.value() );
+ }
+ catch ( RuntimeException e ) {
+ throw new ValidationException( "Unable to instantiate " +
constraintValidator.value(), e );
+ }
+
+ try {
+ constraint.initialize( annotation );
+ }
+ catch ( RuntimeException e ) {
+ throw new ValidationException( "Unable to intialize " +
constraintValidator.value(), e );
+ }
+
+ return new ConstraintDescriptorImpl( annotation, groups, constraint );
+ }
+
+ private <A extends Annotation> String getMessage(A annotation) {
+ try {
+ Method m = annotation.getClass().getMethod( "message" );
+ return ( String ) m.invoke( annotation );
+ }
+ catch ( NoSuchMethodException e ) {
+ throw new ValidationException( "Constraint annotation has to define message
element." );
+ }
+ catch ( Exception e ) {
+ throw new ValidationException( "Unable to get message from " +
annotation.getClass().getName() );
+ }
+ }
+
+ private <A extends Annotation> String[] getGroups(A annotation) {
+ try {
+ Method m = annotation.getClass().getMethod( "groups" );
+ return ( String[] ) m.invoke( annotation );
+ }
+ catch ( NoSuchMethodException e ) {
+ throw new ValidationException( "Constraint annotation has to define groups
element." );
+ }
+ catch ( Exception e ) {
+ throw new ValidationException( "Unable to get groups from " +
annotation.getClass().getName() );
+ }
+ }
+
+ /**
+ * Checks whether the given annotation has a value parameter which returns an array of
annotations.
+ *
+ * @param annotation the annotation to check.
+ *
+ * @return The list of potential constraint annotations or the empty array.
+ *
+ * @todo Not only check that the return type of value is an array, but an array of
annotaitons. Need to check syntax.
+ */
+ private <A extends Annotation> Annotation[] getMultiValueConstraintsCandidates(A
annotation) {
+ try {
+ Method m = annotation.getClass().getMethod( "value" );
+ Class returnType = m.getReturnType();
+ if ( returnType.isArray() ) {
+ return ( Annotation[] ) m.invoke( annotation );
+ }
+ else {
+ return new Annotation[0];
+ }
+ }
+ catch ( Exception e ) {
+ return new Annotation[0];
+ }
+ }
+
+ /**
+ * Finds all constraint annotations defined for the given class and returns them in a
list of
+ * constraint descriptors.
+ *
+ * @param beanClass The class to check for constraints annotations.
+ *
+ * @return A list of constraint descriptors for all constraint specified on the given
class.
+ *
+ * @todo inject XML data here, probably externalizing the process
+ */
+ private List<ConstraintDescriptorImpl> getClassLevelMetadata(Class beanClass) {
+ List<ConstraintDescriptorImpl> metadata = new
ArrayList<ConstraintDescriptorImpl>();
+ for ( Annotation annotation : beanClass.getAnnotations() ) {
+ metadata.addAll( findConstraintAnnotations( annotation ) );
+ }
+ for ( ConstraintDescriptorImpl constraintDescriptor : metadata ) {
+ beanDescriptor.addConstraintDescriptor( constraintDescriptor );
+ }
+ return metadata;
+ }
+
+ /**
+ * Finds all constraint annotations defined for the given methods and returns them in a
list of
+ * constraint descriptors.
+ *
+ * @param method The method to check for constraints annotations.
+ *
+ * @return A list of constraint descriptors for all constraint specified for the given
method.
+ *
+ * @todo inject XML data here, probably externalizing the process
+ */
+ private List<ConstraintDescriptorImpl> getMethodLevelMetadata(Method method) {
+ List<ConstraintDescriptorImpl> metadata = new
ArrayList<ConstraintDescriptorImpl>();
+ for ( Annotation annotation : method.getAnnotations() ) {
+ metadata.addAll( findConstraintAnnotations( annotation ) );
+ }
+
+ String methodName = ReflectionHelper.getPropertyName( method );
+ for ( ConstraintDescriptorImpl constraintDescriptor : metadata ) {
+ if ( methodName == null ) {
+ throw new ValidationException(
+ "Annoated methods must follow the JavaBeans naming convention. " +
method.getName() + "() does not."
+ );
+ }
+ ElementDescriptorImpl elementDescriptor = ( ElementDescriptorImpl )
propertyDescriptors.get( methodName );
+ if ( elementDescriptor == null ) {
+ elementDescriptor = new ElementDescriptorImpl(
+ ElementType.METHOD,
+ method.getReturnType(),
+ method.isAnnotationPresent( Valid.class ),
+ methodName
+ );
+ propertyDescriptors.put( methodName, elementDescriptor );
+ }
+ elementDescriptor.addConstraintDescriptor( constraintDescriptor );
+ }
+ return metadata;
+ }
+
+ /**
+ * Finds all constraint annotations defined for the given field and returns them in a
list of
+ * constraint descriptors.
+ *
+ * @param field The field to check for constraints annotations.
+ *
+ * @return A list of constraint descriptors for all constraint specified on the given
field.
+ *
+ * @todo inject XML data here, probably externalizing the process
+ */
+ private List<ConstraintDescriptorImpl> getFieldLevelMetadata(Field field) {
+ List<ConstraintDescriptorImpl> metadata = new
ArrayList<ConstraintDescriptorImpl>();
+ for ( Annotation annotation : field.getAnnotations() ) {
+ metadata.addAll( findConstraintAnnotations( annotation ) );
+ }
+
+ String fieldName = field.getName();
+ for ( ConstraintDescriptorImpl constraintDescriptor : metadata ) {
+ ElementDescriptorImpl elementDescriptor = ( ElementDescriptorImpl )
propertyDescriptors.get( fieldName );
+ if ( elementDescriptor == null ) {
+ elementDescriptor = new ElementDescriptorImpl(
+ ElementType.FIELD,
+ field.getType(),
+ field.isAnnotationPresent( Valid.class ),
+ fieldName
+ );
+ propertyDescriptors.put( field.getName(), elementDescriptor );
+ }
+ elementDescriptor.addConstraintDescriptor( constraintDescriptor );
+ }
+ return metadata;
+ }
+
+ public Class<T> getBeanClass() {
+ return beanClass;
+ }
+
+ public ElementDescriptor getBeanDescriptor() {
+ return beanDescriptor;
+ }
+
+ public List<Field> getCascadedFields() {
+ return cascadedFields;
+ }
+
+ public List<Method> getCascadedMethods() {
+ return cascadedMethods;
+ }
+
+ public List<Member> getCascadedMembers() {
+ List<Member> cascadedMembers = new ArrayList<Member>();
+ cascadedMembers.addAll( getCascadedFields() );
+ cascadedMembers.addAll( getCascadedMethods() );
+ return cascadedMembers;
+ }
+
+ public Map<String, List<String>> getGroupSequences() {
+ return groupSequences;
+ }
+
+ public List<ValidatorMetaData> getConstraintMetaDataList() {
+ return constraintMetaDataList;
+ }
+
+ public Map<String, ElementDescriptor> getPropertyDescriptors() {
+ return propertyDescriptors;
+ }
+
+ public ElementDescriptor getPropertyDescriptors(String property) {
+ return propertyDescriptors.get( property );
+ }
+}
\ No newline at end of file
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidationContext.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidationContext.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidationContext.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,184 @@
+// $Id: ValidationContext.java 105 2008-09-29 12:37:32Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.engine;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Stack;
+
+import org.hibernate.validation.impl.InvalidConstraintImpl;
+import org.hibernate.validation.util.IdentitySet;
+
+/**
+ * Context object keeping track of all processed objects and all failing constraints.
+ * At the same time it keeps track of the currently validated object, the current group
and property path.
+ * The way the validation works at the moment the validated object and the property path
have to be processed
+ * in a stack fashion.
+ *
+ * all sort of information needed Introduced to reduce the parameters passed around
between the different
+ * validate methdods in <code>ValidatorImpl</code>.
+ *
+ * @author Hardy Ferentschik
+ * @author Emmanuel Bernard
+ */
+public class ValidationContext<T> {
+
+ /**
+ * The root bean of the validation.
+ */
+ private final T rootBean;
+
+ /**
+ * Maps for each group name to an identity set to keep track of already validated
objects. We have to make sure
+ * that each object gets only validated once (per group).
+ */
+ private final Map<String, IdentitySet> processedObjects;
+
+ /**
+ * A list of all failing constraints so far.
+ */
+ private final List<InvalidConstraintImpl<T>> failingConstraints;
+
+ /**
+ * The current property path.
+ */
+ private String propertyPath;
+
+ /**
+ * The current group which is getting processed.
+ */
+ private String currentGroup;
+
+ /**
+ * Stack for keep track of the currently validated object.
+ */
+ private Stack<Object> validatedobjectStack = new Stack<Object>();
+
+
+ public ValidationContext(T object) {
+ this( object, object );
+ }
+
+ public ValidationContext(T rootBean, Object object) {
+ this.rootBean = rootBean;
+ validatedobjectStack.push( object );
+ processedObjects = new HashMap<String, IdentitySet>();
+ propertyPath = "";
+ failingConstraints = new ArrayList<InvalidConstraintImpl<T>>();
+ }
+
+ public Object peekValidatedObject() {
+ return validatedobjectStack.peek();
+ }
+
+ public void pushValidatedObject(Object validatedObject) {
+ validatedobjectStack.push( validatedObject );
+ }
+
+ public void popValidatedObject() {
+ validatedobjectStack.pop();
+ }
+
+ public T getRootBean() {
+ return rootBean;
+ }
+
+ public String getCurrentGroup() {
+ return currentGroup;
+ }
+
+ public void setCurrentGroup(String currentGroup) {
+ this.currentGroup = currentGroup;
+ }
+
+ public void markProcessedForCurrentGroup() {
+ if ( processedObjects.containsKey( currentGroup ) ) {
+ processedObjects.get( currentGroup ).add( validatedobjectStack.peek() );
+ }
+ else {
+ IdentitySet set = new IdentitySet();
+ set.add( validatedobjectStack.peek() );
+ processedObjects.put( currentGroup, set );
+ }
+ }
+
+ public boolean isProcessedForCurrentGroup(Object value) {
+ final IdentitySet objectsProcessedInCurrentGroups = processedObjects.get( currentGroup
);
+ return objectsProcessedInCurrentGroups != null &&
objectsProcessedInCurrentGroups.contains( value );
+ }
+
+ public void addConstraintFailure(InvalidConstraintImpl<T> failingConstraint) {
+ int i = failingConstraints.indexOf( failingConstraint );
+ if ( i == -1 ) {
+ failingConstraints.add( failingConstraint );
+ }
+ else {
+ failingConstraints.get( i ).addGroups( failingConstraint.getGroups() );
+ }
+ }
+
+ public List<InvalidConstraintImpl<T>> getFailingConstraints() {
+ return failingConstraints;
+ }
+
+ /**
+ * Adds a new level to the current property path of this context.
+ *
+ * @param property the new property to add to the current path.
+ */
+ public void pushProperty(String property) {
+ if ( propertyPath.length() == 0 ) {
+ propertyPath = property;
+ }
+ else {
+ propertyPath = propertyPath + "." + property;
+ }
+ }
+
+ /**
+ * Drops the last level of the current property path of this context.
+ */
+ public void popProperty() {
+ int lastIndex = propertyPath.lastIndexOf( '.' );
+ if ( lastIndex != -1 ) {
+ propertyPath = propertyPath.substring( 0, lastIndex );
+ }
+ else {
+ propertyPath = "";
+ }
+ }
+
+ public void appendIndexToPropertyPath(String index) {
+ propertyPath += index;
+ }
+
+ public void replacePropertyIndex(String index) {
+ propertyPath = propertyPath.replaceAll( "\\{0\\}", index );
+ }
+
+ public String peekPropertyPath() {
+ return propertyPath;
+ }
+
+ public boolean needsValidation(Set<String> groups) {
+ return groups.contains( currentGroup );
+ }
+}
\ No newline at end of file
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,575 @@
+// $Id: ValidatorImpl.java 113 2008-09-30 20:00:16Z epbernard $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.engine;
+
+import java.lang.reflect.Member;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import javax.validation.ConstraintDescriptor;
+import javax.validation.ConstraintFactory;
+import javax.validation.ElementDescriptor;
+import javax.validation.InvalidConstraint;
+import javax.validation.MessageResolver;
+import javax.validation.Validator;
+
+import org.hibernate.validation.Version;
+import org.hibernate.validation.impl.ConstraintDescriptorImpl;
+import org.hibernate.validation.impl.ConstraintFactoryImpl;
+import org.hibernate.validation.impl.InvalidConstraintImpl;
+import org.hibernate.validation.impl.ResourceBundleMessageResolver;
+import org.hibernate.validation.util.ReflectionHelper;
+import org.hibernate.validation.util.PropertyIterator;
+
+/**
+ * The main Bean Validation class.
+ *
+ * @author Emmanuel Bernard
+ * @author Hardy Ferentschik
+ * @todo Make all properties transient for serializability.
+ */
+public class ValidatorImpl<T> implements Validator<T> {
+
+ /**
+ * The default group/sequence name when no group parameter is passed to validate().
+ *
+ * @todo Is it correct to use this default string and if so is this the correct place to
define it?
+ */
+ private static final String DEFAULT_GROUP_NAME = "default";
+
+ private static final Set<Class> INDEXABLE_CLASS = new HashSet<Class>();
+
+ static {
+ INDEXABLE_CLASS.add( Integer.class );
+ INDEXABLE_CLASS.add( Long.class );
+ INDEXABLE_CLASS.add( String.class );
+ }
+
+ static {
+ Version.touch();
+ }
+
+ @SuppressWarnings("unchecked")
+ private final List<InvalidConstraintImpl<T>> EMPTY_CONSTRAINTS_LIST =
Collections.EMPTY_LIST;
+
+ /**
+ * A map for caching validators for cascaded entities.
+ */
+ private final Map<Class<?>, ValidatorImpl> subValidators = new
ConcurrentHashMap<Class<?>, ValidatorImpl>();
+
+ /**
+ * Gives access to the required parsed meta data.
+ */
+ private final MetaDataProvider<T> metaDataProvider;
+
+ /**
+ * Message resolver used for interpolating error messages.
+ */
+ private final MessageResolver messageResolver;
+
+ public ValidatorImpl(Class<T> beanClass, ConstraintFactory constraintFactory,
MessageResolver messageResolver) {
+ if ( beanClass == null ) {
+ throw new IllegalArgumentException( "Bean class paramter cannot be null" );
+ }
+
+ metaDataProvider = new MetaDataProviderImpl<T>( beanClass, constraintFactory );
+ this.messageResolver = messageResolver;
+ }
+
+ public ValidatorImpl(Class<T> beanClass) {
+ this( beanClass, new ConstraintFactoryImpl(), new ResourceBundleMessageResolver() );
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public Set<InvalidConstraint<T>> validate(T object, String... groups) {
+ if ( object == null ) {
+ throw new IllegalArgumentException( "Validation of a null object" );
+ }
+
+ ValidationContext<T> context = new ValidationContext<T>( object );
+ List<InvalidConstraintImpl<T>> list = validate( context, Arrays.asList(
groups ) );
+ return new HashSet<InvalidConstraint<T>>( list );
+ }
+
+ /**
+ * Validates the ovject contained in <code>context</code>.
+ *
+ * @param context A context object containing the object to validate together with other
state information needed
+ * for validation.
+ * @param groups A list of groups to validate.
+ *
+ * @return List of invalid constraints.
+ *
+ * @todo Currently we iterate the cascaded fields multiple times. Maybe we should change
to an approach where we iterate the object graph only once.
+ * @todo Context root bean can be a different object than the current Validator<T>
hence two different generics variables
+ */
+ private List<InvalidConstraintImpl<T>> validate(ValidationContext<T>
context, List<String> groups) {
+ if ( context.peekValidatedObject() == null ) {
+ return EMPTY_CONSTRAINTS_LIST;
+ }
+
+ // if no group is specified use the default
+ if ( groups.size() == 0 ) {
+ groups = Arrays.asList( DEFAULT_GROUP_NAME );
+ }
+
+ List<String> expandedGroups;
+ boolean isGroupSequence;
+ for ( String group : groups ) {
+ expandedGroups = new ArrayList<String>();
+ isGroupSequence = expandGroupName( group, expandedGroups );
+
+ for ( String expandedGroupName : expandedGroups ) {
+ context.setCurrentGroup( expandedGroupName );
+
+ validateConstraints( context );
+ validateCascadedConstraints( context );
+
+ if ( isGroupSequence && context.getFailingConstraints().size() > 0 ) {
+ break;
+ }
+ }
+ }
+ return context.getFailingConstraints();
+ }
+
+ /**
+ * Validates the non-cascaded constraints.
+ *
+ * @param context The current validation context.
+ */
+ private void validateConstraints(ValidationContext<T> context) {
+ for ( ValidatorMetaData metaData : metaDataProvider.getConstraintMetaDataList() ) {
+ ConstraintDescriptorImpl constraintDescriptor = metaData.getDescriptor();
+ context.pushProperty( metaData.getPropertyName() );
+
+ if ( !context.needsValidation( constraintDescriptor.getGroups() ) ) {
+ context.popProperty();
+ continue;
+ }
+
+ Object value = metaData.getValue( context.peekValidatedObject() );
+ ContextImpl contextImpl = new ContextImpl(constraintDescriptor);
+
+ if ( !constraintDescriptor.getConstraintImplementation().isValid( value, contextImpl )
) {
+ for ( ContextImpl.ErrorMessage error : contextImpl.getErrorMessages() ) {
+ String message = messageResolver.interpolate(
+ error.getMessage(),
+ constraintDescriptor,
+ context.peekValidatedObject()
+ );
+ InvalidConstraintImpl<T> failingConstraint = new
InvalidConstraintImpl<T>(
+ message,
+ context.getRootBean(),
+ metaDataProvider.getBeanClass(),
+ value,
+ context.peekPropertyPath(), //FIXME use error.getProperty()
+ context.getCurrentGroup()
+ );
+ context.addConstraintFailure( failingConstraint );
+ }
+ }
+ context.popProperty();
+ }
+ context.markProcessedForCurrentGroup();
+ }
+
+ private void validateCascadedConstraint(ValidationContext<T> context, Type type,
Object value) {
+ if ( value == null ) {
+ return;
+ }
+
+ Iterator<?> iter;
+ if ( ReflectionHelper.isCollection( type ) ) {
+ boolean isIterable = value instanceof Iterable;
+ Map<?, ?> map = !isIterable ? ( Map<?, ?> ) value : null;
+ Iterable<?> elements = isIterable ?
+ ( Iterable<?> ) value :
+ map.entrySet();
+ iter = elements.iterator();
+ context.appendIndexToPropertyPath( "[{0}]" );
+ }
+ else if ( ReflectionHelper.isArray( type ) ) {
+ List<?> arrayList = Arrays.asList( value );
+ iter = arrayList.iterator();
+ context.appendIndexToPropertyPath( "[{0}]" );
+ }
+ else {
+ List<Object> list = new ArrayList<Object>();
+ list.add( value );
+ iter = list.iterator();
+ }
+
+ validateCascadedConstraint( context, iter );
+ }
+
+ private void validateCascadedConstraints(ValidationContext<T> context) {
+ List<Member> cascadedMembers = getMetaDataProvider().getCascadedMembers();
+ for ( Member member : cascadedMembers ) {
+ Type type = ReflectionHelper.typeOf( member );
+ context.pushProperty( ReflectionHelper.getPropertyName( member ) );
+ ReflectionHelper.setAccessibility( member );
+ Object value = ReflectionHelper.getValue( member, context.peekValidatedObject() );
+ validateCascadedConstraint( context, type, value );
+ context.popProperty();
+ }
+ }
+
+ private void validateCascadedConstraint(ValidationContext<T> context,
Iterator<?> iter) {
+ Object actualValue;
+ String propertyIndex;
+ int i = 0;
+ while ( iter.hasNext() ) {
+ actualValue = iter.next();
+ propertyIndex = String.valueOf( i );
+ if ( actualValue instanceof Map.Entry ) {
+ Object key = ( ( Map.Entry ) actualValue ).getKey();
+ if ( INDEXABLE_CLASS.contains( key.getClass() ) ) {
+ propertyIndex = key.toString();
+ }
+ actualValue = ( ( Map.Entry ) actualValue ).getValue();
+ }
+
+ if ( context.isProcessedForCurrentGroup( actualValue ) ) {
+ i++;
+ continue;
+ }
+
+ context.replacePropertyIndex( propertyIndex );
+
+ Class cascadedClass = actualValue.getClass();
+ ValidatorImpl validatorImpl = getValidatorForClass( cascadedClass );
+ context.pushValidatedObject( actualValue );
+ validatorImpl.validate( context, Arrays.asList( context.getCurrentGroup() ) );
+ context.popValidatedObject();
+ i++;
+ }
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public Set<InvalidConstraint<T>> validateProperty(T object, String
propertyName, String... groups) {
+ List<InvalidConstraintImpl<T>> failingConstraints = new
ArrayList<InvalidConstraintImpl<T>>();
+ validateProperty( object, new PropertyIterator( propertyName ), failingConstraints,
groups );
+ return new HashSet<InvalidConstraint<T>>( failingConstraints );
+ }
+
+
+ private void validateProperty(T object, PropertyIterator propertyIter,
List<InvalidConstraintImpl<T>> failingConstraints, String... groups) {
+ DesrciptorValueWrapper wrapper = getConstraintDescriptorAndValueForPath( this,
propertyIter, object );
+
+ if ( wrapper == null ) {
+ return;
+ }
+
+ // if no group is specified use the default
+ if ( groups.length == 0 ) {
+ groups = new String[] { DEFAULT_GROUP_NAME };
+ }
+
+ List<String> expandedGroups;
+ boolean isGroupSequence;
+ for ( String group : groups ) {
+ expandedGroups = new ArrayList<String>();
+ isGroupSequence = expandGroupName( group, expandedGroups );
+
+ for ( String expandedGroupName : expandedGroups ) {
+
+ if ( !wrapper.descriptor.isInGroups( expandedGroupName ) ) {
+ continue;
+ }
+
+ ContextImpl contextImpl = new ContextImpl(wrapper.descriptor);
+ if ( !wrapper.descriptor.getConstraintImplementation().isValid( wrapper.value,
contextImpl ) ) {
+
+ for ( ContextImpl.ErrorMessage error : contextImpl.getErrorMessages() ) {
+ String message = messageResolver.interpolate(
+ error.getMessage(),
+ wrapper.descriptor,
+ wrapper.value
+ );
+ InvalidConstraintImpl<T> failingConstraint = new
InvalidConstraintImpl<T>(
+ message,
+ object,
+ ( Class<T> ) object.getClass(),
+ wrapper.value,
+ propertyIter.getOriginalProperty(), //FIXME use error.getProperty()
+ group
+ );
+ addFailingConstraint( failingConstraints, failingConstraint );
+ }
+ }
+
+ if ( isGroupSequence && failingConstraints.size() > 0 ) {
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Set<InvalidConstraint<T>> validateValue(String propertyName, Object
value, String... groups) {
+ List<InvalidConstraintImpl<T>> failingConstraints = new
ArrayList<InvalidConstraintImpl<T>>();
+ validateValue( value, new PropertyIterator( propertyName ), failingConstraints, groups
);
+ return new HashSet<InvalidConstraint<T>>( failingConstraints );
+ }
+
+
+ private void validateValue(Object object, PropertyIterator propertyIter,
List<InvalidConstraintImpl<T>> failingConstraints, String... groups) {
+ ConstraintDescriptorImpl constraintDescriptor = getConstraintDescriptorForPath( this,
propertyIter );
+
+ if ( constraintDescriptor == null ) {
+ return;
+ }
+
+ // if no group is specified use the default
+ if ( groups.length == 0 ) {
+ groups = new String[] { DEFAULT_GROUP_NAME };
+ }
+
+ List<String> expandedGroups;
+ boolean isGroupSequence;
+ for ( String group : groups ) {
+ expandedGroups = new ArrayList<String>();
+ isGroupSequence = expandGroupName( group, expandedGroups );
+
+ for ( String expandedGroupName : expandedGroups ) {
+
+ if ( !constraintDescriptor.isInGroups( expandedGroupName ) ) {
+ continue;
+ }
+
+ ContextImpl contextImpl = new ContextImpl(constraintDescriptor);
+ if ( !constraintDescriptor.getConstraintImplementation().isValid( object, contextImpl
) ) {
+ for ( ContextImpl.ErrorMessage error : contextImpl.getErrorMessages() ) {
+ String message = messageResolver.interpolate(
+ error.getMessage(),
+ constraintDescriptor,
+ object
+ );
+ InvalidConstraintImpl<T> failingConstraint = new
InvalidConstraintImpl<T>(
+ message,
+ null,
+ null,
+ object,
+ propertyIter.getOriginalProperty(), //FIXME use error.getProperty()
+ ""
+ );
+ addFailingConstraint( failingConstraints, failingConstraint );
+ }
+ }
+
+ if ( isGroupSequence && failingConstraints.size() > 0 ) {
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns the constraint descriptor for the given path relative to the specified
validator.
+ * <p>
+ * This method does not traverse an actual object, but rather tries to resolve the
porperty generically.
+ * </p>
+ * <p>
+ * This method is called recursively. Only if there is a valid 'validation path'
through the object graph
+ * a constraint descriptor will be returned.
+ * </p>
+ *
+ * @param validator the validator to check for constraints.
+ * @param propertyIter an instance of <code>PropertyIterator</code>
+ *
+ * @return The constraint descriptor matching the given path.
+ */
+ private ConstraintDescriptorImpl getConstraintDescriptorForPath(ValidatorImpl<?>
validator, PropertyIterator propertyIter) {
+
+ ConstraintDescriptorImpl matchingConstraintDescriptor = null;
+ propertyIter.split();
+
+ if ( !propertyIter.hasNext() ) {
+ List<ValidatorMetaData> metaDataList =
validator.getMetaDataProvider().getConstraintMetaDataList();
+ for ( ValidatorMetaData metaData : metaDataList ) {
+ ConstraintDescriptor constraintDescriptor = metaData.getDescriptor();
+ if ( metaData.getPropertyName().equals( propertyIter.getHead() ) ) {
+ matchingConstraintDescriptor = ( ConstraintDescriptorImpl ) constraintDescriptor;
+ }
+ }
+ }
+ else {
+ List<Member> cascadedMembers =
validator.getMetaDataProvider().getCascadedMembers();
+ for ( Member m : cascadedMembers ) {
+ if ( ReflectionHelper.getPropertyName( m ).equals( propertyIter.getHead() ) ) {
+ Type type = ReflectionHelper.typeOf( m );
+
+ if ( propertyIter.isIndexed() ) {
+ type = ReflectionHelper.getIndexedType( type );
+ if ( type == null ) {
+ continue;
+ }
+ }
+
+ ValidatorImpl v = getValidatorForClass( ( Class ) type );
+ matchingConstraintDescriptor = v.getConstraintDescriptorForPath( v, propertyIter );
+ }
+ }
+ }
+
+ return matchingConstraintDescriptor;
+ }
+
+
+ private DesrciptorValueWrapper
getConstraintDescriptorAndValueForPath(ValidatorImpl<?> validator, PropertyIterator
propertyIter, Object value) {
+
+ DesrciptorValueWrapper wrapper = null;
+ propertyIter.split();
+
+
+ // bottom out - there is only one token left
+ if ( !propertyIter.hasNext() ) {
+ List<ValidatorMetaData> metaDataList =
validator.getMetaDataProvider().getConstraintMetaDataList();
+ for ( ValidatorMetaData metaData : metaDataList ) {
+ ConstraintDescriptor constraintDescriptor = metaData.getDescriptor();
+ if ( metaData.getPropertyName().equals( propertyIter.getHead() ) ) {
+ return new DesrciptorValueWrapper(
+ ( ConstraintDescriptorImpl ) constraintDescriptor, metaData.getValue( value )
+ );
+ }
+ }
+ }
+ else {
+ List<Member> cascadedMembers =
validator.getMetaDataProvider().getCascadedMembers();
+ for ( Member m : cascadedMembers ) {
+ if ( ReflectionHelper.getPropertyName( m ).equals( propertyIter.getHead() ) ) {
+ ReflectionHelper.setAccessibility( m );
+ Object newValue = null;
+ if ( propertyIter.isIndexed() ) {
+ newValue = ReflectionHelper.getValue( m, value );
+ }
+ else {
+ newValue = ReflectionHelper.getIndexedValue( value, propertyIter.getIndex() );
+ }
+ ValidatorImpl cascadedValidator = getValidatorForClass( newValue.getClass() );
+ wrapper = cascadedValidator.getConstraintDescriptorAndValueForPath(
+ cascadedValidator, propertyIter, newValue
+ );
+ }
+ }
+ }
+
+ return wrapper;
+ }
+
+
+ private void addFailingConstraint(List<InvalidConstraintImpl<T>>
failingConstraints, InvalidConstraintImpl<T> failingConstraint) {
+ int i = failingConstraints.indexOf( failingConstraint );
+ if ( i == -1 ) {
+ failingConstraints.add( failingConstraint );
+ }
+ else {
+ failingConstraints.get( i ).addGroups( failingConstraint.getGroups() );
+ }
+ }
+
+
+ /**
+ * @todo add child validation
+ */
+ public boolean hasConstraints() {
+ return metaDataProvider.getConstraintMetaDataList().size() > 0;
+ }
+
+ public ElementDescriptor getBeanConstraints() {
+ return metaDataProvider.getBeanDescriptor();
+ }
+
+ public ElementDescriptor getConstraintsForProperty(String propertyName) {
+ return metaDataProvider.getPropertyDescriptors().get( propertyName );
+ }
+
+ public String[] getValidatedProperties() {
+ return metaDataProvider.getPropertyDescriptors()
+ .keySet()
+ .toArray( new String[metaDataProvider.getPropertyDescriptors().size()] );
+ }
+
+ public MetaDataProvider<T> getMetaDataProvider() {
+ return metaDataProvider;
+ }
+
+ /**
+ * Checks whether the provided group name is a group sequence and if so expands the
group name and add the expanded
+ * groups names to <code>expandedGroupName </code>
+ *
+ * @param groupName The group name to expand
+ * @param expandedGroupNames The exanded group names or just a list with the single
provided group name id the name
+ * was not expandable
+ *
+ * @return <code>true</code> if an expansion took place,
<code>false</code> otherwise.
+ */
+ private boolean expandGroupName(String groupName, List<String> expandedGroupNames)
{
+ if ( expandedGroupNames == null ) {
+ throw new IllegalArgumentException( "List cannot be empty" );
+ }
+
+ boolean isGroupSequence;
+
+ if ( metaDataProvider.getGroupSequences().containsKey( groupName ) ) {
+ expandedGroupNames.addAll( metaDataProvider.getGroupSequences().get( groupName ) );
+ isGroupSequence = true;
+ }
+ else {
+ expandedGroupNames.add( groupName );
+ isGroupSequence = false;
+ }
+ return isGroupSequence;
+ }
+
+ @SuppressWarnings("unchecked")
+ private <V> ValidatorImpl<V> getValidatorForClass(Class<V>
cascadedClass) {
+ ValidatorImpl<V> validatorImpl = subValidators.get( cascadedClass );
+ if ( validatorImpl == null ) {
+ validatorImpl = new ValidatorImpl<V>( cascadedClass );
+ subValidators.put( cascadedClass, validatorImpl );
+ }
+ return validatorImpl;
+ }
+
+ private class DesrciptorValueWrapper {
+ final ConstraintDescriptorImpl descriptor;
+ final Object value;
+
+ DesrciptorValueWrapper(ConstraintDescriptorImpl descriptor, Object value) {
+ this.descriptor = descriptor;
+ this.value = value;
+ }
+ }
+}
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorMetaData.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorMetaData.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorMetaData.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,188 @@
+// $Id: ValidatorMetaData.java 105 2008-09-29 12:37:32Z hardy.ferentschik $// $Id:
ValidatorMetaData.java 105 2008-09-29 12:37:32Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.engine;
+
+import java.lang.annotation.ElementType;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import javax.validation.ValidationException;
+
+import org.hibernate.validation.impl.ConstraintDescriptorImpl;
+import org.hibernate.validation.util.ReflectionHelper;
+
+/**
+ * Instances of this class abstract the constraint type (class, method or field
constraint). This allows
+ * a unified handling of constraints in the validator imlpementation.
+ *
+ * @author Hardy Ferentschik
+ */
+public class ValidatorMetaData {
+
+ /**
+ * The constraint specific meta data.
+ */
+ private final ConstraintDescriptorImpl descriptor;
+
+ /**
+ * The type (class) the constraint was defined on. <code>null</code> if the
constraint was specified on method or
+ * field level.
+ */
+ private final Type type;
+
+ /**
+ * The method the constraint was defined on. <code>null</code> if the
constraint was specified on class or
+ * field level.
+ */
+ private final Method method;
+
+ /**
+ * The field the constraint was defined on. <code>null</code> if the
constraint was specified on class or
+ * method level.
+ */
+ private final Field field;
+
+ /**
+ * The JavaBeans name for this constraint.
+ */
+ private final String propertyName;
+
+ /**
+ * Describes on which level (<code>TYPE</code>,
<code>METHOD</code>, <code>FIELD</code>) the constraint was
+ * defined on.
+ */
+ private final ElementType elementType;
+
+ public ValidatorMetaData(Type t, ConstraintDescriptorImpl constraintDescriptor) {
+ this.type = t;
+ this.method = null;
+ this.field = null;
+ this.descriptor = constraintDescriptor;
+ this.elementType = ElementType.TYPE;
+ this.propertyName = "";
+ }
+
+ public ValidatorMetaData(Method m, ConstraintDescriptorImpl constraintDescriptor) {
+ this.method = m;
+ this.type = null;
+ this.field = null;
+ this.descriptor = constraintDescriptor;
+ this.elementType = ElementType.METHOD;
+ this.propertyName = ReflectionHelper.getPropertyName( m );
+ }
+
+ public ValidatorMetaData(Field f, ConstraintDescriptorImpl constraintDescriptor) {
+ this.field = f;
+ this.method = null;
+ this.type = null;
+ this.descriptor = constraintDescriptor;
+ this.elementType = ElementType.FIELD;
+ this.propertyName = f.getName();
+ }
+
+ /**
+ * @param o the object from which to retrieve the value.
+ *
+ * @return Returns the value for this constraint from the specified object. Depending on
the type either the value itself
+ * is returned of method or field access is used to access the value.
+ */
+ public Object getValue(Object o) {
+ switch ( elementType ) {
+ case TYPE: {
+ return o;
+ }
+ case METHOD: {
+ return ReflectionHelper.getValue( method, o );
+ }
+ case FIELD: {
+ return ReflectionHelper.getValue( field, o );
+ }
+ default: {
+ throw new ValidationException(
+ "Invalid state of ValidatorMetaData. Parameter elementType has unexpected
value - " + elementType
+ );
+ }
+ }
+ }
+
+ /**
+ * @return Returns <code>true</code> in case the constraint is defined on a
collection, <code>false</code>
+ * otherwise.
+ */
+ public boolean isCollection() {
+ Type t = typeOfAnnoatedElement();
+ return ReflectionHelper.isCollection( t );
+ }
+
+ /**
+ * @return Returns <code>true</code> in case the constraint is defined on an
array, <code>false</code>
+ * otherwise.
+ */
+ public boolean isArray() {
+ Type t = typeOfAnnoatedElement();
+ return ReflectionHelper.isArray( t );
+ }
+
+ public ConstraintDescriptorImpl getDescriptor() {
+ return descriptor;
+ }
+
+ public Method getMethod() {
+ return method;
+ }
+
+ public Field getField() {
+ return field;
+ }
+
+ public Type getType() {
+ return type;
+ }
+
+ public String getPropertyName() {
+ return propertyName;
+ }
+
+ public ElementType getElementType() {
+ return elementType;
+ }
+
+ private Type typeOfAnnoatedElement() {
+ Type t;
+ switch ( elementType ) {
+ case TYPE: {
+ t = type;
+ break;
+ }
+ case METHOD: {
+ t = ReflectionHelper.typeOf( method );
+ break;
+ }
+ case FIELD: {
+ t = ReflectionHelper.typeOf( field );
+ break;
+ }
+ default: {
+ throw new ValidationException(
+ "Invalid state of ValidatorMetaData. Parameter elementType has unexpected
value - " + elementType
+ );
+ }
+ }
+ return t;
+ }
+}
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ConstraintDescriptorImpl.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ConstraintDescriptorImpl.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ConstraintDescriptorImpl.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,101 @@
+// $Id: ConstraintDescriptorImpl.java 105 2008-09-29 12:37:32Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.impl;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import javax.validation.Constraint;
+import javax.validation.ConstraintDescriptor;
+import javax.validation.ValidationException;
+
+/**
+ * Describe a single constraint.
+ *
+ * @author Emmanuel Bernard
+ */
+public class ConstraintDescriptorImpl implements ConstraintDescriptor {
+ private Annotation annotation;
+ private Constraint constraintImplementation;
+ private Set<String> contexts;
+ private Map<String, Object> parameters;
+
+
+ public ConstraintDescriptorImpl(Annotation annotation, String[] contexts, Constraint
validator) {
+ this.annotation = annotation;
+ if ( contexts.length == 0 ) {
+ contexts = new String[] { "default" };
+ }
+ this.contexts = new HashSet<String>();
+ this.contexts.addAll( Arrays.asList( contexts ) );
+ this.constraintImplementation = validator;
+ this.parameters = getAnnotationParameters( annotation );
+ }
+
+ /**
+ * Constraint declaration annotation
+ */
+ public Annotation getAnnotation() {
+ return annotation;
+ }
+
+ /**
+ * What are the contexts the constraint is applied on
+ */
+ public Set<String> getGroups() {
+ return contexts;
+ }
+
+ public boolean isInGroups(String group) {
+ return contexts.contains( group );
+ }
+
+ /**
+ * Return the constraint implementation routine
+ */
+ public Constraint getConstraintImplementation() {
+ return constraintImplementation;
+ }
+
+ public Map<String, Object> getParameters() {
+ return parameters;
+ }
+
+ private Map<String, Object> getAnnotationParameters(Annotation annotation) {
+ Method[] declaredMethods = annotation.annotationType().getDeclaredMethods();
+ Map<String, Object> parameters = new HashMap<String, Object>(
declaredMethods.length );
+ for ( Method m : declaredMethods ) {
+ try {
+ parameters.put( m.getName(), m.invoke( annotation ) );
+ }
+ catch ( IllegalAccessException e ) {
+ throw new ValidationException( "Unable to read annotation parameters: " +
annotation.getClass(), e );
+ }
+ catch ( InvocationTargetException e ) {
+ throw new ValidationException( "Unable to read annotation parameters: " +
annotation.getClass(), e );
+ }
+ }
+ return Collections.unmodifiableMap( parameters );
+ }
+}
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ConstraintFactoryImpl.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ConstraintFactoryImpl.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ConstraintFactoryImpl.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,41 @@
+// $Id: ConstraintFactoryImpl.java 105 2008-09-29 12:37:32Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.impl;
+
+import javax.validation.Constraint;
+import javax.validation.ConstraintFactory;
+import javax.validation.ValidationException;
+
+/**
+ * Default <code>ConstraintFactory</code> using a no-arg constructor.
+ *
+ * @author Emmanuel Bernard
+ */
+public class ConstraintFactoryImpl implements ConstraintFactory {
+ public <T extends Constraint> T getInstance(Class<T> key) {
+ try {
+ return key.newInstance();
+ }
+ catch ( InstantiationException e ) {
+ throw new ValidationException( "Unable to instanciate " + key, e );
+ }
+ catch ( IllegalAccessException e ) {
+ throw new ValidationException( "Unable to instanciate " + key, e );
+ }
+ }
+}
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ElementDescriptorImpl.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ElementDescriptorImpl.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ElementDescriptorImpl.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,90 @@
+// $Id: ElementDescriptorImpl.java 105 2008-09-29 12:37:32Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.impl;
+
+import java.lang.annotation.ElementType;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import javax.validation.ConstraintDescriptor;
+import javax.validation.ElementDescriptor;
+
+/**
+ * Describe a validated element (class, field or property).
+ *
+ * @author Emmanuel Bernard
+ * @author Hardy Ferentschik
+ * @todo Should returnType be renamed to type?
+ * @todo Handle problem in descirbing cyclic dependecies for propertyPath
+ */
+public class ElementDescriptorImpl implements ElementDescriptor {
+ private final ElementType elementType;
+ private final Class returnType;
+ private final boolean cascaded;
+ private final List<ConstraintDescriptor> constraintDescriptors = new
ArrayList<ConstraintDescriptor>();
+ private final String propertyPath;
+
+
+ public ElementDescriptorImpl(ElementType elementType, Class returnType, boolean
cascaded, String propertyPath) {
+ this.elementType = elementType;
+ this.returnType = returnType;
+ this.cascaded = cascaded;
+ this.propertyPath = propertyPath;
+ }
+
+ public void addConstraintDescriptor(ConstraintDescriptorImpl constraintDescriptor) {
+ constraintDescriptors.add( constraintDescriptor );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ElementType getElementType() {
+ return elementType;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @todo Generic type or regular type?
+ */
+ public Class getReturnType() {
+ return returnType;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isCascaded() {
+ return cascaded;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<ConstraintDescriptor> getConstraintDescriptors() {
+ return Collections.unmodifiableList( constraintDescriptors );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getPropertyPath() {
+ return propertyPath;
+ }
+}
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/HibernateValidationProvider.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/HibernateValidationProvider.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/HibernateValidationProvider.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,65 @@
+// $Id: HibernateValidationProvider.java 105 2008-09-29 12:37:32Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.impl;
+
+import javax.validation.ValidationException;
+import javax.validation.ValidatorBuilder;
+import javax.validation.ValidatorFactory;
+import javax.validation.spi.ValidationProvider;
+import javax.validation.spi.ValidatorBuilderImplementor;
+import javax.validation.spi.BootstrapState;
+
+import org.hibernate.validation.HibernateValidatorBuilder;
+
+/**
+ * Default implementation of <code>ValidationProvider</code> within Hibernate
validator.
+ *
+ * @author Emmanuel Bernard
+ * @author Hardy Ferentschik
+ */
+public class HibernateValidationProvider implements ValidationProvider {
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isSuitable(Class<? extends ValidatorBuilder<?>> builderClass)
{
+ return builderClass == HibernateValidatorBuilder.class;
+ }
+
+ public <T extends ValidatorBuilder<T>> T
createSpecializedValidatorBuilder(BootstrapState state, Class<T> builderClass) {
+ if ( ! isSuitable( builderClass ) ) {
+ throw new ValidationException("Illegal call to
createSpecializedValidatorBuilder() for a non suitable provider");
+ }
+ //cast protected by isSuitable call
+ return builderClass.cast( new ValidatorBuilderImpl( this ) );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ValidatorBuilder<?> createGenericValidatorBuilder(BootstrapState state) {
+ return new ValidatorBuilderImpl( state );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ValidatorFactory buildValidatorFactory(ValidatorBuilderImplementor
validatorBuilder) {
+ return new ValidatorFactoryImpl( validatorBuilder );
+ }
+}
Property changes on:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/HibernateValidationProvider.java
___________________________________________________________________
Name: svn:executable
+ *
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/InvalidConstraintImpl.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/InvalidConstraintImpl.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/InvalidConstraintImpl.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,137 @@
+// $Id: InvalidConstraintImpl.java 105 2008-09-29 12:37:32Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.impl;
+
+import java.util.HashSet;
+import java.util.Set;
+import javax.validation.InvalidConstraint;
+
+/**
+ * @author Emmanuel Bernard
+ * @author Hardy Ferentschik
+ */
+public class InvalidConstraintImpl<T> implements InvalidConstraint<T> {
+ private String message;
+ private T rootBean;
+ private Class<T> beanClass;
+ private Object value;
+ private String propertyPath;
+ private HashSet<String> groups;
+
+
+ public InvalidConstraintImpl(String message, T rootBean, Class<T> beanClass,
Object value, String propertyPath, String group) {
+ this.message = message;
+ this.rootBean = rootBean;
+ this.beanClass = beanClass;
+ this.value = value;
+ this.propertyPath = propertyPath;
+ groups = new HashSet<String>();
+ groups.add( group );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getMessage() {
+ return message;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public T getRootBean() {
+ return rootBean;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Class<T> getBeanClass() {
+ return beanClass;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Object getValue() {
+ return value;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getPropertyPath() {
+ return propertyPath;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Set<String> getGroups() {
+ return groups;
+ }
+
+ public void addParent(T parentBean, String parentProperty) {
+ this.propertyPath = parentProperty + "." + propertyPath;
+ this.rootBean = parentBean;
+ }
+
+ public void addGroups(Set<String> groupSet) {
+ groups.addAll( groupSet );
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if ( this == o ) {
+ return true;
+ }
+ if ( !( o instanceof InvalidConstraintImpl ) ) {
+ return false;
+ }
+
+ InvalidConstraintImpl that = ( InvalidConstraintImpl ) o;
+
+ if ( beanClass != null ? !beanClass.equals( that.beanClass ) : that.beanClass != null )
{
+ return false;
+ }
+ if ( message != null ? !message.equals( that.message ) : that.message != null ) {
+ return false;
+ }
+ if ( propertyPath != null ? !propertyPath.equals( that.propertyPath ) :
that.propertyPath != null ) {
+ return false;
+ }
+ if ( rootBean != null ? !rootBean.equals( that.rootBean ) : that.rootBean != null ) {
+ return false;
+ }
+ if ( value != null ? !value.equals( that.value ) : that.value != null ) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = message != null ? message.hashCode() : 0;
+ result = 31 * result + ( rootBean != null ? rootBean.hashCode() : 0 );
+ result = 31 * result + ( beanClass != null ? beanClass.hashCode() : 0 );
+ result = 31 * result + ( value != null ? value.hashCode() : 0 );
+ result = 31 * result + ( propertyPath != null ? propertyPath.hashCode() : 0 );
+ return result;
+ }
+}
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ResourceBundleMessageResolver.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ResourceBundleMessageResolver.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ResourceBundleMessageResolver.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,151 @@
+// $Id: ResourceBundleMessageResolver.java 105 2008-09-29 12:37:32Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.impl;
+
+import java.util.Locale;
+import java.util.Map;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javax.validation.ConstraintDescriptor;
+import javax.validation.MessageResolver;
+
+import org.slf4j.Logger;
+
+import org.hibernate.validation.util.LoggerFactory;
+
+
+/**
+ * Resource bundle backed message resolver.
+ *
+ * @author Emmanuel Bernard
+ */
+public class ResourceBundleMessageResolver implements MessageResolver {
+ private static final String DEFAULT_VALIDATION_MESSAGES =
"org.hibernate.validation.ValidationMessages";
+ private static final String USER_VALIDATION_MESSAGES = "ValidationMessages";
+ private static final Logger log = LoggerFactory.make();
+
+ /**
+ * Regular expression used to do message interpolation.
+ */
+ private static final Pattern messagePattern = Pattern.compile(
"\\{([\\w\\.]+)\\}" );
+ private ResourceBundle defaultResourceBundle;
+ private ResourceBundle userResourceBundle;
+
+ public ResourceBundleMessageResolver() {
+ userResourceBundle = getFileBasedResourceBundle();
+ defaultResourceBundle = ResourceBundle.getBundle( DEFAULT_VALIDATION_MESSAGES );
+ }
+
+ public ResourceBundleMessageResolver(ResourceBundle resourceBundle) {
+ if ( resourceBundle == null ) {
+ userResourceBundle = getFileBasedResourceBundle();
+ }
+ else {
+ this.userResourceBundle = resourceBundle;
+ }
+ defaultResourceBundle = ResourceBundle.getBundle( DEFAULT_VALIDATION_MESSAGES );
+ }
+
+ /**
+ * Search current thread classloader for the resource bundle. If not found, search
validator (this) classloader.
+ *
+ * @return the resource bundle or <code>null</code> if none is found.
+ */
+ private ResourceBundle getFileBasedResourceBundle() {
+ ResourceBundle rb = null;
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ if ( classLoader != null ) {
+ rb = loadBundle( classLoader, USER_VALIDATION_MESSAGES + " not found by thread
local classloader" );
+ }
+ if ( rb == null ) {
+ rb = loadBundle(
+ this.getClass().getClassLoader(), USER_VALIDATION_MESSAGES + " not found by
validator classloader"
+ );
+ }
+ if ( log.isDebugEnabled() ) {
+ if ( rb != null ) {
+ log.debug( USER_VALIDATION_MESSAGES + " found" );
+ }
+ else {
+ log.debug( USER_VALIDATION_MESSAGES + " not found. Delegating to " +
DEFAULT_VALIDATION_MESSAGES );
+ }
+ }
+ return rb;
+ }
+
+ private ResourceBundle loadBundle(ClassLoader classLoader, String message) {
+ ResourceBundle rb = null;
+ try {
+ rb = ResourceBundle.getBundle( USER_VALIDATION_MESSAGES, Locale.getDefault(),
classLoader );
+ }
+ catch ( MissingResourceException e ) {
+ log.trace( message );
+ }
+ return rb;
+ }
+
+ public String interpolate(String message, ConstraintDescriptor constraintDescriptor,
Object value) {
+ //probably no need for caching, but it could be done by parameters since the map
+ //is immutable and uniquely built per Validation definition, the comparaison has to be
based on == and not equals though
+ return replace( message, constraintDescriptor.getParameters() );
+ }
+
+
+ private String replace(String message, Map<String, Object> parameters) {
+ Matcher matcher = messagePattern.matcher( message );
+ StringBuffer sb = new StringBuffer();
+ while ( matcher.find() ) {
+ matcher.appendReplacement( sb, resolveParameter( matcher.group( 1 ), parameters ) );
+ }
+ matcher.appendTail( sb );
+ return sb.toString();
+ }
+
+
+ private String resolveParameter(String token, Map<String, Object> parameters) {
+ Object variable = parameters.get( token );
+ if ( variable != null ) {
+ return variable.toString();
+ }
+
+ StringBuffer buffer = new StringBuffer();
+ String string = null;
+ try {
+ string = userResourceBundle != null ? userResourceBundle.getString( token ) : null;
+ }
+ catch ( MissingResourceException e ) {
+ //give a second chance with the default resource bundle
+ }
+ if ( string == null ) {
+ try {
+ string = defaultResourceBundle.getString( token );
+ }
+ catch ( MissingResourceException e ) {
+ //return the unchanged string
+ buffer.append( "{" ).append( token ).append( '}' );
+ }
+ }
+ if ( string != null ) {
+ // call resolve recusively!
+ buffer.append( replace( string, parameters ) );
+ }
+ return buffer.toString();
+ }
+}
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ValidatorBuilderImpl.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ValidatorBuilderImpl.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ValidatorBuilderImpl.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,116 @@
+// $Id: ValidatorBuilderImpl.java 105 2008-09-29 12:37:32Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.impl;
+
+import java.io.InputStream;
+import java.util.List;
+import javax.validation.ConstraintFactory;
+import javax.validation.MessageResolver;
+import javax.validation.ValidationException;
+import javax.validation.ValidationProviderResolver;
+import javax.validation.ValidatorBuilder;
+import javax.validation.ValidatorFactory;
+import javax.validation.bootstrap.DefaultValidationProviderResolver;
+import javax.validation.spi.ValidationProvider;
+import javax.validation.spi.ValidatorBuilderImplementor;
+import javax.validation.spi.BootstrapState;
+
+import org.hibernate.validation.HibernateValidatorBuilder;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class ValidatorBuilderImpl implements HibernateValidatorBuilder,
ValidatorBuilderImplementor {
+ private MessageResolver messageResolver = new ResourceBundleMessageResolver();
+ private ConstraintFactory constraintFactory = new ConstraintFactoryImpl();
+ private String configurationFile = "META-INF/validation.xml";
+ private final ValidationProvider provider;
+ private final ValidationProviderResolver providerResolver;
+
+ public ValidatorBuilderImpl(BootstrapState state) {
+ if (state.getValidationProviderResolver() == null) {
+ this.providerResolver = new DefaultValidationProviderResolver();
+ }
+ else {
+ this.providerResolver = state.getValidationProviderResolver();
+ }
+ this.provider = null;
+ }
+
+ public ValidatorBuilderImpl(ValidationProvider provider) {
+ if ( provider == null ) {
+ throw new ValidationException( "Assertion error: inconsistent
ValidatorBuilderImpl construction");
+ }
+ this.provider = provider;
+ this.providerResolver = null;
+ }
+
+ public ValidatorBuilderImpl messageResolver(MessageResolver resolver) {
+ this.messageResolver = resolver;
+ return this;
+ }
+
+ public ValidatorBuilderImpl constraintFactory(ConstraintFactory constraintFactory) {
+ this.constraintFactory = constraintFactory;
+ return this;
+ }
+
+ public ValidatorFactory build() {
+ if ( isSpecificProvider() ) {
+ return provider.buildValidatorFactory( this );
+ }
+ else {
+ //read provider name from configuration
+ Class<? extends ValidatorBuilder<?>> providerClass = null;
+
+ if ( providerClass != null ) {
+ for ( ValidationProvider provider : providerResolver.getValidationProviders() ) {
+ if ( provider.isSuitable( providerClass ) ) {
+ return provider.buildValidatorFactory( this );
+ }
+ }
+ throw new ValidationException( "Unable to find provider: " + providerClass
);
+ }
+ else {
+ List<ValidationProvider> providers =
providerResolver.getValidationProviders();
+ assert providers.size() != 0; //I run therefore I am
+ return providers.get( 0 ).buildValidatorFactory( this );
+ }
+ }
+ }
+
+ private boolean isSpecificProvider() {
+ return provider != null;
+ }
+
+ public MessageResolver getMessageResolver() {
+ return messageResolver;
+ }
+
+ public ConstraintFactory getConstraintFactory() {
+ return constraintFactory;
+ }
+
+ public ValidatorBuilderImpl configure(InputStream stream) {
+ return null; //To change body of implemented methods use File | Settings | File
Templates.
+ }
+
+ public InputStream getConfigurationStream() {
+ return null; //To change body of implemented methods use File | Settings | File
Templates.
+ }
+}
Property changes on:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ValidatorBuilderImpl.java
___________________________________________________________________
Name: svn:executable
+ *
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ValidatorFactoryImpl.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ValidatorFactoryImpl.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ValidatorFactoryImpl.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,50 @@
+// $Id: ValidatorFactoryImpl.java 105 2008-09-29 12:37:32Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.impl;
+
+import javax.validation.ConstraintFactory;
+import javax.validation.MessageResolver;
+import javax.validation.Validator;
+import javax.validation.ValidatorFactory;
+import javax.validation.spi.ValidatorBuilderImplementor;
+
+import org.hibernate.validation.engine.ValidatorImpl;
+
+/**
+ * @author Emmanuel Bernard
+ * @author Hardy Ferentschik
+ */
+public class ValidatorFactoryImpl implements ValidatorFactory {
+
+ private final MessageResolver messageResolver;
+ private final ConstraintFactory constraintFactory;
+
+
+ public ValidatorFactoryImpl(ValidatorBuilderImplementor validatorBuilder) {
+ this.messageResolver = validatorBuilder.getMessageResolver();
+ this.constraintFactory = validatorBuilder.getConstraintFactory();
+ //do init metadata from XML form
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public <T> Validator<T> getValidator(Class<T> clazz) {
+ return new ValidatorImpl<T>( clazz, constraintFactory, messageResolver );
+ }
+}
Property changes on:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ValidatorFactoryImpl.java
___________________________________________________________________
Name: svn:executable
+ *
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/IdentitySet.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/IdentitySet.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/IdentitySet.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,107 @@
+// $Id: IdentitySet.java 105 2008-09-29 12:37:32Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.util;
+
+import java.util.Collection;
+import java.util.IdentityHashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Set that compares object by identity rather than equality.
+ *
+ * @author Emmanuel Bernard
+ */
+public class IdentitySet implements Set {
+ private Map<Object, Object> map;
+ private Object CONTAINS = new Object();
+
+ public IdentitySet() {
+ this( 10 );
+ }
+
+ public IdentitySet(int size) {
+ this.map = new IdentityHashMap<Object, Object>( size );
+ }
+
+ public int size() {
+ return map.size();
+ }
+
+ public boolean isEmpty() {
+ return map.isEmpty();
+ }
+
+ public boolean contains(Object o) {
+ return map.containsKey( o );
+ }
+
+ public Iterator iterator() {
+ return map.keySet().iterator();
+ }
+
+ public Object[] toArray() {
+ return map.keySet().toArray();
+ }
+
+ public boolean add(Object o) {
+ return map.put( o, CONTAINS ) == null;
+ }
+
+ public boolean remove(Object o) {
+ return map.remove( o ) == CONTAINS;
+ }
+
+ public boolean addAll(Collection c) {
+ boolean doThing = false;
+ for ( Object o : c ) {
+ doThing = doThing || add( o );
+ }
+ return doThing;
+ }
+
+ public void clear() {
+ map.clear();
+ }
+
+ public boolean removeAll(Collection c) {
+ boolean remove = false;
+ for ( Object o : c ) {
+ remove = remove || remove( o );
+ }
+ return remove;
+ }
+
+ public boolean retainAll(Collection c) {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean containsAll(Collection c) {
+ for ( Object o : c ) {
+ if ( !contains( o ) ) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public Object[] toArray(Object[] a) {
+ return map.keySet().toArray( a );
+ }
+}
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/LoggerFactory.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/LoggerFactory.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/LoggerFactory.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,32 @@
+// :$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.util;
+
+import org.slf4j.Logger;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class LoggerFactory {
+ public static Logger make() {
+ Throwable t = new Throwable();
+ StackTraceElement directCaller = t.getStackTrace()[1];
+ return org.slf4j.LoggerFactory.getLogger( directCaller.getClassName() );
+ }
+}
+
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/PropertyIterator.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/PropertyIterator.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/PropertyIterator.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,102 @@
+// $Id: PropertyIterator.java 112 2008-09-30 08:08:50Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.util;
+
+/**
+ * @author Hardy Ferentschik
+ */
+
+/**
+ * Helper class to iterate over a property. After constructing an instance of this class
one can with
+ * successive calls to <code>split()</code> split the property into a head
and tail section. The head will contain the
+ * property up to the first '.' and tail the rest. If head is an indexed value it
is further seperated into its actual
+ * value and index. For example, <code>new
PropertyNavigator("order[2].orderNumer").split()</code> will result into:
+ * <ul>
+ * <li> <code>getHead() == "order"</code> </li>
+ * <li> <code>getIndex() == "2"</code> </li>
+ * <li> <code>getTail() == "orderNumber"</code> </li>
+ * </ul>.
+ */
+public class PropertyIterator {
+ final String originalProperty;
+ String head;
+ String index;
+ String tail;
+
+ public PropertyIterator(String property) {
+ this.originalProperty = property;
+ if ("".equals( property ) ) {
+ this.tail = null;
+ } else {
+ this.tail = property;
+ }
+ }
+
+ public boolean hasNext() {
+ return tail != null;
+ }
+
+ /**
+ * Splits the property at the next '.'
+ *
+ * @todo Add error handling in case the property uses wrong characters or has unbalanced
[]
+ */
+ public void split() {
+
+ if ( tail == null ) {
+ return;
+ }
+
+ String[] tokens = tail.split( "\\.", 2 ); // split the property at the first
.
+
+ head = tokens[0];
+ index = null;
+
+ if ( head.contains( "[" ) ) {
+ head = tokens[0].substring( 0, tokens[0].indexOf( "[" ) );
+ index = tokens[0].substring( tokens[0].indexOf( "[" ) + 1,
tokens[0].indexOf( "]" ) );
+ }
+
+ if ( tokens.length > 1 ) {
+ tail = tokens[1];
+ }
+ else {
+ tail = null;
+ }
+ }
+
+ public String getOriginalProperty() {
+ return originalProperty;
+ }
+
+ public String getHead() {
+ return head;
+ }
+
+ public String getTail() {
+ return tail;
+ }
+
+ public String getIndex() {
+ return index;
+ }
+
+ public boolean isIndexed() {
+ return index != null;
+ }
+}
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/ReflectionHelper.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/ReflectionHelper.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/ReflectionHelper.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,309 @@
+// $Id: ReflectionHelper.java 111 2008-09-30 08:00:12Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.util;
+
+import java.beans.Introspector;
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Field;
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.WildcardType;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Iterator;
+import java.util.Arrays;
+import java.util.List;
+import javax.validation.ValidationException;
+
+/**
+ * Some reflection utility methods.
+ *
+ * @author Hardy Ferentschik
+ */
+public class ReflectionHelper {
+
+ private ReflectionHelper() {
+ }
+
+ /**
+ * Process bean properties getter by applying the JavaBean naming conventions.
+ *
+ * @param member the member for which to get the property name.
+ *
+ * @return The bean method name with the "is" or "get" prefix
stripped off, <code>null</code>
+ * the method name id not according to the JavaBeans standard.
+ *
+ * @todo reference the JavaBean naming conventions spec here
+ */
+ public static String getPropertyName(Member member) {
+ String name = null;
+
+ if ( member instanceof Field ) {
+ name = member.getName();
+ }
+
+ if ( member instanceof Method ) {
+ String methodName = member.getName();
+ if ( methodName.startsWith( "is" ) ) {
+ name = Introspector.decapitalize( methodName.substring( 2 ) );
+ }
+ else if ( methodName.startsWith( "get" ) ) {
+ name = Introspector.decapitalize( methodName.substring( 3 ) );
+ }
+ }
+
+ return name;
+ }
+
+ /**
+ * @param member The <code>Member</code> instance for which to retrieve the
type.
+ *
+ * @return Retrurns the <code>Type</code> of the given
<code>Field</code> or <code>Method</code>.
+ *
+ * @throws IllegalArgumentException in case <code>member</code> is not a
<code>Field</code> or <code>Method</code>.
+ */
+ public static Type typeOf(Member member) {
+ if ( member instanceof Field ) {
+ return ( ( Field ) member ).getGenericType();
+ }
+ if ( member instanceof Method ) {
+ return ( ( Method ) member ).getGenericReturnType();
+ }
+ throw new IllegalArgumentException( "Member " + member + " is neither a
field nor a method" );
+ }
+
+
+ public static Object getValue(Member member, Object object) {
+ Object value = null;
+
+ if ( member instanceof Method ) {
+ Method method = ( Method ) member;
+ try {
+ value = method.invoke( object );
+ }
+ catch ( IllegalAccessException e ) {
+ throw new ValidationException( "Unable to access " + method.getName(), e
);
+ }
+ catch ( InvocationTargetException e ) {
+ throw new ValidationException( "Unable to access " + method.getName(), e
);
+ }
+ }
+ else if ( member instanceof Field ) {
+ Field field = ( Field ) member;
+ try {
+ value = field.get( object );
+ }
+ catch ( IllegalAccessException e ) {
+ throw new ValidationException( "Unable to access " + field.getName(), e );
+ }
+ }
+ return value;
+ }
+
+ public static void setAccessibility(Member member) {
+ if ( !Modifier.isPublic( member.getModifiers() ) ) {
+ //Sun's ease of use, sigh...
+ ( ( AccessibleObject ) member ).setAccessible( true );
+ }
+ }
+
+ public static Class<?> loadClass(String name, Class caller) throws
ClassNotFoundException {
+ try {
+ //try context classloader, if fails try caller classloader
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ if ( loader != null ) {
+ return loader.loadClass( name );
+ }
+ }
+ catch ( ClassNotFoundException e ) {
+ //trying caller classloader
+ if ( caller == null ) {
+ throw e;
+ }
+ }
+ return Class.forName( name, true, caller.getClassLoader() );
+ }
+
+ /**
+ * Determines the type of elements of a generic collection or array.
+ *
+ * @param type the collection or array type.
+ *
+ * @return the element type of the generic collection/array or
<code>null</code> in case the specified type is not a collection/array or the
+ * element type cannot be determined.
+ *
+ * @todo Verify algorithm. Does this hold up in most cases?
+ */
+ public static Type getIndexedType(Type type) {
+ Type indexedType = null;
+ if ( isCollection( type ) && type instanceof ParameterizedType ) {
+ ParameterizedType paramType = ( ParameterizedType ) type;
+ Class collectionClass = getCollectionClass( type );
+ if ( collectionClass == Collection.class || collectionClass == java.util.List.class ||
collectionClass == java.util.Set.class || collectionClass == java.util.SortedSet.class )
{
+ indexedType = paramType.getActualTypeArguments()[0];
+ }
+ else if ( collectionClass == Map.class || collectionClass == java.util.SortedMap.class
) {
+ indexedType = paramType.getActualTypeArguments()[1];
+ }
+ }
+ else if ( ReflectionHelper.isArray( type ) && type instanceof GenericArrayType
) {
+ GenericArrayType arrayTye = ( GenericArrayType ) type;
+ indexedType = arrayTye.getGenericComponentType();
+ }
+ return indexedType;
+ }
+
+
+ /**
+ * @param type the type to check.
+ *
+ * @return Returns <code>true</code> if <code>type</code> is an
array type or <code>false</code> otherwise.
+ */
+ public static boolean isArray(Type type) {
+ if ( type instanceof Class ) {
+ return ( ( Class ) type ).isArray();
+ }
+ return type instanceof GenericArrayType;
+ }
+
+
+ /**
+ * @param type the type to check.
+ *
+ * @return Returns <code>true</code> if <code>type</code> is a
collection type or <code>false</code> otherwise.
+ */
+ public static boolean isCollection(Type type) {
+ return getCollectionClass( type ) != null;
+ }
+
+
+ /**
+ * Returns the collection class for the specified type provided it is a collection.
+ * <p>
+ * This is a simplified version of commons annotations
</code>TypeUtils.getCollectionClass()</code>.
+ * </p>
+ *
+ * @param type the <code>Type</code> to check.
+ *
+ * @return the collection class, or <code>null</code> if type is not a
collection class.
+ */
+ @SuppressWarnings("unchecked")
+ public static Class<? extends Collection> getCollectionClass(Type type) {
+ if ( type instanceof Class && isCollectionClass( ( Class ) type ) ) {
+ return ( Class<? extends Collection> ) type;
+ }
+ if ( type instanceof ParameterizedType ) {
+ return getCollectionClass( ( ( ParameterizedType ) type ).getRawType() );
+ }
+ if ( type instanceof WildcardType ) {
+ Type[] upperBounds = ( ( WildcardType ) type ).getUpperBounds();
+ if ( upperBounds.length == 0 ) {
+ return null;
+ }
+ return getCollectionClass( upperBounds[0] );
+ }
+ return null;
+ }
+
+ /**
+ * Checks whether the specified class parameter is an instance of a collection class.
+ *
+ * @param clazz <code>Class</code> to check.
+ *
+ * @return <code>true</code> is <code>clazz</code> is instance
of a collection class, <code>false</code> otherwise.
+ */
+ private static boolean isCollectionClass(Class<?> clazz) {
+ Class[] interfaces = clazz.getInterfaces();
+
+ for ( Class interfaceClass : interfaces) {
+ if (interfaceClass == Collection.class
+ || interfaceClass == java.util.List.class
+ || interfaceClass == java.util.Set.class
+ || interfaceClass == java.util.Map.class
+ || interfaceClass == java.util.SortedSet.class // extension to the specs
+ || interfaceClass == java.util.SortedMap.class) { // extension to the specs)
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Tries to retrieve the indexed value from the specified object.
+ *
+ * @param value The object from which to retrieve the indexed value. The object has to
be non <code>null</null> and
+ * either a collection or array.
+ * @param index The index. The index does not have to be numerical.
<code>value</code> could also be a map in which
+ * case the index could also be a string key.
+ * @return The indexed value or <code>null</code> if
<code>value</code> is <code>null</code> or not a collection or
array.
+ * <code>null</code> is also returned in case the index does not exist.
+ */
+ public static Object getIndexedValue(Object value, String index) {
+ if ( value == null ) {
+ return null;
+ }
+
+ // try to create the index
+ int numIndex = -1;
+ try {
+ numIndex = Integer.valueOf( index );
+ }
+ catch ( NumberFormatException nfe ) {
+ // ignore
+ }
+
+ if ( numIndex == -1 ) { // must be a map indexed by string
+ Map<?, ?> map = ( Map<?, ?> ) value;
+ //noinspection SuspiciousMethodCalls
+ return map.get( index );
+ }
+
+ Iterator<?> iter = null;
+ Type type = value.getClass();
+ if ( isCollection( type ) ) {
+ boolean isIterable = value instanceof Iterable;
+ Map<?, ?> map = !isIterable ? ( Map<?, ?> ) value : null;
+ Iterable<?> elements = isIterable ?
+ ( Iterable<?> ) value :
+ map.values();
+ iter = elements.iterator();
+
+ }
+ else if ( isArray( type ) ) {
+ List<?> arrayList = Arrays.asList( value );
+ iter = arrayList.iterator();
+ }
+
+ int i = 0;
+ Object o;
+ while ( iter.hasNext() ) {
+ o = iter.next();
+ if ( i == numIndex ) {
+ return o;
+ }
+ i++;
+ }
+ return null;
+ }
+}
Added:
validator/trunk/hibernate-validator/src/main/resources/META-INF/services/javax.validation.spi.ValidationProvider
===================================================================
---
validator/trunk/hibernate-validator/src/main/resources/META-INF/services/javax.validation.spi.ValidationProvider
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/resources/META-INF/services/javax.validation.spi.ValidationProvider 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1 @@
+org.hibernate.validation.impl.HibernateValidationProvider
\ No newline at end of file
Added:
validator/trunk/hibernate-validator/src/main/resources/org/hibernate/validation/ValidationMessages.properties
===================================================================
---
validator/trunk/hibernate-validator/src/main/resources/org/hibernate/validation/ValidationMessages.properties
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/resources/org/hibernate/validation/ValidationMessages.properties 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,4 @@
+validator.notNull=may not be null
+validator.length=length must be between {min} and {max}
+validator.notEmpty=may not be empty
+validator.pattern=must match "{regex}"
\ No newline at end of file
Added: validator/trunk/hibernate-validator/src/site/site.xml
===================================================================
--- validator/trunk/hibernate-validator/src/site/site.xml (rev 0)
+++ validator/trunk/hibernate-validator/src/site/site.xml 2008-10-02 10:39:39 UTC (rev
15247)
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<project name="Maven">
+ <bannerLeft>
+ <name>Maven</name>
+ <
src>http://maven.apache.org/images/apache-maven-project.png</src>
+ <
href>http://maven.apache.org/</href>
+ </bannerLeft>
+ <bannerRight>
+ <
src>http://maven.apache.org/images/maven-small.gif</src>
+ </bannerRight>
+ <body>
+ <links>
+ <item name="Maven 2"
href="http://maven.apache.org/"/>
+ </links>
+
+ <menu ref="reports"/>
+
+ </body>
+</project>
\ No newline at end of file
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/bootstrap/ValidationTest.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/bootstrap/ValidationTest.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/bootstrap/ValidationTest.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,244 @@
+// $Id: ValidationTest.java 115 2008-10-01 15:33:10Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.bootstrap;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import javax.validation.Constraint;
+import javax.validation.ConstraintDescriptor;
+import javax.validation.ConstraintFactory;
+import javax.validation.InvalidConstraint;
+import javax.validation.MessageResolver;
+import javax.validation.Validation;
+import javax.validation.ValidationException;
+import javax.validation.ValidationProviderResolver;
+import javax.validation.Validator;
+import javax.validation.ValidatorBuilder;
+import javax.validation.ValidatorFactory;
+import javax.validation.Context;
+import javax.validation.bootstrap.SpecializedBuilderFactory;
+import javax.validation.spi.ValidationProvider;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import org.junit.Test;
+
+import org.hibernate.validation.HibernateValidatorBuilder;
+import org.hibernate.validation.constraints.NotNullConstraint;
+import org.hibernate.validation.eg.Customer;
+import org.hibernate.validation.impl.ConstraintFactoryImpl;
+import org.hibernate.validation.impl.ValidatorBuilderImpl;
+import org.hibernate.validation.impl.ValidatorFactoryImpl;
+import org.hibernate.validation.impl.HibernateValidationProvider;
+
+/**
+ * Tests the validation bootstrapping.
+ *
+ * @author Hardy Ferentschik
+ */
+public class ValidationTest {
+
+ @Test
+ public void testBootstrapAsServiceWithBuilder() {
+ HibernateValidatorBuilder builder = Validation
+ .builderType( HibernateValidatorBuilder.class )
+ .getValidatorBuilder();
+ assertDefaultBuilderAndFactory( builder );
+ }
+
+ @Test
+ public void testBootstrapAsServiceDefault() {
+ ValidatorBuilder<?> builder = Validation.getValidatorBuilder();
+ assertDefaultBuilderAndFactory( builder );
+ }
+
+ @Test
+ public void testGetCustomerValiator() {
+ ValidatorBuilder<?> builder = Validation.getValidatorBuilder();
+ assertDefaultBuilderAndFactory( builder );
+
+ ValidatorFactory factory = builder.build();
+ Validator<Customer> validator = factory.getValidator( Customer.class );
+
+ Customer customer = new Customer();
+ customer.setFirstName( "John" );
+
+ Set<InvalidConstraint<Customer>> invalidConstraints = validator.validate(
customer );
+ assertEquals( "Wrong number of constraints", 1, invalidConstraints.size() );
+
+ customer.setLastName( "Doe" );
+
+ invalidConstraints = validator.validate( customer );
+ assertEquals( "Wrong number of constraints", 0, invalidConstraints.size() );
+ }
+
+
+ @Test
+ public void testCustomMessageResolver() {
+
+ // first try with the default message resolver
+ ValidatorBuilder<?> builder = Validation.getValidatorBuilder();
+ assertDefaultBuilderAndFactory( builder );
+
+ ValidatorFactory factory = builder.build();
+ Validator<Customer> validator = factory.getValidator( Customer.class );
+
+ Customer customer = new Customer();
+ customer.setFirstName( "John" );
+
+ Set<InvalidConstraint<Customer>> invalidConstraints = validator.validate(
customer );
+ assertEquals( "Wrong number of constraints", 1, invalidConstraints.size() );
+ InvalidConstraint<Customer> constraint = invalidConstraints.iterator().next();
+ assertEquals( "Wrong message", "may not be null",
constraint.getMessage() );
+
+ //FIXME nothing guarantee that a builder can be reused
+ // now we modify the builder, get a new factory and valiator and try again
+ builder.messageResolver(
+ new MessageResolver() {
+ public String interpolate(String message, ConstraintDescriptor constraintDescriptor,
Object value) {
+ return "my custom message";
+ }
+ }
+ );
+ factory = builder.build();
+ validator = factory.getValidator( Customer.class );
+ invalidConstraints = validator.validate( customer );
+ assertEquals( "Wrong number of constraints", 1, invalidConstraints.size() );
+ constraint = invalidConstraints.iterator().next();
+ assertEquals( "Wrong message", "my custom message",
constraint.getMessage() );
+ }
+
+ @Test
+ public void testCustomConstraintFactory() {
+
+ ValidatorBuilder<?> builder = Validation.getValidatorBuilder();
+ assertDefaultBuilderAndFactory( builder );
+
+ ValidatorFactory factory = builder.build();
+ Validator<Customer> validator = factory.getValidator( Customer.class );
+
+ Customer customer = new Customer();
+ customer.setFirstName( "John" );
+
+ Set<InvalidConstraint<Customer>> invalidConstraints = validator.validate(
customer );
+ assertEquals( "Wrong number of constraints", 1, invalidConstraints.size() );
+ InvalidConstraint<Customer> constraint = invalidConstraints.iterator().next();
+ assertEquals( "Wrong message", "may not be null",
constraint.getMessage() );
+
+ //FIXME nothing guarantee that a builder can be reused
+ // now we modify the builder, get a new factory and valiator and try again
+ builder.constraintFactory(
+ new ConstraintFactory() {
+ public <T extends Constraint> T getInstance(Class<T> key) {
+ if ( key == NotNullConstraint.class ) {
+ return ( T ) new BadlyBehavedNotNullConstraint();
+ }
+ return new ConstraintFactoryImpl().getInstance( key );
+ }
+ }
+ );
+ factory = builder.build();
+ validator = factory.getValidator( Customer.class );
+ invalidConstraints = validator.validate( customer );
+ assertEquals( "Wrong number of constraints", 0, invalidConstraints.size() );
+ }
+
+ @Test
+ public void testCustomResolverAndType() {
+ ValidationProviderResolver resolver = new ValidationProviderResolver() {
+
+ public List<ValidationProvider> getValidationProviders() {
+ List<ValidationProvider> list = new ArrayList<ValidationProvider>();
+ list.add( new HibernateValidationProvider() );
+ return list;
+ }
+ };
+
+
+ HibernateValidatorBuilder builder = Validation
+ .builderType( HibernateValidatorBuilder.class )
+ .providerResolver( resolver )
+ .getValidatorBuilder();
+ assertDefaultBuilderAndFactory( builder );
+ }
+
+ @Test
+ public void testCustomResolver() {
+ ValidationProviderResolver resolver = new ValidationProviderResolver() {
+
+ public List<ValidationProvider> getValidationProviders() {
+ List<ValidationProvider> list = new ArrayList<ValidationProvider>();
+ list.add( new HibernateValidationProvider() );
+ return list;
+ }
+ };
+
+
+ ValidatorBuilder<?> builder = Validation
+ .defineBootstrapState()
+ .providerResolver( resolver )
+ .getValidatorBuilder();
+ assertDefaultBuilderAndFactory( builder );
+ }
+
+ @Test
+ public void testFailingCustomResolver() {
+ ValidationProviderResolver resolver = new ValidationProviderResolver() {
+
+ public List<ValidationProvider> getValidationProviders() {
+ return new ArrayList<ValidationProvider>();
+ }
+ };
+
+ final SpecializedBuilderFactory<HibernateValidatorBuilder>
specializedBuilderFactory =
+ Validation
+ .builderType(HibernateValidatorBuilder.class)
+ .providerResolver( resolver );
+
+ try {
+ specializedBuilderFactory.getValidatorBuilder();
+ fail();
+ }
+ catch ( ValidationException e ) {
+ assertEquals(
+ "Wrong error message",
+ "Unable to find provider: interface
org.hibernate.validation.HibernateValidatorBuilder",
+ e.getMessage()
+ );
+ }
+ }
+
+ private void assertDefaultBuilderAndFactory(ValidatorBuilder builder) {
+ assertNotNull( builder );
+ assertTrue( builder instanceof ValidatorBuilderImpl );
+
+ ValidatorFactory factory = builder.build();
+ assertNotNull( factory );
+ assertTrue( factory instanceof ValidatorFactoryImpl );
+ }
+
+ class BadlyBehavedNotNullConstraint extends NotNullConstraint {
+ @Override
+ public boolean isValid(Object object, Context context) {
+ return true;
+ }
+ }
+}
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/LengthConstraintTest.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/LengthConstraintTest.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/LengthConstraintTest.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,74 @@
+// $Id: LengthConstraintTest.java 110 2008-09-29 23:46:37Z epbernard $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.constraints;
+
+import java.lang.annotation.Annotation;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import org.junit.Test;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class LengthConstraintTest {
+ @Test
+ public void testIsValid() {
+ LengthConstraint constraint = new LengthConstraint();
+ constraint.initialize(
+ new Length() {
+
+ public int min() {
+ return 1;
+ }
+
+ public int max() {
+ return 3;
+ }
+
+ public String message() {
+ return "{validator.length}";
+ }
+
+ public String[] groups() {
+ return new String[0];
+ }
+
+ public Class<? extends Annotation> annotationType() {
+ return this.getClass();
+ }
+ }
+ );
+
+ assertTrue( constraint.isValid( null, null ) );
+ assertFalse( constraint.isValid( "", null ) );
+ assertTrue( constraint.isValid( "f", null ) );
+ assertTrue( constraint.isValid( "fo", null ) );
+ assertTrue( constraint.isValid( "foo", null ) );
+ assertFalse( constraint.isValid( "foobar", null ) );
+
+ try {
+ constraint.isValid( new Object(), null );
+ fail();
+ }
+ catch ( IllegalArgumentException e ) {
+ // success
+ }
+ }
+}
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/NotEmptyConstraintTest.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/NotEmptyConstraintTest.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/NotEmptyConstraintTest.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,48 @@
+// $Id: NotEmptyConstraintTest.java 110 2008-09-29 23:46:37Z epbernard $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.constraints;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import org.junit.Test;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class NotEmptyConstraintTest {
+
+ @Test
+ public void testIsValid() {
+ NotEmptyConstraint constraint = new NotEmptyConstraint();
+
+ assertTrue( constraint.isValid( null, null ) );
+ assertTrue( constraint.isValid( "foo", null ) );
+ assertTrue( constraint.isValid( " ", null ) );
+
+ assertFalse( constraint.isValid( "", null ) );
+
+ try {
+ constraint.isValid( new Object(), null );
+ fail();
+ }
+ catch ( IllegalArgumentException e ) {
+ // success
+ }
+ }
+}
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/NotNullConstraintTest.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/NotNullConstraintTest.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/NotNullConstraintTest.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,36 @@
+// $Id: NotNullConstraintTest.java 110 2008-09-29 23:46:37Z epbernard $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.constraints;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class NotNullConstraintTest {
+
+ @Test
+ public void testIsValid() {
+ NotNullConstraint constraint = new NotNullConstraint();
+
+ assertFalse( constraint.isValid( null, null ) );
+ assertTrue( constraint.isValid( new Object(), null ) );
+ }
+}
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/PatternConstraintTest.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/PatternConstraintTest.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/PatternConstraintTest.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,72 @@
+// $Id: PatternConstraintTest.java 110 2008-09-29 23:46:37Z epbernard $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.constraints;
+
+import java.lang.annotation.Annotation;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import org.junit.Test;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class PatternConstraintTest {
+ @Test
+ public void testIsValid() {
+ PatternConstraint constraint = new PatternConstraint();
+ constraint.initialize(
+ new Pattern() {
+
+ public String message() {
+ return "{validator.pattern}";
+ }
+
+ public String[] groups() {
+ return new String[0];
+ }
+
+ public String regex() {
+ return "foobar";
+ }
+
+ public int flags() {
+ return 0;
+ }
+
+ public Class<? extends Annotation> annotationType() {
+ return this.getClass();
+ }
+ }
+ );
+
+ assertTrue( constraint.isValid( null, null ) );
+ assertFalse( constraint.isValid( "", null ) );
+ assertFalse( constraint.isValid( "bla bla", null ) );
+ assertFalse( constraint.isValid( "This test is not foobar", null ) );
+
+ try {
+ constraint.isValid( new Object(), null );
+ fail();
+ }
+ catch ( IllegalArgumentException e ) {
+ // success
+ }
+ }
+}
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Actor.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Actor.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Actor.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,89 @@
+// $Id: Actor.java 105 2008-09-29 12:37:32Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.eg;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.validation.Valid;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class Actor implements Person {
+
+ private String firstName;
+ private String middleName;
+ private String lastName;
+
+ @Valid
+ private List<Actor> playedWith = new ArrayList<Actor>();
+
+ public Actor() {
+
+ }
+
+ public Actor(String firstName, String lastName) {
+ this.firstName = firstName;
+ this.lastName = lastName;
+ }
+
+ public List<Actor> getPlayedWith() {
+ return playedWith;
+ }
+
+ public void setPlayedWith(List<Actor> playedWith) {
+ this.playedWith = playedWith;
+ }
+
+ public void addPlayedWith(Actor playedWith) {
+ this.playedWith.add( playedWith );
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getMiddleName() {
+ return middleName;
+ }
+
+ public void setMiddleName(String middleName) {
+ this.middleName = middleName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ @Override
+ public String toString() {
+ return "Actor{" +
+ "firstName='" + firstName + '\'' +
+ ", middleName='" + middleName + '\'' +
+ ", lastName='" + lastName + '\'' +
+ '}';
+ }
+}
\ No newline at end of file
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Address.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Address.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Address.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,73 @@
+// $Id: Address.java 105 2008-09-29 12:37:32Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.eg;
+
+import org.hibernate.validation.constraints.Length;
+import org.hibernate.validation.constraints.NotNull;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class Address {
+ @NotNull
+ @Length(max = 30)
+ private String addressline1;
+
+ @NotNull
+ @Length(max = 30)
+ private String addressline2;
+
+ private String zipCode;
+
+ private String city;
+
+ public String getAddressline1() {
+ return addressline1;
+ }
+
+ public void setAddressline1(String addressline1) {
+ this.addressline1 = addressline1;
+ }
+
+ public String getAddressline2() {
+ return addressline2;
+ }
+
+ public void setAddressline2(String addressline2) {
+ this.addressline2 = addressline2;
+ }
+
+ public String getZipCode() {
+ return zipCode;
+ }
+
+ public void setZipCode(String zipCode) {
+ this.zipCode = zipCode;
+ }
+
+ @Length(max = 30)
+ @NotNull
+ public String getCity() {
+ return city;
+ }
+
+ public void setCity(String city) {
+ this.city = city;
+ }
+}
+
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Animal.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Animal.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Animal.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,52 @@
+// $Id: Animal.java 105 2008-09-29 12:37:32Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.eg;
+
+import org.hibernate.validation.constraints.NotEmpty;
+import org.hibernate.validation.constraints.NotNull;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class Animal {
+ public enum Domain {
+ PROKARYOTA, EUKARYOTA
+ }
+
+ @NotEmpty(groups = { "first", "second" })
+ private String name;
+
+ @NotNull(groups = "first")
+ private Domain domain;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Domain getDomain() {
+ return domain;
+ }
+
+ public void setDomain(Domain domain) {
+ this.domain = domain;
+ }
+}
\ No newline at end of file
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Author.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Author.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Author.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,62 @@
+// $Id: Author.java 105 2008-09-29 12:37:32Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.eg;
+
+import org.hibernate.validation.constraints.Length;
+import org.hibernate.validation.constraints.NotEmpty;
+import org.hibernate.validation.constraints.NotNull;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class Author {
+
+ @NotEmpty(groups = "last")
+ private String firstName;
+
+ @NotNull(groups = "first")
+ @NotEmpty(groups = "first")
+ private String lastName;
+
+ @Length(max = 20, groups = "last")
+ private String company;
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ public String getCompany() {
+ return company;
+ }
+
+ public void setCompany(String company) {
+ this.company = company;
+ }
+}
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Book.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Book.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Book.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,66 @@
+// $Id: Book.java 105 2008-09-29 12:37:32Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.eg;
+
+import javax.validation.GroupSequence;
+import javax.validation.Valid;
+
+import org.hibernate.validation.constraints.Length;
+import org.hibernate.validation.constraints.NotEmpty;
+import org.hibernate.validation.constraints.NotNull;
+
+/**
+ * @author Hardy Ferentschik
+ */
+@GroupSequence(name = "default", sequence = { "first",
"second", "last" })
+public class Book {
+ @NotNull(groups = "first")
+ @NotEmpty(groups = "first")
+ private String title;
+
+ @Length(max = 30, groups = "second")
+ private String subtitle;
+
+ @Valid
+ @NotNull(groups = "first")
+ private Author author;
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getSubtitle() {
+ return subtitle;
+ }
+
+ public void setSubtitle(String subtitle) {
+ this.subtitle = subtitle;
+ }
+
+ public Author getAuthor() {
+ return author;
+ }
+
+ public void setAuthor(Author author) {
+ this.author = author;
+ }
+}
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Boy.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Boy.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Boy.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,64 @@
+// $Id: Boy.java 105 2008-09-29 12:37:32Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.eg;
+
+import org.hibernate.validation.constraints.NotNull;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class Boy implements Person {
+
+ private String firstName;
+ private String middleName;
+ private String lastName;
+ private Integer age;
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getMiddleName() {
+ return middleName;
+ }
+
+ public void setMiddleName(String middleName) {
+ this.middleName = middleName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ public void setAge(Integer age) {
+ this.age = age;
+ }
+
+ @NotNull
+ public Integer age() {
+ return age;
+ }
+}
\ No newline at end of file
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Customer.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Customer.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Customer.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,67 @@
+// $Id: Customer.java 105 2008-09-29 12:37:32Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.eg;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.validation.Valid;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class Customer implements Person {
+
+ private String firstName;
+ private String middleName;
+ private String lastName;
+
+ @Valid
+ private List<Order> orderList = new ArrayList<Order>();
+
+ public void addOrder(Order order) {
+ orderList.add( order );
+ }
+
+ public List<Order> getOrderList() {
+ return orderList;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getMiddleName() {
+ return middleName;
+ }
+
+ public void setMiddleName(String middleName) {
+ this.middleName = middleName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+}
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Dictonary.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Dictonary.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Dictonary.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,57 @@
+// $Id: Dictonary.java 105 2008-09-29 12:37:32Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.eg;
+
+import javax.validation.GroupSequence;
+import javax.validation.GroupSequences;
+
+import org.hibernate.validation.constraints.NotEmpty;
+import org.hibernate.validation.constraints.NotNull;
+
+/**
+ * @author Hardy Ferentschik
+ */
+@GroupSequences({
+ @GroupSequence(name = "default-alias", sequence = { "default" }),
+ @GroupSequence(name = "all", sequence = { "default",
"translate" })
+})
+public class Dictonary extends Book {
+ @NotNull(groups = "translate")
+ @NotEmpty(groups = "translate")
+ private String translatesTo;
+
+ @NotNull(groups = "translate")
+ @NotEmpty(groups = "translate")
+ private String translatesFrom;
+
+ public String getTranslatesTo() {
+ return translatesTo;
+ }
+
+ public void setTranslatesTo(String translatesTo) {
+ this.translatesTo = translatesTo;
+ }
+
+ public String getTranslatesFrom() {
+ return translatesFrom;
+ }
+
+ public void setTranslatesFrom(String translatesFrom) {
+ this.translatesFrom = translatesFrom;
+ }
+}
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Engine.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Engine.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Engine.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,41 @@
+// $Id: Engine.java 105 2008-09-29 12:37:32Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.eg;
+
+import org.hibernate.validation.constraints.Pattern;
+import org.hibernate.validation.constraints.Patterns;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class Engine {
+ @Patterns({
+ @Pattern(regex = "^[A-Z0-9-]+$",
+ message = "must contain alphabetical characters only"),
+ @Pattern(regex = "^....-....-....$", message = "must match
....-....-....")
+ })
+ private String serialNumber;
+
+ public String getSerialNumber() {
+ return serialNumber;
+ }
+
+ public void setSerialNumber(String serialNumber) {
+ this.serialNumber = serialNumber;
+ }
+}
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/EnglishDictonary.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/EnglishDictonary.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/EnglishDictonary.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,30 @@
+// $Id: EnglishDictonary.java 105 2008-09-29 12:37:32Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.eg;
+
+import javax.validation.GroupSequence;
+import javax.validation.GroupSequences;
+
+/**
+ * @author Hardy Ferentschik
+ */
+@GroupSequences({
+ @GroupSequence(name = "default", sequence = { "first" }) //
illegal - default is already defined in Book
+})
+public class EnglishDictonary extends Dictonary {
+}
\ No newline at end of file
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Female.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Female.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Female.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,51 @@
+// $Id: Female.java 105 2008-09-29 12:37:32Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.eg;
+
+import org.hibernate.validation.eg.constraint.NoGroups;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class Female implements Person {
+
+ // @NoGroups is an invalid annotation (missing group paramter)
+ @NoGroups
+ private String firstName;
+ private String lastName;
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ public String getMiddleName() {
+ return null;
+ }
+}
\ No newline at end of file
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Male.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Male.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Male.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,50 @@
+// $Id: Male.java 105 2008-09-29 12:37:32Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.eg;
+
+import org.hibernate.validation.eg.constraint.NoMessage;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class Male implements Person {
+ // @NoMessage is an invalid annotation (no message paramter)
+ @NoMessage
+ private String firstName;
+ private String lastName;
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ public String getMiddleName() {
+ return null;
+ }
+}
\ No newline at end of file
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Order.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Order.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Order.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,36 @@
+// $Id: Order.java 105 2008-09-29 12:37:32Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.eg;
+
+import org.hibernate.validation.constraints.NotNull;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class Order {
+ @NotNull
+ Integer orderNumber;
+
+ public Integer getOrderNumber() {
+ return orderNumber;
+ }
+
+ public void setOrderNumber(Integer orderNumber) {
+ this.orderNumber = orderNumber;
+ }
+}
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Person.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Person.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Person.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,36 @@
+// $Id: Person.java 105 2008-09-29 12:37:32Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.eg;
+
+import org.hibernate.validation.constraints.NotEmpty;
+import org.hibernate.validation.constraints.NotNull;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public interface Person {
+ @NotNull
+ @NotEmpty
+ String getFirstName();
+
+ String getMiddleName();
+
+ @NotNull
+ @NotEmpty
+ String getLastName();
+}
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Unconstraint.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Unconstraint.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Unconstraint.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,26 @@
+// : Person.java 69 2008-09-08 11:05:07Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.eg;
+
+/**
+ * Empty un-constraint test class.
+ *
+ * @author Hardy Ferentschik
+ */
+public class Unconstraint {
+}
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/constraint/NoGroups.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/constraint/NoGroups.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/constraint/NoGroups.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,37 @@
+// $Id: NoGroups.java 105 2008-09-29 12:37:32Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.eg.constraint;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+import javax.validation.ConstraintValidator;
+
+/**
+ * @author Hardy Ferentschik
+ */
+@Documented
+(a)ConstraintValidator(NoGroupsConstraint.class)
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface NoGroups {
+ public abstract String message() default "default message";
+}
\ No newline at end of file
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/constraint/NoGroupsConstraint.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/constraint/NoGroupsConstraint.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/constraint/NoGroupsConstraint.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,34 @@
+// $Id: NoGroupsConstraint.java 110 2008-09-29 23:46:37Z epbernard $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.eg.constraint;
+
+import javax.validation.Constraint;
+import javax.validation.Context;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class NoGroupsConstraint implements Constraint<NoGroups> {
+
+ public void initialize(NoGroups parameters) {
+ }
+
+ public boolean isValid(Object object, Context context) {
+ return false;
+ }
+}
\ No newline at end of file
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/constraint/NoMessage.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/constraint/NoMessage.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/constraint/NoMessage.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,37 @@
+// $Id: NoMessage.java 105 2008-09-29 12:37:32Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.eg.constraint;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+import javax.validation.ConstraintValidator;
+
+/**
+ * @author Hardy Ferentschik
+ */
+@Documented
+(a)ConstraintValidator(NoMessageConstraint.class)
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface NoMessage {
+ public abstract String[] groups() default { };
+}
\ No newline at end of file
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/constraint/NoMessageConstraint.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/constraint/NoMessageConstraint.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/constraint/NoMessageConstraint.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,34 @@
+// $Id: NoMessageConstraint.java 110 2008-09-29 23:46:37Z epbernard $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.eg.constraint;
+
+import javax.validation.Constraint;
+import javax.validation.Context;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class NoMessageConstraint implements Constraint<NoMessage> {
+
+ public void initialize(NoMessage parameters) {
+ }
+
+ public boolean isValid(Object object, Context context) {
+ return false;
+ }
+}
\ No newline at end of file
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/ValidatorImplTest.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/ValidatorImplTest.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/ValidatorImplTest.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,428 @@
+// $Id: ValidatorImplTest.java 105 2008-09-29 12:37:32Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.engine;
+
+import java.util.HashSet;
+import java.util.Set;
+import javax.validation.InvalidConstraint;
+import javax.validation.ValidationException;
+import javax.validation.Validator;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import org.junit.Test;
+
+import org.hibernate.validation.eg.Actor;
+import org.hibernate.validation.eg.Address;
+import org.hibernate.validation.eg.Animal;
+import org.hibernate.validation.eg.Author;
+import org.hibernate.validation.eg.Book;
+import org.hibernate.validation.eg.Boy;
+import org.hibernate.validation.eg.Customer;
+import org.hibernate.validation.eg.Dictonary;
+import org.hibernate.validation.eg.Engine;
+import org.hibernate.validation.eg.EnglishDictonary;
+import org.hibernate.validation.eg.Female;
+import org.hibernate.validation.eg.Male;
+import org.hibernate.validation.eg.Order;
+import org.hibernate.validation.eg.Unconstraint;
+
+/**
+ * Tests for the implementation of <code>Validator</code>.
+ *
+ * @author Hardy Ferentschik
+ */
+public class ValidatorImplTest {
+
+ /**
+ * JSR 303: Constraint definition properties - message (2.1.1.1)
+ */
+ @Test
+ public void testConstraintWithNoMessage() {
+ try {
+ new ValidatorImpl<Male>( Male.class );
+ fail();
+ }
+ catch ( ValidationException e ) {
+ assertEquals(
+ "Wrong error message", "Constraint annotation has to define message
element.", e.getMessage()
+ );
+ }
+ }
+
+ /**
+ * JSR 303: Constraint definition properties - groups (2.1.1.2)
+ */
+ @Test
+ public void testConstraintWithNoGroups() {
+ try {
+ new ValidatorImpl<Female>( Female.class );
+ fail();
+ }
+ catch ( ValidationException e ) {
+ assertEquals(
+ "Wrong error message", "Constraint annotation has to define groups
element.", e.getMessage()
+ );
+ }
+ }
+
+ /**
+ * JSR 303: Requirements on classes to be validates (3.1)
+ */
+ @Test
+ public void testWrongMethodName() {
+ try {
+ new ValidatorImpl<Boy>( Boy.class );
+ fail();
+ }
+ catch ( ValidationException e ) {
+ assertEquals(
+ "Wrong error message",
+ "Annoated methods must follow the JavaBeans naming convention. age() does
not.",
+ e.getMessage()
+ );
+ }
+ }
+
+
+ @Test( expected = IllegalArgumentException.class)
+ public void testNullParamterToValidatorImplConstructor() {
+ new ValidatorImpl<Unconstraint>( null);
+ }
+
+ @Test
+ public void testUnconstraintClass() {
+ Validator<Unconstraint> validator = new ValidatorImpl<Unconstraint>(
Unconstraint.class );
+ assertTrue( "There should be no constraints", !validator.hasConstraints() );
+ }
+
+ @Test
+ public void testHasConstraints() {
+ Validator<Customer> validatorCustomer = new ValidatorImpl<Customer>(
Customer.class );
+ assertTrue( "There should be constraints", validatorCustomer.hasConstraints()
);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testValidateWithNull() {
+ Validator<Customer> validatorCustomer = new ValidatorImpl<Customer>(
Customer.class );
+ validatorCustomer.validate( null );
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testValidateWithNullProperty() {
+ Validator<Customer> validatorCustomer = new ValidatorImpl<Customer>(
Customer.class );
+ validatorCustomer.validate( null, "firstName" );
+ }
+
+ @Test
+ public void testGroups() {
+ Validator<Book> validator = new ValidatorImpl<Book>( Book.class );
+
+ Author author = new Author();
+ author.setLastName( "" );
+ author.setFirstName( "" );
+ Book book = new Book();
+ book.setTitle( "" );
+ book.setAuthor( author );
+
+ Set<InvalidConstraint<Book>> invalidConstraints = validator.validate( book,
"first", "second", "last" );
+ assertEquals( "Wrong number of constraints", 3, invalidConstraints.size() );
+
+ author.setFirstName( "Gavin" );
+ author.setLastName( "King" );
+
+ invalidConstraints = validator.validate( book, "first", "second",
"last" );
+ InvalidConstraint constraint = invalidConstraints.iterator().next();
+ assertEquals( "Wrong number of constraints", 1, invalidConstraints.size() );
+ assertEquals( "Wrong message", "may not be empty",
constraint.getMessage() );
+ assertEquals( "Wrong bean class", Book.class, constraint.getBeanClass() );
+ assertEquals( "Wrong root entity", book, constraint.getRootBean() );
+ assertEquals( "Wrong value", book.getTitle(), constraint.getValue() );
+ assertEquals( "Wrong propertyName", "title",
constraint.getPropertyPath() );
+
+ book.setTitle( "Hibernate Persistence with JPA" );
+ book.setSubtitle( "Revised Edition of Hibernate in Action" );
+
+ invalidConstraints = validator.validate( book, "first", "second",
"last" );
+ constraint = invalidConstraints.iterator().next();
+ assertEquals( "Wrong number of constraints", 1, invalidConstraints.size() );
+ assertEquals( "Wrong message", "length must be between 0 and 30",
constraint.getMessage() );
+ assertEquals( "Wrong bean class", Book.class, constraint.getBeanClass() );
+ assertEquals( "Wrong root entity", book, constraint.getRootBean() );
+ assertEquals( "Wrong value", book.getSubtitle(), constraint.getValue() );
+ assertEquals( "Wrong propertyName", "subtitle",
constraint.getPropertyPath() );
+
+ book.setSubtitle( "Revised Edition" );
+ author.setCompany( "JBoss a divison of RedHat" );
+
+ invalidConstraints = validator.validate( book, "first", "second",
"last" );
+ constraint = invalidConstraints.iterator().next();
+ assertEquals( "Wrong number of constraints", 1, invalidConstraints.size() );
+ assertEquals( "Wrong message", "length must be between 0 and 20",
constraint.getMessage() );
+ assertEquals( "Wrong bean class", Author.class, constraint.getBeanClass() );
+ assertEquals( "Wrong root entity", book, constraint.getRootBean() );
+ assertEquals( "Wrong value", author.getCompany(), constraint.getValue() );
+ assertEquals( "Wrong propertyName", "author.company",
constraint.getPropertyPath() );
+
+ author.setCompany( "JBoss" );
+
+ invalidConstraints = validator.validate( book, "first", "second",
"last" );
+ assertEquals( "Wrong number of constraints", 0, invalidConstraints.size() );
+ }
+
+ @Test
+ public void testDefaultGroupSequence() {
+ Validator<Book> validator = new ValidatorImpl<Book>( Book.class );
+
+ Author author = new Author();
+ author.setLastName( "" );
+ author.setFirstName( "" );
+ Book book = new Book();
+ book.setAuthor( author );
+
+ Set<InvalidConstraint<Book>> invalidConstraints = validator.validate( book,
"default" );
+ assertEquals( "Wrong number of constraints", 2, invalidConstraints.size() );
+
+ author.setFirstName( "Gavin" );
+ author.setLastName( "King" );
+
+ invalidConstraints = validator.validate( book, "default" );
+ InvalidConstraint constraint = invalidConstraints.iterator().next();
+ assertEquals( "Wrong number of constraints", 1, invalidConstraints.size() );
+ assertEquals( "Wrong message", "may not be null",
constraint.getMessage() );
+ assertEquals( "Wrong bean class", Book.class, constraint.getBeanClass() );
+ assertEquals( "Wrong root entity", book, constraint.getRootBean() );
+ assertEquals( "Wrong value", book.getTitle(), constraint.getValue() );
+ assertEquals( "Wrong propertyName", "title",
constraint.getPropertyPath() );
+
+ book.setTitle( "Hibernate Persistence with JPA" );
+ book.setSubtitle( "Revised Edition of Hibernate in Action" );
+
+ invalidConstraints = validator.validate( book, "default" );
+ assertEquals( "Wrong number of constraints", 1, invalidConstraints.size() );
+
+ book.setSubtitle( "Revised Edition" );
+ author.setCompany( "JBoss a divison of RedHat" );
+
+ invalidConstraints = validator.validate( book, "default" );
+ assertEquals( "Wrong number of constraints", 1, invalidConstraints.size() );
+
+ author.setCompany( "JBoss" );
+
+ invalidConstraints = validator.validate( book, "default" );
+ assertEquals( "Wrong number of constraints", 0, invalidConstraints.size() );
+ }
+
+ @Test
+ public void testBasicValidation() {
+ Validator<Customer> validator = new ValidatorImpl<Customer>( Customer.class
);
+
+ Customer customer = new Customer();
+ customer.setFirstName( "John" );
+
+ Set<InvalidConstraint<Customer>> invalidConstraints = validator.validate(
customer );
+ assertEquals( "Wrong number of constraints", 1, invalidConstraints.size() );
+
+ customer.setLastName( "Doe" );
+
+ invalidConstraints = validator.validate( customer );
+ assertEquals( "Wrong number of constraints", 0, invalidConstraints.size() );
+ }
+
+ @Test
+ public void testGroupSequences() {
+ Validator<Dictonary> validator = new ValidatorImpl<Dictonary>(
Dictonary.class );
+
+ Dictonary dictonary = new Dictonary();
+ dictonary.setTitle( "English - German" );
+ Author author = new Author();
+ author.setLastName( "-" );
+ author.setFirstName( "-" );
+ author.setCompany( "Langenscheidt Publ." );
+ dictonary.setAuthor( author );
+
+ Set<InvalidConstraint<Dictonary>> invalidConstraints = validator.validate(
dictonary, "default-alias" );
+ assertEquals( "Wrong number of constraints", 0, invalidConstraints.size() );
+ }
+
+ @Test
+ public void testValidationFailureInMultipleGroups() {
+ Validator<Animal> validator = new ValidatorImpl<Animal>( Animal.class );
+ Animal elepfant = new Animal();
+ elepfant.setName( "" );
+ elepfant.setDomain( Animal.Domain.EUKARYOTA );
+
+ Set<InvalidConstraint<Animal>> invalidConstraints = validator.validate(
elepfant, "first", "second" );
+ assertEquals(
+ "The should be two invalid constraints since the same propertyName gets
validated in both groups",
+ 1,
+ invalidConstraints.size()
+ );
+
+ InvalidConstraint constraint = invalidConstraints.iterator().next();
+ Set<String> expected = new HashSet<String>();
+ expected.add( "first" );
+ expected.add( "second" );
+ assertEquals(
+ "The constraint should be invalid for both groups",
+ expected,
+ constraint.getGroups()
+ );
+ }
+
+ @Test(expected = ValidationException.class)
+ public void testInvalidSequenceName() {
+ new ValidatorImpl<EnglishDictonary>( EnglishDictonary.class );
+ }
+
+ @Test
+ public void testValidationMethod() {
+ Validator<Address> validator = new ValidatorImpl<Address>( Address.class
);
+
+ Address address = new Address();
+ address.setAddressline1( null );
+ address.setAddressline2( null );
+ address.setCity(
"Llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch" ); //town in
North Wales
+
+ Set<InvalidConstraint<Address>> invalidConstraints = validator.validate(
address );
+ assertEquals(
+ "we should have been 2 not null violation for addresslines and one lenth
violation for city",
+ 3,
+ invalidConstraints.size()
+ );
+
+ invalidConstraints = validator.validateProperty( address, "city" );
+ assertEquals(
+ "only city should be validated",
+ 1,
+ invalidConstraints.size()
+ );
+
+ invalidConstraints = validator.validateProperty( address, "city" );
+ assertEquals(
+ "only city should be validated",
+ 1,
+ invalidConstraints.size()
+ );
+
+ invalidConstraints = validator.validateValue( "city", "Paris" );
+ assertEquals(
+ "Paris should be a valid city name.",
+ 0,
+ invalidConstraints.size()
+ );
+ }
+
+ @Test
+ public void testValidateList() {
+ Validator<Customer> validator = new ValidatorImpl<Customer>( Customer.class
);
+
+ Customer customer = new Customer();
+ customer.setFirstName( "John" );
+ customer.setLastName( "Doe" );
+
+ Set<InvalidConstraint<Customer>> invalidConstraints = validator.validate(
customer );
+ assertEquals( "Wrong number of constraints", 0, invalidConstraints.size() );
+
+ Order order1 = new Order();
+ customer.addOrder( order1 );
+
+ invalidConstraints = validator.validate( customer );
+ InvalidConstraint constraint = invalidConstraints.iterator().next();
+ assertEquals( "Wrong number of constraints", 1, invalidConstraints.size() );
+ assertEquals( "Wrong message", "may not be null",
constraint.getMessage() );
+ assertEquals( "Wrong bean class", Order.class, constraint.getBeanClass() );
+ assertEquals( "Wrong root entity", customer, constraint.getRootBean() );
+ assertEquals( "Wrong value", order1.getOrderNumber(), constraint.getValue()
);
+ assertEquals( "Wrong propertyName", "orderList[0].orderNumber",
constraint.getPropertyPath() );
+
+ }
+
+ /**
+ * JSR 303: Multi-valued constraints (2.2)
+ */
+ @Test
+ public void testMultiValueConstraint() {
+ Validator<Engine> validator = new ValidatorImpl<Engine>( Engine.class );
+
+ Engine engine = new Engine();
+ engine.setSerialNumber( "mail(a)foobar.com" );
+ Set<InvalidConstraint<Engine>> invalidConstraints = validator.validate(
engine );
+ assertEquals( "Wrong number of constraints", 2, invalidConstraints.size() );
+
+ engine.setSerialNumber( "ABCDEFGH1234" );
+ invalidConstraints = validator.validate( engine );
+ assertEquals( "Wrong number of constraints", 1, invalidConstraints.size() );
+
+ engine.setSerialNumber( "ABCD-EFGH-1234" );
+ invalidConstraints = validator.validate( engine );
+ assertEquals( "Wrong number of constraints", 0, invalidConstraints.size() );
+ }
+
+
+ /**
+ * JSR 303: Object graph validation (3.5.1)
+ */
+ @Test
+ public void testGraphValidation() {
+ Actor clint = new Actor( "Clint", "Eastwood" );
+ Actor morgan = new Actor( "Morgan", "" );
+ Actor charlie = new Actor( "Charlie", "Sheen" );
+
+ clint.addPlayedWith( charlie );
+ charlie.addPlayedWith( clint );
+ charlie.addPlayedWith( morgan );
+ morgan.addPlayedWith( charlie );
+ morgan.addPlayedWith( clint );
+ clint.addPlayedWith( morgan );
+
+ Validator<Actor> validator = new ValidatorImpl<Actor>( Actor.class );
+ Set<InvalidConstraint<Actor>> invalidConstraints = validator.validate(
clint );
+ InvalidConstraint constraint = invalidConstraints.iterator().next();
+ assertEquals( "Wrong number of constraints", 1, invalidConstraints.size() );
+ assertEquals( "Wrong message", "may not be empty",
constraint.getMessage() );
+ assertEquals( "Wrong bean class", Actor.class, constraint.getBeanClass() );
+ assertEquals( "Wrong root entity", clint, constraint.getRootBean() );
+ assertEquals( "Wrong value", morgan.getLastName(), constraint.getValue() );
+ assertEquals( "Wrong propertyName",
"playedWith[0].playedWith[1].lastName", constraint.getPropertyPath() );
+ }
+
+ @Test
+ public void testValidateValue() {
+ Validator<Customer> validator = new ValidatorImpl<Customer>( Customer.class
);
+
+ Order order = new Order();
+
+ Set<InvalidConstraint<Customer>> invalidConstraints =
validator.validateValue(
+ "orderList[0].orderNumber", null
+ );
+ assertEquals( "Wrong number of constraints", 1, invalidConstraints.size() );
+
+ InvalidConstraint constraint = invalidConstraints.iterator().next();
+ assertEquals( "Wrong number of constraints", 1, invalidConstraints.size() );
+ assertEquals( "Wrong message", "may not be null",
constraint.getMessage() );
+ assertEquals( "Wrong bean class", null, constraint.getBeanClass() );
+ assertEquals( "Wrong root entity", null, constraint.getRootBean() );
+ assertEquals( "Wrong value", order.getOrderNumber(), constraint.getValue()
);
+ assertEquals( "Wrong propertyName", "orderList[0].orderNumber",
constraint.getPropertyPath() );
+
+ invalidConstraints = validator.validateValue( "orderList[0].orderNumber",
"1234" );
+ assertEquals( "Wrong number of constraints", 0, invalidConstraints.size() );
+ }
+}
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/impl/ResourceBundleMessageResolverTest.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/impl/ResourceBundleMessageResolverTest.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/impl/ResourceBundleMessageResolverTest.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,186 @@
+// $Id: ResourceBundleMessageResolverTest.java 105 2008-09-29 12:37:32Z hardy.ferentschik
$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.impl;
+
+import java.lang.annotation.Annotation;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.ResourceBundle;
+
+import static org.junit.Assert.assertEquals;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+
+import org.hibernate.validation.constraints.Length;
+import org.hibernate.validation.constraints.NotNull;
+import org.hibernate.validation.constraints.NotNullConstraint;
+import org.hibernate.validation.util.LoggerFactory;
+
+/**
+ * Tests for message resolution.
+ *
+ * @author Hardy Ferentschik
+ */
+public class ResourceBundleMessageResolverTest {
+ private static final Logger log = LoggerFactory.make();
+
+ private ResourceBundleMessageResolver resolver;
+ private NotNull notNull;
+ private Length length;
+
+ @Before
+ public void setUp() {
+ resolver = new ResourceBundleMessageResolver( new TestResources() );
+ notNull = new NotNull() {
+ public String message() {
+ return "{validator.notNull}";
+ }
+
+ public String[] groups() {
+ return new String[] { };
+ }
+
+ public Class<? extends Annotation> annotationType() {
+ return this.getClass();
+ }
+ };
+
+ length = new Length() {
+ public int min() {
+ return 0;
+ }
+
+ public int max() {
+ return Integer.MAX_VALUE;
+ }
+
+ public String message() {
+ return "{validator.length}";
+ }
+
+ public String[] groups() {
+ return new String[] { };
+ }
+
+ public Class<? extends Annotation> annotationType() {
+ return this.getClass();
+ }
+ };
+ }
+
+ @Test
+ public void testSuccessfulInterpolation() {
+ ConstraintDescriptorImpl desciptor = new ConstraintDescriptorImpl(
+ notNull, new String[] { }, new NotNullConstraint()
+ );
+
+ String expected = "replacement worked";
+ String actual = resolver.interpolate( "{foo}", desciptor, null );
+ assertEquals( "Wrong substitution", expected, actual );
+
+ expected = "replacement worked replacement worked";
+ actual = resolver.interpolate( "{foo} {foo}", desciptor, null );
+ assertEquals( "Wrong substitution", expected, actual );
+
+ expected = "This replacement worked just fine";
+ actual = resolver.interpolate( "This {foo} just fine", desciptor, null );
+ assertEquals( "Wrong substitution", expected, actual );
+
+ expected = "{} { replacement worked }";
+ actual = resolver.interpolate( "{} { {foo} }", desciptor, null );
+ assertEquals( "Wrong substitution", expected, actual );
+ }
+
+ @Test
+ public void testUnSuccessfulInterpolation() {
+ ConstraintDescriptorImpl desciptor = new ConstraintDescriptorImpl(
+ notNull, new String[] { }, new NotNullConstraint()
+ );
+ String expected = "foo"; // missing {}
+ String actual = resolver.interpolate( "foo", desciptor, null );
+ assertEquals( "Wrong substitution", expected, actual );
+
+ expected = "#{foo {}";
+ actual = resolver.interpolate( "#{foo {}", desciptor, null );
+ assertEquals( "Wrong substitution", expected, actual );
+ }
+
+ @Test
+ public void testUnkownTokenInterpolation() {
+ ConstraintDescriptorImpl desciptor = new ConstraintDescriptorImpl(
+ notNull, new String[] { }, new NotNullConstraint()
+ );
+ String expected = "{bar}"; // unkown token {}
+ String actual = resolver.interpolate( "{bar}", desciptor, null );
+ assertEquals( "Wrong substitution", expected, actual );
+ }
+
+ @Test
+ public void testDefaultInterpolation() {
+ ConstraintDescriptorImpl desciptor = new ConstraintDescriptorImpl(
+ notNull, new String[] { }, new NotNullConstraint()
+ );
+ String expected = "may not be null";
+ String actual = resolver.interpolate( notNull.message(), desciptor, null );
+ assertEquals( "Wrong substitution", expected, actual );
+
+ desciptor = new ConstraintDescriptorImpl( length, new String[] { }, new
NotNullConstraint() );
+ expected = "length must be between 0 and 2147483647"; // unkown token {}
+ actual = resolver.interpolate( length.message(), desciptor, null );
+ assertEquals( "Wrong substitution", expected, actual );
+ }
+
+
+ class TestResources extends ResourceBundle implements Enumeration<String> {
+ private Map<String, String> testResources;
+ Iterator<String> iter;
+
+ public TestResources() {
+ testResources = new HashMap<String, String>();
+ // add some test messages
+ testResources.put( "foo", "replacement worked" );
+
+ iter = testResources.keySet().iterator();
+ }
+
+ public Object handleGetObject(String key) {
+ return testResources.get( key );
+ }
+
+ public Enumeration<String> getKeys() {
+ return this;
+ }
+
+ public boolean hasMoreElements() {
+ return iter.hasNext();
+ }
+
+ public String nextElement() {
+ if ( hasMoreElements() ) {
+ return iter.next();
+ }
+ else {
+ throw new NoSuchElementException();
+ }
+ }
+ }
+}
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/IdentitySetTest.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/IdentitySetTest.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/IdentitySetTest.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,76 @@
+// $Id: IdentitySetTest.java 105 2008-09-29 12:37:32Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.util;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class IdentitySetTest {
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testAddIdenticalInstance() {
+ Set identitySet = new IdentitySet();
+ Set hashSet = new HashSet();
+ assertTrue( identitySet.size() == 0 );
+ assertTrue( hashSet.size() == 0 );
+
+ Object o1 = new Object() {
+ int counter = 0;
+
+ public int hashCode() {
+ return counter++;
+ }
+
+ public boolean equals() {
+ return false;
+ }
+ };
+ identitySet.add( o1 );
+ hashSet.add( o1 );
+ assertTrue( identitySet.size() == 1 );
+ assertTrue( hashSet.size() == 1 );
+
+ identitySet.add( o1 );
+ hashSet.add( o1 );
+ assertTrue( identitySet.size() == 1 );
+ assertTrue( hashSet.size() == 2 );
+
+ Object o2 = new Object() {
+ int counter = 0;
+
+ public int hashCode() {
+ return counter++;
+ }
+
+ public boolean equals() {
+ return false;
+ }
+ };
+ identitySet.add( o2 );
+ hashSet.add( o2 );
+ assertTrue( identitySet.size() == 2 );
+ assertTrue( hashSet.size() == 3 );
+ }
+}
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/PropertyIteratorTest.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/PropertyIteratorTest.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/PropertyIteratorTest.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,89 @@
+// $Id: PropertyIteratorTest.java 112 2008-09-30 08:08:50Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class PropertyIteratorTest {
+
+ @Test
+ public void testSplit() {
+ String property = "order[3].deliveryAddress.addressline[1]";
+ PropertyIterator propIter = new PropertyIterator( property );
+
+ assertTrue( propIter.hasNext() );
+
+ propIter.split();
+ assertTrue( propIter.hasNext() );
+ assertEquals( "order", propIter.getHead() );
+ assertTrue( propIter.isIndexed() );
+ assertEquals( "3", propIter.getIndex() );
+ assertEquals( "deliveryAddress.addressline[1]", propIter.getTail() );
+ assertEquals( property, propIter.getOriginalProperty() );
+
+ propIter.split();
+ assertTrue( propIter.hasNext() );
+ assertEquals( "deliveryAddress", propIter.getHead() );
+ assertFalse( propIter.isIndexed() );
+ assertEquals( null, propIter.getIndex() );
+ assertEquals( "addressline[1]", propIter.getTail() );
+ assertEquals( property, propIter.getOriginalProperty() );
+
+ propIter.split();
+ assertFalse( propIter.hasNext() );
+ assertEquals( "addressline", propIter.getHead() );
+ assertTrue( propIter.isIndexed() );
+ assertEquals( "1", propIter.getIndex() );
+ assertEquals( null, propIter.getTail() );
+ assertEquals( property, propIter.getOriginalProperty() );
+ }
+
+ @Test
+ public void testNull() {
+ PropertyIterator propIter = new PropertyIterator( null );
+ assertFalse( propIter.hasNext() );
+
+ propIter.split();
+ assertFalse( propIter.hasNext() );
+ assertEquals( null, propIter.getHead() );
+ assertFalse( propIter.isIndexed() );
+ assertEquals( null, propIter.getIndex() );
+ assertEquals( null, propIter.getTail() );
+ assertEquals( null, propIter.getOriginalProperty() );
+ }
+
+ @Test
+ public void testEmptyString() {
+ PropertyIterator propIter = new PropertyIterator( "" );
+ assertFalse( propIter.hasNext() );
+
+ propIter.split();
+ assertFalse( propIter.hasNext() );
+ assertEquals( null, propIter.getHead() );
+ assertFalse( propIter.isIndexed() );
+ assertEquals( null, propIter.getIndex() );
+ assertEquals( null, propIter.getTail() );
+ assertEquals( "", propIter.getOriginalProperty() );
+ }
+}
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/ReflectionHelperTest.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/ReflectionHelperTest.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/ReflectionHelperTest.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,72 @@
+// $Id: ReflectionHelperTest.java 111 2008-09-30 08:00:12Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package org.hibernate.validation.util;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.List;
+import java.util.ArrayList;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import org.junit.Test;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class ReflectionHelperTest {
+ @Test
+ public void testGetIndexedValueFormMap() {
+ Map<String, Object> map = new HashMap<String, Object>();
+ Object testObject = new Object();
+ String key = "key";
+ map.put( key, testObject );
+
+ Object value = ReflectionHelper.getIndexedValue( map, key );
+ assertEquals( "We should be able to retrieve the indexed object", testObject,
value );
+
+ // try to get to the value by integer index
+ value = ReflectionHelper.getIndexedValue( map, "0" );
+ assertEquals( "We should be able to retrieve the indexed object", testObject,
value );
+
+ value = ReflectionHelper.getIndexedValue( map, "foo" );
+ assertNull("A non existent index should return the null value", value);
+
+ value = ReflectionHelper.getIndexedValue( map, "2" );
+ assertNull("A non existent index should return the null value", value);
+ }
+
+ @Test
+ public void testGetIndexedValueForList() {
+ List<Object> list = new ArrayList<Object>();
+ Object testObject = new Object();
+ list.add( testObject );
+
+ Object value = ReflectionHelper.getIndexedValue( list, "0" );
+ assertEquals( "We should be able to retrieve the indexed object", testObject,
value );
+
+ value = ReflectionHelper.getIndexedValue( list, "2" );
+ assertNull("A non existent index should return the null value", value);
+ }
+
+ @Test
+ public void testGetIndexedValueForNull() {
+ Object value = ReflectionHelper.getIndexedValue( null, "0" );
+ assertNull( value );
+ }
+}
Added: validator/trunk/hibernate-validator/src/test/resources/log4j.properties
===================================================================
--- validator/trunk/hibernate-validator/src/test/resources/log4j.properties
(rev 0)
+++ validator/trunk/hibernate-validator/src/test/resources/log4j.properties 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,24 @@
+### direct log messages to stdout ###
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
+
+### direct messages to file hibernate.log ###
+log4j.appender.file=org.apache.log4j.FileAppender
+log4j.appender.file.File=hibernate.log
+log4j.appender.file.layout=org.apache.log4j.PatternLayout
+log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
+
+### direct messages to socket - chainsaw ###
+log4j.appender.socket=org.apache.log4j.net.SocketAppender
+log4j.appender.socket.remoteHost=localhost
+log4j.appender.socket.port=4560
+log4j.appender.socket.locationInfo=true
+
+
+### set log levels - for more verbose logging change 'info' to 'debug'
###
+log4j.rootLogger=debug, stdout
+
+log4j.logger.org.hibernate.validation.engine.ValidatorImpl=trace
+
Property changes on: validator/trunk/hibernate-validator-legacy
___________________________________________________________________
Name: svn:ignore
+ build
target
test_output
Added: validator/trunk/pom.xml
===================================================================
--- validator/trunk/pom.xml (rev 0)
+++ validator/trunk/pom.xml 2008-10-02 10:39:39 UTC (rev 15247)
@@ -0,0 +1,223 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
xmlns="http://maven.apache.org/POM/4.0.0"
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.hibernate</groupId>
+ <artifactId>hibernate-validator-parent</artifactId>
+ <packaging>pom</packaging>
+ <version>1.0.0-SNAPSHOT</version>
+ <name>Hibernate Validator Parent</name>
+ <url>http://localhost/~hardy/</url>
+
+ <description>
+ Hibernate's Bean Validation (JSR-303) reference implementation.
+ </description>
+
+ <developers>
+ <developer>
+ <name>Emmanuel Bernard</name>
+ <email>emmanuel(a)hibernate.org</email>
+ <organization>JBoss, a division of Red Hat</organization>
+ <url>http://in.relation.to/Bloggers/Emmanuel</url>
+ </developer>
+ <developer>
+ <name>Hardy Ferentschik</name>
+ <email>hferents(a)redhat.com</email>
+ <organization>JBoss, a division of Red Hat</organization>
+ <url>http://in.relation.to/Bloggers/Hardy</url>
+ </developer>
+ </developers>
+
+ <repositories>
+ <repository>
+ <id>repository.jboss.org</id>
+ <name>JBoss Repository</name>
+ <
url>http://repository.jboss.org/maven2</url>
+ </repository>
+ </repositories>
+
+ <pluginRepositories>
+ <pluginRepository>
+ <id>repository.jboss.org</id>
+ <name>JBoss Repository</name>
+ <
url>http://repository.jboss.org/maven2</url>
+ </pluginRepository>
+ </pluginRepositories>
+
+ <modules>
+ <module>validation-api</module>
+ <module>hibernate-validator</module>
+ </modules>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>javax.validation</groupId>
+ <artifactId>validation-api</artifactId>
+ <version>${version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>1.4.2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <version>1.4.2</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-collections</groupId>
+ <artifactId>commons-collections</artifactId>
+ <version>3.2</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.4</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <build>
+ <extensions>
+ <extension>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-webdav</artifactId>
+ <version>1.0-beta-2</version>
+ </extension>
+ </extensions>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.2</version>
+ <configuration>
+ <archive>
+ <manifestEntries>
+
<Implementation-Title>${pom.artifactId}</Implementation-Title>
+
<Implementation-Version>${pom.version}</Implementation-Version>
+
<Implementation-Vendor>${pom.groupId}</Implementation-Vendor>
+
<Implementation-Vendor-Id>${pom.groupId}</Implementation-Vendor-Id>
+
<Implementation-URL>${pom.url}</Implementation-URL>
+ <Specification-Title>Bean
Validation"</Specification-Title>
+ </manifestEntries>
+ </archive>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <forkMode>always</forkMode>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-source-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-sources</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+
+ <ciManagement>
+ <system>Hudson</system>
+ <
url>http://hudson.qa.jboss.com/hudson/job/beanvalidation</url>
+ </ciManagement>
+
+ <issueManagement>
+ <system>JIRA</system>
+
<
url>http://opensource.atlassian.com/projects/hibernate/browse/BVAL<...
+ </issueManagement>
+
+ <inceptionYear>2007</inceptionYear>
+
+ <licenses>
+ <license>
+ <name>Apache License, Version 2.0</name>
+ <
url>http://www.apache.org/licenses/LICENSE-2.0</url>
+ </license>
+ </licenses>
+
+ <scm>
+
<
connection>scm:https://svn.jboss.org/repos/beancheck/ri/trunk</conn...
+ <
url>http://fisheye.jboss.org/browse/Fixme</url>
+ </scm>
+
+ <distributionManagement>
+ <repository>
+ <!-- Copy the dist to the local checkout of the JBoss maven2 repo
${maven.repository.root} -->
+ <!-- It is anticipated that ${maven.repository.root} be set in user's
settings.xml -->
+ <!-- todo : replace this with direct svn access once the svnkit providers
are available -->
+ <id>repository.jboss.org</id>
+ <url>file://${maven.repository.root}</url>
+ </repository>
+ <snapshotRepository>
+ <id>snapshots.jboss.org</id>
+ <name>JBoss Snapshot Repository</name>
+ <
url>dav:https://snapshots.jboss.org/maven2</url>
+ </snapshotRepository>
+ <site>
+ <id>local</id>
+ <url>file:///Users/hardy/Sites</url>
+ </site>
+ </distributionManagement>
+
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-project-info-reports-plugin</artifactId>
+ <version>2.0.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>jxr-maven-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <artifactId>maven-clover-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-pmd-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>taglist-maven-plugin</artifactId>
+ </plugin>
+ <!--plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>changelog-maven-plugin</artifactId>
+ </plugin-->
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>changes-maven-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </reporting>
+
+</project>
Added: validator/trunk/src/site/site.xml
===================================================================
--- validator/trunk/src/site/site.xml (rev 0)
+++ validator/trunk/src/site/site.xml 2008-10-02 10:39:39 UTC (rev 15247)
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<project name="Maven">
+ <bannerLeft>
+ <name>Maven</name>
+ <
src>http://maven.apache.org/images/apache-maven-project.png</src>
+ <
href>http://maven.apache.org/</href>
+ </bannerLeft>
+ <bannerRight>
+ <
src>http://maven.apache.org/images/maven-small.gif</src>
+ </bannerRight>
+ <body>
+ <links>
+ <item name="Maven 2"
href="http://maven.apache.org/"/>
+ </links>
+
+ <menu ref="modules" />
+ <menu ref="reports"/>
+
+
+ </body>
+</project>
\ No newline at end of file
Property changes on: validator/trunk/validation-api
___________________________________________________________________
Name: svn:ignore
+ target
Added: validator/trunk/validation-api/pom.xml
===================================================================
--- validator/trunk/validation-api/pom.xml (rev 0)
+++ validator/trunk/validation-api/pom.xml 2008-10-02 10:39:39 UTC (rev 15247)
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
xmlns="http://maven.apache.org/POM/4.0.0"
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.hibernate</groupId>
+ <artifactId>hibernate-validator-parent</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <groupId>javax.validation</groupId>
+ <artifactId>validation-api</artifactId>
+ <packaging>jar</packaging>
+ <name>Bean Validation API</name>
+
+ <distributionManagement>
+ <site>
+ <id>local</id>
+ <url>file:///Users/hardy/Sites/${artifactId}</url>
+ </site>
+ </distributionManagement>
+</project>
Added: validator/trunk/validation-api/src/main/java/javax/validation/Constraint.java
===================================================================
--- validator/trunk/validation-api/src/main/java/javax/validation/Constraint.java
(rev 0)
+++
validator/trunk/validation-api/src/main/java/javax/validation/Constraint.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,49 @@
+// $Id: Constraint.java 114 2008-10-01 13:44:26Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package javax.validation;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * Define the logic to validate a given constraint.
+ *
+ * @author Emmanuel Bernard
+ * @author Hardy Ferentschik
+ */
+public interface Constraint<A extends Annotation> {
+ /**
+ * Validator parameters for a given constraint definition
+ * Annotations parameters are passed as key/value into parameters
+ * <p/>
+ * This method is guaranteed to be called before any of the other Constraint
implementation methods
+ *
+ * @param constraintAnnotation parameters for a given constraint definition
+ */
+ void initialize(A constraintAnnotation);
+
+ /**
+ * Implement the validation constraint
+ *
+ * @param object object to validate
+ * @param validationContext context in which the constraint implementation is evaluated
+ *
+ * @return true if object pass the constraint
+ */
+ boolean isValid(Object object, Context validationContext);
+}
+
\ No newline at end of file
Added:
validator/trunk/validation-api/src/main/java/javax/validation/ConstraintDescriptor.java
===================================================================
---
validator/trunk/validation-api/src/main/java/javax/validation/ConstraintDescriptor.java
(rev 0)
+++
validator/trunk/validation-api/src/main/java/javax/validation/ConstraintDescriptor.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,51 @@
+// $Id: ConstraintDescriptor.java 114 2008-10-01 13:44:26Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package javax.validation;
+
+import java.lang.annotation.Annotation;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Describes a single constraint.
+ *
+ * @author Emmanuel Bernard
+ * @author Hardy Ferentschik
+ */
+public interface ConstraintDescriptor {
+ /**
+ * @return The annotation for this constraint.
+ */
+ Annotation getAnnotation();
+
+ /**
+ * @return The groups the constraint is applied on.
+ */
+ Set<String> getGroups();
+
+ /**
+ * @return The actual constraint implementation.
+ */
+ Constraint getConstraintImplementation();
+
+ /**
+ * @return Returns a map containing the annotation paramter names as keys and the
annotation parameter values
+ * as value.
+ */
+ Map<String, Object> getParameters();
+}
Added:
validator/trunk/validation-api/src/main/java/javax/validation/ConstraintFactory.java
===================================================================
--- validator/trunk/validation-api/src/main/java/javax/validation/ConstraintFactory.java
(rev 0)
+++
validator/trunk/validation-api/src/main/java/javax/validation/ConstraintFactory.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,30 @@
+// $Id: ConstraintFactory.java 114 2008-10-01 13:44:26Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package javax.validation;
+
+/**
+ * Instantiate a Constraint from it's class.
+ * The ConstraintFactory is <b>not</b> responsible for calling
Constraint#initialize
+ *
+ * @author Dhanji R. Prasanna
+ * @author Emmanuel Bernard
+ * @author Hardy Ferentschik
+ */
+public interface ConstraintFactory {
+ <T extends Constraint> T getInstance(Class<T> key);
+}
Added:
validator/trunk/validation-api/src/main/java/javax/validation/ConstraintValidator.java
===================================================================
---
validator/trunk/validation-api/src/main/java/javax/validation/ConstraintValidator.java
(rev 0)
+++
validator/trunk/validation-api/src/main/java/javax/validation/ConstraintValidator.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,45 @@
+// $Id: ConstraintValidator.java 114 2008-10-01 13:44:26Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package javax.validation;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+
+/**
+ * Link between an constraint annotation and it's constraint validation
implementation.
+ * <p/>
+ * An given constraint annotation should be annotated by a @ConstraintValidator
+ * annotation which refers to its constraint validation implementation.
+ *
+ * @author Emmanuel Bernard (emmanuel at
hibernate.org)
+ * @author Gavin King
+ * @author Hardy Ferentschik
+ */
+@Documented
+@Target({ ANNOTATION_TYPE })
+@Retention(RUNTIME)
+public @interface ConstraintValidator {
+ /**
+ * Constraint validation implementation
+ */
+ public abstract Class<? extends Constraint> value();
+}
\ No newline at end of file
Added: validator/trunk/validation-api/src/main/java/javax/validation/Context.java
===================================================================
--- validator/trunk/validation-api/src/main/java/javax/validation/Context.java
(rev 0)
+++ validator/trunk/validation-api/src/main/java/javax/validation/Context.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,55 @@
+package javax.validation;
+
+/**
+ * Provide contextual data and operation when applying a given constraint implementation
+ *
+ * @author Emmanuel Bernard
+ */
+public interface Context {
+ /**
+ * Disable default error message and default InvalidConstraint object generation.
+ * Useful to set a different error message or generate an InvalidConstraint based on
+ * a different property
+ *
+ * @see #addError(String)
+ * @see #addError(String, String)
+ */
+ void disableDefaultError();
+
+ /**
+ * return the current unexpanded default message
+ * TODO: is it needed
+ */
+ String getDefaultErrorMessage();
+
+ /**
+ * Add a new unexpanded error message.
+ * <p/>
+ * If isValid returns false, an InvalidConstraint object will be built per error
message
+ * including the default one unless #disableDefaultErrorMEssage() has been called.
+ * <p/>
+ * Aside from the error message, InvalidConstraint objects generated from such a call
+ * contains the same contextual information (root bean, path and so on)
+ * <p/>
+ * This method can be called multiple time. One InvalidConstraint instance per call is
created.
+ *
+ * @param message new unexpanded error message
+ */
+ void addError(String message);
+
+ /**
+ * Add a new unexpanded error message to a given sub property.
+ * <p/>
+ * If isValid returns false, an InvalidConstraint object will be built per error message
including the default one
+ * if null apply to the current property or the bean the constraint is applied on,
otherwise apply to the <code>property</code> named
+ * <p/>
+ * TODO exception or swallowed when bean-level instance is not present?
+ *
+ * @param message new unexpanded error message
+ * @param property property name the InvalidConstraint is targeting
+ *
+ * @throws ValidationException when the property is not present on the bean level
object
+ */
+ void addError(String message, String property);
+
+}
Added:
validator/trunk/validation-api/src/main/java/javax/validation/ElementDescriptor.java
===================================================================
--- validator/trunk/validation-api/src/main/java/javax/validation/ElementDescriptor.java
(rev 0)
+++
validator/trunk/validation-api/src/main/java/javax/validation/ElementDescriptor.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,59 @@
+// $Id: ElementDescriptor.java 114 2008-10-01 13:44:26Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package javax.validation;
+
+import java.lang.annotation.ElementType;
+import java.util.List;
+
+/**
+ * Describes a validated element (class, field or property).
+ *
+ * @author Emmanuel Bernard
+ * @author Hardy Ferentschik
+ */
+public interface ElementDescriptor {
+ /**
+ * @return The element type.
+ */
+ ElementType getElementType();
+
+ /**
+ * @return Statically defined returned type.
+ *
+ * @todo should it be Type or even completly removed
+ */
+ Class getReturnType();
+
+ /**
+ * @return Returns <code>true</code> if the association is cascaded,
<code>false</code> otherwise.
+ */
+ boolean isCascaded();
+
+ /**
+ * @return All the constraint descriptors for this element.
+ */
+ List<ConstraintDescriptor> getConstraintDescriptors();
+
+ /**
+ * @return Property path from the root entity validated.
+ *
+ * @todo there is a problem in describing cyclic dependencies
+ */
+ String getPropertyPath();
+
+}
Added: validator/trunk/validation-api/src/main/java/javax/validation/GroupSequence.java
===================================================================
--- validator/trunk/validation-api/src/main/java/javax/validation/GroupSequence.java
(rev 0)
+++
validator/trunk/validation-api/src/main/java/javax/validation/GroupSequence.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,34 @@
+// $Id: GroupSequence.java 114 2008-10-01 13:44:26Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package javax.validation;
+
+import static java.lang.annotation.ElementType.TYPE;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * @author Hardy Ferentschik
+ */
+@Target({ TYPE })
+@Retention(RUNTIME)
+public @interface GroupSequence {
+ String name();
+
+ String[] sequence();
+}
Added: validator/trunk/validation-api/src/main/java/javax/validation/GroupSequences.java
===================================================================
--- validator/trunk/validation-api/src/main/java/javax/validation/GroupSequences.java
(rev 0)
+++
validator/trunk/validation-api/src/main/java/javax/validation/GroupSequences.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,32 @@
+// $Id: GroupSequences.java 114 2008-10-01 13:44:26Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package javax.validation;
+
+import static java.lang.annotation.ElementType.TYPE;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * @author Hardy Ferentschik
+ */
+@Target({ TYPE })
+@Retention(RUNTIME)
+public @interface GroupSequences {
+ GroupSequence[] value();
+}
\ No newline at end of file
Added:
validator/trunk/validation-api/src/main/java/javax/validation/InvalidConstraint.java
===================================================================
--- validator/trunk/validation-api/src/main/java/javax/validation/InvalidConstraint.java
(rev 0)
+++
validator/trunk/validation-api/src/main/java/javax/validation/InvalidConstraint.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,62 @@
+// $Id: InvalidConstraint.java 114 2008-10-01 13:44:26Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package javax.validation;
+
+import java.util.Set;
+
+/**
+ * Describe a constraint validation defect.
+ *
+ * @author Emmanuel Bernard
+ * @todo add pointers to the metadata?
+ * @todo the rational behind rootBean and propertyPath is to keep the context available
to the user
+ */
+public interface InvalidConstraint<T> {
+
+ /**
+ * @return The error message for this constraint violation.
+ */
+ String getMessage();
+
+ /**
+ * @return The root bean being validated.
+ */
+ T getRootBean();
+
+ /**
+ * @return the bean type being validated.
+ */
+ Class<T> getBeanClass();
+
+ /**
+ * @return the value failing to pass the constraint.
+ */
+ Object getValue();
+
+ /**
+ * @return the property path to the value from <code>rootBean</code>
+ * <code>null</code> if the value is the
<code>rootBean<code> itself.
+ */
+ String getPropertyPath();
+
+ /**
+ * @return the list of groups that the triggered constraint applies on and which also
are
+ * within the list of groups requested for validation.
+ */
+ Set<String> getGroups();
+}
Added: validator/trunk/validation-api/src/main/java/javax/validation/MessageResolver.java
===================================================================
--- validator/trunk/validation-api/src/main/java/javax/validation/MessageResolver.java
(rev 0)
+++
validator/trunk/validation-api/src/main/java/javax/validation/MessageResolver.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,37 @@
+// $Id: MessageResolver.java 114 2008-10-01 13:44:26Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package javax.validation;
+
+/**
+ * Interpolate a given validation message.
+ *
+ * @author Emmanuel Bernard
+ * @author Hardy Ferentschik
+ */
+public interface MessageResolver {
+ /**
+ * Interpolate the message from the constraint parameters and the actual validated
object.
+ *
+ * @param message The message to interpolate.
+ * @param constraintDescriptor The constraint descriptor.
+ * @param value The actual validted object.
+ *
+ * @return Interpolated error message.
+ */
+ String interpolate(String message, ConstraintDescriptor constraintDescriptor, Object
value);
+}
Added:
validator/trunk/validation-api/src/main/java/javax/validation/StandardConstraint.java
===================================================================
--- validator/trunk/validation-api/src/main/java/javax/validation/StandardConstraint.java
(rev 0)
+++
validator/trunk/validation-api/src/main/java/javax/validation/StandardConstraint.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,32 @@
+// $Id: StandardConstraint.java 114 2008-10-01 13:44:26Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package javax.validation;
+
+/**
+ * Define the constraint influence on standard constraint dimensions
+ *
+ * @author Emmanuel Bernard
+ * @author Hardy Ferentschik
+ */
+public interface StandardConstraint {
+ /**
+ * returns the StandardConstraintDescriptor initialized according to the
+ * constraint validator
+ */
+ StandardConstraintDescriptor getStandardConstraints();
+}
Added:
validator/trunk/validation-api/src/main/java/javax/validation/StandardConstraintDescriptor.java
===================================================================
---
validator/trunk/validation-api/src/main/java/javax/validation/StandardConstraintDescriptor.java
(rev 0)
+++
validator/trunk/validation-api/src/main/java/javax/validation/StandardConstraintDescriptor.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,63 @@
+// $Id: StandardConstraintDescriptor.java 114 2008-10-01 13:44:26Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package javax.validation;
+
+/**
+ * Describe how the current constraint influences the standard constraints.
+ *
+ * @author Emmanuel Bernard
+ * @author Hardy Ferentschik
+ */
+public class StandardConstraintDescriptor {
+ /**
+ * Defines the object nullability.
+ *
+ * @return <code>TRUE<code> if the object is nullable,
<code>FALSE</code> if object is not
+ * nullable and <code>null</code> if nullabiltiy does not apply.
+ */
+ public Boolean getNullability() {
+ return null;
+ }
+
+ /**
+ * Defines the precision if the validated object is a number.
+ *
+ * @return the number's precision or <code>null</code> if precision does
not apply.
+ */
+ public Integer getPrecision() {
+ return null;
+ }
+
+ /**
+ * Defines the scale if the validated object is a number.
+ *
+ * @return the number's scale or <code>null</code> if scale does not
apply.
+ */
+ public Integer getScale() {
+ return null;
+ }
+
+ /**
+ * Defines the length if the validated object is a string.
+ *
+ * @return the strings's length or <code>null</code> if length does not
apply.
+ */
+ public Integer getLength() {
+ return null;
+ }
+}
Added: validator/trunk/validation-api/src/main/java/javax/validation/Valid.java
===================================================================
--- validator/trunk/validation-api/src/main/java/javax/validation/Valid.java
(rev 0)
+++ validator/trunk/validation-api/src/main/java/javax/validation/Valid.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,36 @@
+// $Id: Valid.java 114 2008-10-01 13:44:26Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package javax.validation;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Mark an association as cascaded.
+ * The associated object will be validated by cascade.
+ *
+ * @author Emmanuel Bernard
+ * @author Hardy Ferentschik
+ */
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface Valid {
+}
Added: validator/trunk/validation-api/src/main/java/javax/validation/Validation.java
===================================================================
--- validator/trunk/validation-api/src/main/java/javax/validation/Validation.java
(rev 0)
+++
validator/trunk/validation-api/src/main/java/javax/validation/Validation.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,218 @@
+// $Id: Validation.java 117 2008-10-02 10:22:31Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package javax.validation;
+
+import javax.validation.bootstrap.DefaultValidationProviderResolver;
+import javax.validation.bootstrap.GenericBuilderFactory;
+import javax.validation.bootstrap.SpecializedBuilderFactory;
+import javax.validation.spi.BootstrapState;
+import javax.validation.spi.ValidationProvider;
+
+/**
+ * This class is the entry point for the Bean Validation framework. There are three ways
to bootstrap the framework:
+ * <ul>
+ * <li>
+ * The easiest approach is to use the default Bean Validation provider.
+ * <pre>
+ * ValidatorFactory factory = Validation.getValidatorBuilder().build();
+ * </pre>
+ * In this case {@link javax.validation.bootstrap.DefaultValidationProviderResolver
DefaultValidationProviderResolver}
+ * will be used to locate available providers.
+ *
+ * The chosen provider is defined as followed:
+ * <ul>
+ * <li>if the XML configuration defines a provider, this provider is
used</li>
+ * <li>if the XML configuratio does not define a provider or if no XML
configuration is present the first provider
+ * returned by the ValidationProviderResolver isntance is used.</li>
+ * </ul>
+ * </li>
+ * <li>
+ * The second bootstrap approach allows to choose a custom
<code>ValidationProviderResolver</code>. The chosen
+ * <code>ValidationProvider</code> is then determined in the same way as in
the default bootstrapping case (see above).
+ * <pre>
+ * ValidatorBuilder<?> builder = Validation
+ * .defineBootstrapState()
+ * .providerResolver( new MyResolverStrategy() )
+ * .getValidatorBuilder();
+ * ValidatorFactory factory = builder.build();
+ * </pre>
+ * </li>
+ *
+ * <p/>
+ * <li>
+ * The third approach allows you to specify explicitly and in a type safe fashion the
expected provider by
+ * using its specific <code>ValidatorBuilder</code> sub-interface.
+ *
+ * Optionally you can choose a custom
<code>ValidationProviderResolver</code>.
+ * <pre>
+ * ACMEValidatorBuilder builder = Validation
+ * .builderType(ACMEValidatorBuilder.class)
+ * .providerResolver( new MyResolverStrategy() ) // optionally set the provider
resolver
+ * .getValidatorBuilder();
+ * ValidatorFactory factory = builder.build();
+ * </pre>
+ * </li>
+ * </ul>
+ * Note:<br/>
+ * <ul>
+ * <li>
+ * The ValidatorFactory object built by the bootstrap process should be cached and shared
amongst
+ * Validator consumers.
+ * </li>
+ * <li>
+ * This class is thread-safe.
+ * </li>
+ * </ul>
+ *
+ * @author Emmanuel Bernard
+ * @author Hardy Feretnschik
+ * @see DefaultValidationProviderResolver
+ */
+public class Validation {
+
+ /**
+ * Build a <code>ValidatorBuilder</code>. The actual provider choice is
given by the XML configuration. If the
+ * XML configuration does not exsist the default is taken.
+ * <p/>
+ * The provider list is resolved using the {@link
javax.validation.bootstrap.DefaultValidationProviderResolver
DefaultValidationProviderResolver}.
+ *
+ * @return <code>ValidatorBuilder</code> instance.
+ */
+ public static ValidatorBuilder<?> getValidatorBuilder() {
+ return defineBootstrapState().getValidatorBuilder();
+ }
+
+ /**
+ * Build a <code>ValidatorBuilder</code>. The provider list is resolved
using the strategy provided to the bootstrap state.
+ * <pre>
+ * ValidatorBuilder<?> builder = Validation
+ * .defineBootstrapState()
+ * .providerResolver( new MyResolverStrategy() )
+ * .getValidatorBuilder();
+ * ValidatorFactory factory = builder.build();
+ * </pre>
+ * The actual provider choice is given by the XML configuration. If the XML
configuration does not exsist the first
+ * available provider will be returned.
+ *
+ * @return instance building a generic <code>ValidatorBuilder</code>
compliant with the bootstrap state provided.
+ */
+ public static GenericBuilderFactory defineBootstrapState() {
+ return new GenericBuilderFactoryImpl();
+ }
+
+ /**
+ * Build a <code>ValidatorBuilder</code> for a particular provider
implementation.
+ * Optionally override the provider resolution strategy used to determine the provider.
+ * <p/>
+ * Used by applications targeting a specific provider programmatically.
+ * <p/>
+ * <pre>
+ * ACMEValidatorBuilder builder = Validation.builderType(ACMEValidatorBuilder.class)
+ * .providerResolver( new MyResolverStrategy() )
+ * .build();
+ * </pre>,
+ * where <code>ACMEValidatorBuilder</code> is the
<code>ValidatorBuiler</code> sub interface uniquely identifying
+ * the ACME Bean Validation provider.
+ *
+ * @param builderType the <code>ValidatorBuilder</code> sub interface
uniquely defining the targeted provider.
+ *
+ * @return instance building a provider specific
<code>ValidatorBuilder</code> sub interface implementation.
+ *
+ * @see #getValidatorBuilder()
+ */
+ public static <T extends ValidatorBuilder<T>>
SpecializedBuilderFactory<T> builderType(Class<T> builderType) {
+ return new SpecializedBuilderFactoryImpl<T>( builderType );
+ }
+
+ //private class, not exposed
+ private static class SpecializedBuilderFactoryImpl<T extends
ValidatorBuilder<T>>
+ implements SpecializedBuilderFactory<T> {
+
+ private Class<T> builderType;
+ private ValidationProviderResolver resolver;
+
+ public SpecializedBuilderFactoryImpl(Class<T> builderType) {
+ this.builderType = builderType;
+ }
+
+ /**
+ * Optionally define the provider resolver implementation used.
+ * If not defined, use the default ValidationProviderResolver
+ *
+ * @param resolver ValidationProviderResolver implementation used
+ *
+ * @return self
+ */
+ public SpecializedBuilderFactory<T> providerResolver(ValidationProviderResolver
resolver) {
+ this.resolver = resolver;
+ return this;
+ }
+
+ /**
+ * Determine the provider implementation suitable for builderType and delegate the
creation
+ * of this specific ValidatorBuilder subclass to the provider.
+ *
+ * @return a ValidatorBuilder sub interface implementation
+ */
+ public T getValidatorBuilder() {
+ if ( builderType == null ) {
+ throw new ValidationException(
+ "builder is mandatory. Use getValidatorBuilder() to use the generic provider
discovery mechanism"
+ );
+ }
+ if ( resolver == null ) {
+ resolver = new DefaultValidationProviderResolver();
+ }
+ for ( ValidationProvider provider : resolver.getValidationProviders() ) {
+ if ( provider.isSuitable( builderType ) ) {
+ GenericBuilderFactoryImpl state = new GenericBuilderFactoryImpl();
+ state.providerResolver( resolver );
+ return provider.createSpecializedValidatorBuilder( state, builderType );
+ }
+ }
+ throw new ValidationException( "Unable to find provider: " + builderType );
+ }
+ }
+
+ //private class, not exposed
+ private static class GenericBuilderFactoryImpl implements GenericBuilderFactory,
BootstrapState {
+
+ private ValidationProviderResolver resolver;
+
+ public GenericBuilderFactory providerResolver(ValidationProviderResolver resolver) {
+ this.resolver = resolver;
+ return this;
+ }
+
+ public ValidationProviderResolver getValidationProviderResolver() {
+ return resolver;
+ }
+
+ public ValidatorBuilder<?> getValidatorBuilder() {
+ ValidationProviderResolver resolver = this.resolver == null ?
+ new DefaultValidationProviderResolver() :
+ this.resolver;
+
+ if ( resolver.getValidationProviders().size() == 0 ) {
+ //FIXME looks like an assertion error almost
+ throw new ValidationException( "Unable to find a default provider" );
+ }
+ return resolver.getValidationProviders().get( 0 ).createGenericValidatorBuilder( this
);
+ }
+ }
+}
Property changes on:
validator/trunk/validation-api/src/main/java/javax/validation/Validation.java
___________________________________________________________________
Name: svn:executable
+ *
Added:
validator/trunk/validation-api/src/main/java/javax/validation/ValidationException.java
===================================================================
---
validator/trunk/validation-api/src/main/java/javax/validation/ValidationException.java
(rev 0)
+++
validator/trunk/validation-api/src/main/java/javax/validation/ValidationException.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,41 @@
+// $Id: ValidationException.java 114 2008-10-01 13:44:26Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package javax.validation;
+
+/**
+ * Base exception of all "unexpected" problems.
+ *
+ * @author Emmanuel Bernard
+ */
+public class ValidationException extends RuntimeException {
+ public ValidationException(String message) {
+ super( message );
+ }
+
+ public ValidationException() {
+ super();
+ }
+
+ public ValidationException(String message, Throwable cause) {
+ super( message, cause );
+ }
+
+ public ValidationException(Throwable cause) {
+ super( cause );
+ }
+}
Property changes on:
validator/trunk/validation-api/src/main/java/javax/validation/ValidationException.java
___________________________________________________________________
Name: svn:executable
+ *
Added:
validator/trunk/validation-api/src/main/java/javax/validation/ValidationProviderResolver.java
===================================================================
---
validator/trunk/validation-api/src/main/java/javax/validation/ValidationProviderResolver.java
(rev 0)
+++
validator/trunk/validation-api/src/main/java/javax/validation/ValidationProviderResolver.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,44 @@
+// $Id: ValidationProviderResolver.java 114 2008-10-01 13:44:26Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package javax.validation;
+
+import java.util.List;
+import javax.validation.spi.ValidationProvider;
+
+/**
+ * Determine the list of Bean Validation providers available in the runtime environment
+ * <p/>
+ * Bean Validation providers are identified by the presence of
META-INF/services/javax.validation.spi.ValidationProvider
+ * files following the Service Provider pattern described
+ * <a
href="http://java.sun.com/j2se/1.5.0/docs/guide/jar/jar.html#Service...
+ * <p/>
+ * Each META-INF/services/javax.validation.spi.ValidationProvider file contains the list
of
+ * ValidationProvider implementations each of them representing a provider.
+ * <p/>
+ * Implementations must be thread-safe.
+ *
+ * @author Emmanuel Bernard
+ */
+public interface ValidationProviderResolver {
+ /**
+ * Returns a list of ValidationProviders available in the runtime environment.
+ *
+ * @return list of validation providers.
+ */
+ List<ValidationProvider> getValidationProviders();
+}
Added: validator/trunk/validation-api/src/main/java/javax/validation/Validator.java
===================================================================
--- validator/trunk/validation-api/src/main/java/javax/validation/Validator.java
(rev 0)
+++
validator/trunk/validation-api/src/main/java/javax/validation/Validator.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,95 @@
+// $Id: Validator.java 114 2008-10-01 13:44:26Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package javax.validation;
+
+import java.io.Serializable;
+import java.util.Set;
+
+/**
+ * Validate a given object type.
+ *
+ * @author Emmanuel Bernard
+ * @author Hardy Ferentschik
+ * @todo Should Serializable be part of the definition?
+ */
+public interface Validator<T> extends Serializable {
+ /**
+ * validate all constraints on object (unless shortcut)
+ *
+ * @param object object to validate
+ * @param groups group name(s) targeted for validation (default to
<code>default</code>
+ *
+ * @return array of invalid constrains or an empty array if none.
+ *
+ * @throws IllegalArgumentException e if object is <code>null</code>.
+ */
+ Set<InvalidConstraint<T>> validate(T object, String... groups);
+
+ /**
+ * validate all constraints on propertyname property of object (unless shortcut)
+ * <p/>
+ *
+ * @param object object to validate
+ * @param propertyName property to validate
+ * @param groups group name(s) targeted for validation (default to
<code>default</code>
+ *
+ * @return array of invalid constrains or an empty array if none
+ *
+ * @throws IllegalArgumentException e if object is <code>null</code>.
+ * @todo Do we keep this method?
+ */
+ Set<InvalidConstraint<T>> validateProperty(T object, String propertyName,
String... groups);
+
+ /**
+ * Validates all constraints on propertyname property if the property value is value
(unless shortcut)
+ * <p/>
+ *
+ * @param propertyName property to validate
+ * @param value property value to validate
+ * @param groups group name(s) targeted for validation (default to
<code>default</code>
+ *
+ * @return array of invalid constrains or an empty array if none
+ *
+ * @todo Do we keep this method?
+ * @todo express limitations of InvalidConstraint in this case.
+ */
+ Set<InvalidConstraint<T>> validateValue(String propertyName, Object value,
String... groups);
+
+ /**
+ * return true if at least one constraint declaration is present for the given bean
+ * or if one property is marked for validation cascade
+ */
+ boolean hasConstraints();
+
+ /**
+ * return the class level constraints
+ */
+ ElementDescriptor getBeanConstraints();
+
+ /**
+ * return the property level constraints for a given propertyName
+ * or null if either the property does not exist or has no constraint
+ */
+ ElementDescriptor getConstraintsForProperty(String propertyName);
+
+ /**
+ * return the property names having at least a constraint defined
+ */
+ String[] getValidatedProperties();
+
+}
Added:
validator/trunk/validation-api/src/main/java/javax/validation/ValidatorBuilder.java
===================================================================
--- validator/trunk/validation-api/src/main/java/javax/validation/ValidatorBuilder.java
(rev 0)
+++
validator/trunk/validation-api/src/main/java/javax/validation/ValidatorBuilder.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,86 @@
+// $Id: ValidatorBuilder.java 114 2008-10-01 13:44:26Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package javax.validation;
+
+import java.io.InputStream;
+
+/**
+ * Receives configuration information, selects the appropriate
+ * Bean Validation provider and build the appropriate
+ * ValidatorFactory.
+ * <p/>
+ * Usage:
+ * <pre>
+ * ValidatorBuilder<?> validatorBuilder = //provided by one of the Validation
bootstrap methods
+ * ValidatorFactory = validatorBuilder
+ * .messageResolver( new CustomMessageResolver() )
+ * .build();
+ * </pre>
+ * <p/>
+ * The ValidationProviderResolver is specified at ValidatorBuilder time (see {@link
javax.validation.spi.ValidationProvider}).
+ * If none is explicitely requested, the default ValidationProviderResolver is used.
+ * <p/>
+ * The provider is selected in the following way:
+ * - if a specific ValidatorBuilder subclass is requested programmatically using
Validation.builderType(),
+ * find the first provider matching it
+ * - if a specific ValidatorBuilder subclass is defined in META-INF/validation.xml,
+ * find the first provider matching it
+ * - otherwise, use the first provider returned by the ValidationProviderResolver
+ * <p/>
+ * Implementations are not meant to be thread safe
+ *
+ * @author Emmanuel Bernard
+ */
+public interface ValidatorBuilder<T extends ValidatorBuilder> {
+ /**
+ * Defines the message resolver used. Has priority over the configuration based message
resolver.
+ *
+ * @param resolver message resolver implementation.
+ *
+ * @return <code>this</code> following the chaining method pattern.
+ */
+ T messageResolver(MessageResolver resolver);
+
+ /**
+ * Defines the constraint factory. Has priority over the configuration based constraint
factory.
+ *
+ * @param constraintFactory constraint factory inmplementation.
+ *
+ * @return <code>this</code> following the chaining method pattern.
+ */
+ T constraintFactory(ConstraintFactory constraintFactory);
+
+ /**
+ * Configure the ValidatorFactory based on <code>stream</code>
+ * If not specified, META-INF/validation.xml is used
+ * <p/>
+ * The stream should be closed by the client API after the ValidatorFactory has been
returned
+ *
+ * @param stream configuration stream.
+ *
+ * @return <code>this</code> following the chaining method pattern.
+ */
+ T configure(InputStream stream);
+
+ /**
+ * Build a ValidatorFactory implementation.
+ *
+ * @return ValidatorFactory
+ */
+ ValidatorFactory build();
+}
Property changes on:
validator/trunk/validation-api/src/main/java/javax/validation/ValidatorBuilder.java
___________________________________________________________________
Name: svn:executable
+ *
Added:
validator/trunk/validation-api/src/main/java/javax/validation/ValidatorFactory.java
===================================================================
--- validator/trunk/validation-api/src/main/java/javax/validation/ValidatorFactory.java
(rev 0)
+++
validator/trunk/validation-api/src/main/java/javax/validation/ValidatorFactory.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,34 @@
+// $Id: ValidatorFactory.java 114 2008-10-01 13:44:26Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package javax.validation;
+
+/**
+ * Factory returning initialized Validator instances.
+ * Implementations are thread-safe
+ * This object is typically cached and reused.
+ *
+ * @author Emmanuel Bernard
+ */
+public interface ValidatorFactory {
+ /**
+ * return an initialized Validator instance for the specific class.
+ * Validator instances can be pooled and shared by the implementation
+ * In this scenario, the implementation must return thread-safe Validator
implementations
+ */
+ <T> Validator<T> getValidator(Class<T> clazz);
+}
Property changes on:
validator/trunk/validation-api/src/main/java/javax/validation/ValidatorFactory.java
___________________________________________________________________
Name: svn:executable
+ *
Added:
validator/trunk/validation-api/src/main/java/javax/validation/bootstrap/DefaultValidationProviderResolver.java
===================================================================
---
validator/trunk/validation-api/src/main/java/javax/validation/bootstrap/DefaultValidationProviderResolver.java
(rev 0)
+++
validator/trunk/validation-api/src/main/java/javax/validation/bootstrap/DefaultValidationProviderResolver.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,136 @@
+// $Id: DefaultValidationProviderResolver.java 114 2008-10-01 13:44:26Z hardy.ferentschik
$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package javax.validation.bootstrap;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Map;
+import java.util.WeakHashMap;
+import javax.validation.ValidationException;
+import javax.validation.ValidationProviderResolver;
+import javax.validation.spi.ValidationProvider;
+
+/**
+ * Find <code>ValidationProvider</code> according to the default
<code>ValidationProviderResolver</code> defined in the
+ * Bean Validation specification. This implementation uses the current classloader or the
classloader which has loaded
+ * the current class if the current class loader is unavailable. The classloader is used
to retrieve the Service Provider files.
+ * <p>
+ * This class implements the Service Provider pattern described <a
href="http://java.sun.com/j2se/1.5.0/docs/guide/jar/jar.html#Service...;.
+ * Since we cannot rely on Java 6 we have to reimplement the
<code>Service</code> functionality.
+ * </p>
+ *
+ * @author Emmanuel Bernard
+ * @author Hardy Ferentschik
+ */
+public class DefaultValidationProviderResolver implements ValidationProviderResolver {
+
+ //cache per classloader for an appropriate discovery
+ //keep them in a weak hashmap to avoid memory leaks and allow proper hot redeployment
+ //TODO use a WeakConcurrentHashMap
+ private static final Map<ClassLoader, List<ValidationProvider>>
providersPerClassloader =
+ new WeakHashMap<ClassLoader, List<ValidationProvider>>();
+
+ private static final String SERVICES_FILE = "META-INF/services/" +
ValidationProvider.class.getName();
+
+ public List<ValidationProvider> getValidationProviders() {
+ ClassLoader classloader = Thread.currentThread().getContextClassLoader();
+ if ( classloader == null ) {
+ classloader = DefaultValidationProviderResolver.class.getClassLoader();
+ }
+
+ List<ValidationProvider> providers;
+ synchronized ( providersPerClassloader ) {
+ providers = providersPerClassloader.get( classloader );
+ }
+
+ if ( providers == null ) {
+ providers = new ArrayList<ValidationProvider>();
+ String name = null;
+ try {
+ Enumeration<URL> providerDefinitions = classloader.getResources( SERVICES_FILE
);
+ while ( providerDefinitions.hasMoreElements() ) {
+ URL url = providerDefinitions.nextElement();
+ InputStream stream = url.openStream();
+ try {
+ BufferedReader reader = new BufferedReader( new InputStreamReader( stream ), 100
);
+ name = reader.readLine();
+ while ( name != null ) {
+ name = name.trim();
+ if ( !name.startsWith( "#" ) ) {
+ final Class<?> providerClass = loadClass(
+ name,
+ DefaultValidationProviderResolver.class
+ );
+
+ providers.add(
+ ( ValidationProvider ) providerClass.newInstance()
+ );
+ }
+ name = reader.readLine();
+ }
+ }
+ finally {
+ stream.close();
+ }
+ }
+ }
+ catch ( IOException e ) {
+ throw new ValidationException( "Unable to read " + SERVICES_FILE, e );
+ }
+ catch ( ClassNotFoundException e ) {
+ //TODO is it better to not fail the whole loading because of a black sheep?
+ throw new ValidationException( "Unable to load Bean Validation provider " +
name, e );
+ }
+ catch ( IllegalAccessException e ) {
+ throw new ValidationException( "Unable to instanciate Bean Validation
provider" + name, e );
+ }
+ catch ( InstantiationException e ) {
+ throw new ValidationException( "Unable to instanciate Bean Validation
provider" + name, e );
+ }
+
+ synchronized ( providersPerClassloader ) {
+ providersPerClassloader.put( classloader, providers );
+ }
+ }
+
+ return providers;
+ }
+
+ public static Class<?> loadClass(String name, Class caller) throws
ClassNotFoundException {
+ try {
+ //try context classloader, if fails try caller classloader
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ if ( loader != null ) {
+ return loader.loadClass( name );
+ }
+ }
+ catch ( ClassNotFoundException e ) {
+ //trying caller classloader
+ if ( caller == null ) {
+ throw e;
+ }
+ }
+ return Class.forName( name, true, caller.getClassLoader() );
+ }
+}
Added:
validator/trunk/validation-api/src/main/java/javax/validation/bootstrap/GenericBuilderFactory.java
===================================================================
---
validator/trunk/validation-api/src/main/java/javax/validation/bootstrap/GenericBuilderFactory.java
(rev 0)
+++
validator/trunk/validation-api/src/main/java/javax/validation/bootstrap/GenericBuilderFactory.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,35 @@
+package javax.validation.bootstrap;
+
+import javax.validation.ValidationProviderResolver;
+import javax.validation.ValidatorBuilder;
+
+/**
+ * Defines the state used to bootstrap Bean Validation and create an appropriate
+ * ValidatorBuilder
+ *
+ * @author Emmanuel Bernard
+ */
+public interface GenericBuilderFactory {
+ /**
+ * Defines the provider resolution strategy.
+ * This resolver returns the list of providers evaluated
+ * to build the ValidationBuilder
+ * <p/>
+ * If no resolver is defined, the default ValidationProviderResolver
+ * implementation is used.
+ *
+ * @return <code>this</code> following the chaining method pattern
+ */
+ GenericBuilderFactory providerResolver(ValidationProviderResolver resolver);
+
+ /**
+ * Returns a generic ValidatorBuilder implementation.
+ * At this stage the provider used to build the ValidationFactory is not defined.
+ * <p/>
+ * The ValidatorBuilder implementation is provided by the first provider returned
+ * by the ValidationProviderResolver strategy.
+ *
+ * @return a ValidatorBuilder implementation compliant with the bootstrap state
+ */
+ ValidatorBuilder<?> getValidatorBuilder();
+}
Added:
validator/trunk/validation-api/src/main/java/javax/validation/bootstrap/SpecializedBuilderFactory.java
===================================================================
---
validator/trunk/validation-api/src/main/java/javax/validation/bootstrap/SpecializedBuilderFactory.java
(rev 0)
+++
validator/trunk/validation-api/src/main/java/javax/validation/bootstrap/SpecializedBuilderFactory.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,36 @@
+package javax.validation.bootstrap;
+
+import javax.validation.ValidationProviderResolver;
+import javax.validation.ValidatorBuilder;
+
+/**
+ * Build implementations of builderType, the specific ValidationBuilder sub interface
uniquely identifying
+ * a provider.
+ * <p/>
+ * The requested provider is the first provider suitable for T (as defined in
+ * {@link javax.validation.spi.ValidationProvider#isSuitable(Class)}). The list of
providers evaluated is
+ * returned by {@link ValidationProviderResolver}. If no ValidationProviderResolver is
defined, the
+ * default ValidationProviderResolver strategy is used.
+ *
+ * @author Emmanuel Bernard
+ */
+public interface SpecializedBuilderFactory<T extends ValidatorBuilder<T>> {
+
+ /**
+ * Optionally define the provider resolver implementation used.
+ * If not defined, use the default ValidationProviderResolver
+ *
+ * @param resolver ValidationProviderResolver implementation used
+ *
+ * @return self
+ */
+ public SpecializedBuilderFactory<T> providerResolver(ValidationProviderResolver
resolver);
+
+ /**
+ * Determine the provider implementation suitable for builderType and delegate the
creation
+ * of this specific ValidatorBuilder subclass to the provider.
+ *
+ * @return a ValidatorBuilder sub interface implementation
+ */
+ public T getValidatorBuilder();
+}
Added:
validator/trunk/validation-api/src/main/java/javax/validation/spi/BootstrapState.java
===================================================================
--- validator/trunk/validation-api/src/main/java/javax/validation/spi/BootstrapState.java
(rev 0)
+++
validator/trunk/validation-api/src/main/java/javax/validation/spi/BootstrapState.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,17 @@
+package javax.validation.spi;
+
+import javax.validation.ValidationProviderResolver;
+
+/**
+ * Defines the state used to bootstrap the ValidationBuilder
+ *
+ * @author Emmanuel Bernard
+ */
+public interface BootstrapState {
+ /**
+ * returns the user defined ValidationProviderResolver strategy instance or
<code>null</code> if undefined.
+ *
+ * @return ValidationProviderResolver instance or null
+ */
+ ValidationProviderResolver getValidationProviderResolver();
+}
Added:
validator/trunk/validation-api/src/main/java/javax/validation/spi/ValidationProvider.java
===================================================================
---
validator/trunk/validation-api/src/main/java/javax/validation/spi/ValidationProvider.java
(rev 0)
+++
validator/trunk/validation-api/src/main/java/javax/validation/spi/ValidationProvider.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,81 @@
+// $Id: ValidationProvider.java 114 2008-10-01 13:44:26Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package javax.validation.spi;
+
+import javax.validation.ValidatorBuilder;
+import javax.validation.ValidatorFactory;
+
+/**
+ * Contract between the validation bootstrap mechanism and the provider engine.
+ * <p/>
+ * Implementations must have a public no-arg constructor. The construction of a provider
should be
+ * as "lightweight" as possible.
+ *
+ * @author Emmanuel Bernard
+ * @author Hardy Ferentschik
+ */
+public interface ValidationProvider {
+ /**
+ * @param builderClass targeted builder class.
+ *
+ * @return <code>true</code> if <code>builderClass</code> is the
Bean Validation Provider sub interface for ValidatorBuilder
+ * This sub interface uniquely identify a provider.
+ */
+ boolean isSuitable(Class<? extends ValidatorBuilder<?>> builderClass);
+
+ /**
+ * Returns a ValidatorBuilder instance implementing the
<code>builderType</code> interface.
+ * The ValidatorBuilder instance uses the current provider
(<code>this</code>) to build
+ * the ValidatorFactory instance.
+ * <p/>
+ * This method can only be called on providers returning true on
<code>#issuitable(builderType)</code>
+ *
+ * @param builderClass the Builder class type
+ * @param state bootstrap state
+ *
+ * @return specific validator builder implementation
+ */
+ <T extends ValidatorBuilder<T>> T
createSpecializedValidatorBuilder(BootstrapState state, Class<T> builderClass);
+
+ /**
+ * Returns a ValidatorBuilder instance. This instance is not bound to
+ * use the current provider. The choice of provider follows the algorithm described
+ * in {@link javax.validation.ValidatorBuilder}
+ * <p/>
+ * The ValidationProviderResolver used is provided by <code>state</code>.
+ * If null, the default ValidationProviderResolver is used.
+ *
+ * @param state bootstrap state
+ *
+ * @return validator builder implementation
+ */
+ ValidatorBuilder<?> createGenericValidatorBuilder(BootstrapState state);
+
+ /**
+ * Build a ValidatorFactory using the current provider implementation. The
ValidationFactory
+ * is assembled and follow the configuration passed using ValidatorBuilderImplementor.
+ * <p>
+ * The returned ValidatorFactory is properly initialized and ready for use.
+ * </p>
+ *
+ * @param configuration the configuration descriptor
+ *
+ * @return the instanciated ValidatorFactory
+ */
+ ValidatorFactory buildValidatorFactory(ValidatorBuilderImplementor configuration);
+}
\ No newline at end of file
Added:
validator/trunk/validation-api/src/main/java/javax/validation/spi/ValidatorBuilderImplementor.java
===================================================================
---
validator/trunk/validation-api/src/main/java/javax/validation/spi/ValidatorBuilderImplementor.java
(rev 0)
+++
validator/trunk/validation-api/src/main/java/javax/validation/spi/ValidatorBuilderImplementor.java 2008-10-02
10:39:39 UTC (rev 15247)
@@ -0,0 +1,56 @@
+// $Id: ValidatorBuilderImplementor.java 114 2008-10-01 13:44:26Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, 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.
+*/
+package javax.validation.spi;
+
+import java.io.InputStream;
+import javax.validation.ConstraintFactory;
+import javax.validation.MessageResolver;
+
+/**
+ * Contract between a <code>ValidationBuilder</code> and a
</code>ValidatorProvider</code> to create
+ * a <code>ValidatorFactory</code>.
+ * The configuration artifacts provided to the <code>ValidationBuilder</code>
are passed along.
+ *
+ * @author Emmanuel Bernard
+ * @author Hardy Ferentschik
+ */
+public interface ValidatorBuilderImplementor {
+ /**
+ * Message resolver as defined by the client programmatically
+ * or null if undefined.
+ *
+ * @return message provider instance or null if not defined
+ */
+ MessageResolver getMessageResolver();
+
+ /**
+ * Returns the configuration stream defined by the client programmatically
+ * or null if undefined.
+ *
+ * @return the configuration input stream or null
+ */
+ InputStream getConfigurationStream();
+
+ /**
+ * Defines the constraint implementation factory as defined by the client
programmatically
+ * or null if undefined
+ *
+ * @return factory instance or null if not defined
+ */
+ ConstraintFactory getConstraintFactory();
+}
Property changes on:
validator/trunk/validation-api/src/main/java/javax/validation/spi/ValidatorBuilderImplementor.java
___________________________________________________________________
Name: svn:executable
+ *
Added: validator/trunk/validation-api/src/site/site.xml
===================================================================
--- validator/trunk/validation-api/src/site/site.xml (rev 0)
+++ validator/trunk/validation-api/src/site/site.xml 2008-10-02 10:39:39 UTC (rev 15247)
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<project name="Maven">
+ <bannerLeft>
+ <name>Maven</name>
+ <
src>http://maven.apache.org/images/apache-maven-project.png</src>
+ <
href>http://maven.apache.org/</href>
+ </bannerLeft>
+ <bannerRight>
+ <
src>http://maven.apache.org/images/maven-small.gif</src>
+ </bannerRight>
+ <body>
+ <links>
+ <item name="Maven 2"
href="http://maven.apache.org/"/>
+ </links>
+
+ <menu ref="reports"/>
+
+ </body>
+</project>
\ No newline at end of file