Author: hardy.ferentschik
Date: 2009-08-26 10:28:57 -0400 (Wed, 26 Aug 2009)
New Revision: 17423
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/xml/
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/xml/Customer.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/xml/Person.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/xml/XmlMappingTest.java
validator/trunk/hibernate-validator/src/test/resources/org/
validator/trunk/hibernate-validator/src/test/resources/org/hibernate/
validator/trunk/hibernate-validator/src/test/resources/org/hibernate/validator/
validator/trunk/hibernate-validator/src/test/resources/org/hibernate/validator/xml/
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ValidatorFactoryImpl.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/metadata/BeanMetaDataImpl.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/metadata/MetaConstraint.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/util/ReflectionHelper.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/xml/XmlMappingParser.java
validator/trunk/hibernate-validator/src/test/suite/unit-tests.xml
Log:
HV-214
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ValidatorFactoryImpl.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ValidatorFactoryImpl.java 2009-08-26
12:38:04 UTC (rev 17422)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ValidatorFactoryImpl.java 2009-08-26
14:28:57 UTC (rev 17423)
@@ -20,6 +20,8 @@
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Member;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Set;
import javax.validation.ConstraintValidatorFactory;
import javax.validation.MessageInterpolator;
@@ -28,6 +30,7 @@
import javax.validation.Validator;
import javax.validation.ValidatorContext;
import javax.validation.ValidatorFactory;
+import javax.validation.metadata.ConstraintDescriptor;
import javax.validation.spi.ConfigurationState;
import org.hibernate.validator.metadata.AnnotationIgnores;
@@ -35,6 +38,7 @@
import org.hibernate.validator.metadata.BeanMetaDataImpl;
import org.hibernate.validator.metadata.ConstraintHelper;
import org.hibernate.validator.metadata.MetaConstraint;
+import org.hibernate.validator.util.ReflectionHelper;
import org.hibernate.validator.xml.XmlMappingParser;
/**
@@ -88,25 +92,54 @@
XmlMappingParser mappingParser = new XmlMappingParser( constraintHelper );
mappingParser.parse( mappingStreams );
+ Set<Class<?>> processedClasses = mappingParser.getProcessedClasses();
AnnotationIgnores annotationIgnores = mappingParser.getAnnotationIgnores();
- for ( Class<?> clazz : mappingParser.getProcessedClasses() ) {
+ for ( Class<?> clazz : processedClasses ) {
+ @SuppressWarnings("unchecked")
Class<T> beanClass = ( Class<T> ) clazz;
BeanMetaDataImpl<T> metaData = new BeanMetaDataImpl<T>(
beanClass, constraintHelper, annotationIgnores
);
- for ( MetaConstraint<T, ? extends Annotation> constraint :
mappingParser.getConstraintsForClass( beanClass ) ) {
- metaData.addMetaConstraint( beanClass, constraint );
+ List<Class<?>> classes = new ArrayList<Class<?>>();
+ ReflectionHelper.computeClassHierarchy( beanClass, classes );
+ for ( Class<?> classInHierarchy : classes ) {
+ if ( processedClasses.contains( classInHierarchy ) ) {
+ addXmlConfiguredConstraintToMetaData( mappingParser, beanClass, classInHierarchy,
metaData );
+ }
}
- for ( Member m : mappingParser.getCascadedMembersForClass( beanClass ) ) {
- metaData.addCascadedMember( m );
- }
-
if ( !mappingParser.getDefaultSequenceForClass( beanClass ).isEmpty() ) {
metaData.setDefaultGroupSequence( mappingParser.getDefaultSequenceForClass( beanClass
) );
}
+
beanMetaDataCache.addBeanMetaData( beanClass, metaData );
}
}
+
+ private <T, A extends Annotation> void
addXmlConfiguredConstraintToMetaData(XmlMappingParser mappingParser, Class<T>
rootClass, Class<?> hierarchyClass, BeanMetaDataImpl<T> metaData) {
+ for ( MetaConstraint<?, ? extends Annotation> constraint :
mappingParser.getConstraintsForClass( hierarchyClass ) ) {
+ if ( hierarchyClass.equals( rootClass ) ) {
+ @SuppressWarnings("unchecked") // safe cast due to the class check
+ MetaConstraint<T, ? extends Annotation> castedConstrain = (
MetaConstraint<T, ? extends Annotation> ) constraint;
+ metaData.addMetaConstraint( hierarchyClass, castedConstrain );
+ }
+ else {
+ MetaConstraint<T, A> newMetaConstraint;
+ @SuppressWarnings("unchecked")
+ ConstraintDescriptor<A> descriptor = ( ConstraintDescriptor<A> )
constraint.getDescriptor();
+ if ( constraint.getMember() == null ) {
+ newMetaConstraint = new MetaConstraint<T, A>( rootClass, descriptor );
+ }
+ else {
+ newMetaConstraint = new MetaConstraint<T, A>( constraint.getMember(),
rootClass, descriptor );
+ }
+ metaData.addMetaConstraint( hierarchyClass, newMetaConstraint );
+ }
+ }
+
+ for ( Member m : mappingParser.getCascadedMembersForClass( hierarchyClass ) ) {
+ metaData.addCascadedMember( m );
+ }
+ }
}
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/metadata/BeanMetaDataImpl.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/metadata/BeanMetaDataImpl.java 2009-08-26
12:38:04 UTC (rev 17422)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/metadata/BeanMetaDataImpl.java 2009-08-26
14:28:57 UTC (rev 17423)
@@ -227,35 +227,14 @@
private void createMetaData(AnnotationIgnores annotationIgnores) {
beanDescriptor = new BeanDescriptorImpl<T>( this );
initDefaultGroupSequence();
- List<Class> classes = new ArrayList<Class>();
- computeClassHierarchy( beanClass, classes );
- for ( Class current : classes ) {
+ List<Class<?>> classes = new ArrayList<Class<?>>();
+ ReflectionHelper.computeClassHierarchy( beanClass, classes );
+ for ( Class<?> current : classes ) {
initClass( current, annotationIgnores );
}
}
- /**
- * Get all superclasses and interfaces recursively.
- *
- * @param clazz The class to start the search 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, AnnotationIgnores annotationIgnores) {
+ private void initClass(Class<?> clazz, AnnotationIgnores annotationIgnores) {
initClassConstraints( clazz, annotationIgnores );
initMethodConstraints( clazz, annotationIgnores );
initFieldConstraints( clazz, annotationIgnores );
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/metadata/MetaConstraint.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/metadata/MetaConstraint.java 2009-08-26
12:38:04 UTC (rev 17422)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/metadata/MetaConstraint.java 2009-08-26
14:28:57 UTC (rev 17423)
@@ -37,7 +37,7 @@
/**
* Instances of this class abstract the constraint type (class, method or field
constraint) and give access to
- * meta data about the constraint. This allows a unified handling of constraints in the
validator imlpementation.
+ * meta data about the constraint. This allows a unified handling of constraints in the
validator implementation.
*
* @author Hardy Ferentschik
*/
@@ -108,7 +108,7 @@
return constraintTree.getDescriptor().getGroups();
}
- public ConstraintDescriptor getDescriptor() {
+ public ConstraintDescriptor<A> getDescriptor() {
return constraintTree.getDescriptor();
}
@@ -132,15 +132,11 @@
return elementType;
}
- public ConstraintTree getConstraintTree() {
- return constraintTree;
- }
-
public <T, U, V> boolean validateConstraint(GlobalExecutionContext<T>
executionContext, LocalExecutionContext<U, V> localExecutionContext) {
List<ConstraintViolation<T>> constraintViolations = new
ArrayList<ConstraintViolation<T>>();
localExecutionContext.setElementType( elementType );
constraintTree.validateConstraints(
- typeOfAnnoatedElement(), executionContext, localExecutionContext,
constraintViolations
+ typeOfAnnotatedElement(), executionContext, localExecutionContext,
constraintViolations
);
if ( constraintViolations.size() > 0 ) {
executionContext.addConstraintFailures( constraintViolations );
@@ -166,7 +162,7 @@
}
}
- private Type typeOfAnnoatedElement() {
+ private Type typeOfAnnotatedElement() {
Type t;
switch ( elementType ) {
case TYPE: {
@@ -176,7 +172,7 @@
default: {
t = ReflectionHelper.typeOf( member );
if ( t instanceof Class && ( ( Class ) t ).isPrimitive() ) {
- t = ReflectionHelper.boxedTyp( t );
+ t = ReflectionHelper.boxedType( t );
}
}
}
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/util/ReflectionHelper.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/util/ReflectionHelper.java 2009-08-26
12:38:04 UTC (rev 17422)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/util/ReflectionHelper.java 2009-08-26
14:28:57 UTC (rev 17423)
@@ -50,7 +50,7 @@
private ReflectionHelper() {
}
- //run client in priviledge block
+ //run client in privileged block
@SuppressWarnings("unchecked")
static <T> T getAnnotationParameter(Annotation annotation, String parameterName,
Class<T> type) {
try {
@@ -126,29 +126,9 @@
}
/**
- * Returns the type of the field of return type of a method.
- *
- * @param member the member for which to get the type.
- *
- * @return Returns the type of the field of return type of a method.
- */
- public static Class<?> getAnnotations(Member member) {
-
- Class<?> type = null;
- if ( member instanceof Field ) {
- type = ( ( Field ) member ).getType();
- }
-
- if ( member instanceof Method ) {
- type = ( ( Method ) member ).getReturnType();
- }
- return type;
- }
-
- /**
* @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>.
+ * @return Returns 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>.
*/
@@ -190,7 +170,7 @@
return value;
}
- //run client in priviledge block
+ //run client in privileged block
static void setAccessibility(Member member) {
if ( !Modifier.isPublic( member.getModifiers() ) ) {
//Sun's ease of use, sigh...
@@ -347,7 +327,7 @@
*
* @return Returns the method with the specified name or <code>null</code>
if it does not exist.
*/
- //run client in priviledge block
+ //run client in privileged block
static Method getMethod(Class<?> clazz, String methodName) {
try {
char string[] = methodName.toCharArray();
@@ -374,7 +354,7 @@
*
* @throws IllegalArgumentException in case the parameter {@code primitiveType} does not
represent a primitive type.
*/
- public static Class<?> boxedTyp(Type primitiveType) {
+ public static Class<?> boxedType(Type primitiveType) {
if ( !( primitiveType instanceof Class ) && !( ( Class ) primitiveType
).isPrimitive() ) {
throw new IllegalArgumentException( primitiveType.getClass() + "has to be a
primitive type" );
}
@@ -414,7 +394,7 @@
* @param clazz The class to start the search with.
* @param classes List of classes to which to add all found super classes and
interfaces.
*/
- private static void computeClassHierarchy(Class<?> clazz,
List<Class<?>> classes) {
+ public static void computeClassHierarchy(Class<?> clazz,
List<Class<?>> classes) {
for ( Class current = clazz; current != null; current = current.getSuperclass() ) {
if ( classes.contains( current ) ) {
return;
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/xml/XmlMappingParser.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/xml/XmlMappingParser.java 2009-08-26
12:38:04 UTC (rev 17422)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/xml/XmlMappingParser.java 2009-08-26
14:28:57 UTC (rev 17423)
@@ -120,7 +120,7 @@
if ( constraintMap.containsKey( beanClass ) ) {
for ( MetaConstraint<?, ? extends Annotation> metaConstraint :
constraintMap.get( beanClass ) ) {
@SuppressWarnings("unchecked") // safe cast since the list of meta
constraints is always specific to the bean type
- MetaConstraint<T, ? extends Annotation> boundMetaConstraint = (
MetaConstraint<T, ? extends Annotation> ) metaConstraint;
+ MetaConstraint<T, ? extends Annotation> boundMetaConstraint = (
MetaConstraint<T, ? extends Annotation> ) metaConstraint;
list.add( boundMetaConstraint );
}
return list;
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/xml/Customer.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/xml/Customer.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/xml/Customer.java 2009-08-26
14:28:57 UTC (rev 17423)
@@ -0,0 +1,71 @@
+// $Id: Order.java 17421 2009-08-26 12:25:39Z 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.validator.xml;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class Customer implements Person {
+ private String firstName;
+ private String middleName;
+ private String lastName;
+
+ private String customerId;
+
+ private String password;
+
+ public String getFirstName() {
+ return this.firstName;
+ }
+
+ public void setFirstName(final String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getMiddleName() {
+ return this.middleName;
+ }
+
+ public void setMiddleName(final String middleName) {
+ this.middleName = middleName;
+ }
+
+ public String getLastName() {
+ return this.lastName;
+ }
+
+ public void setLastName(final String lastName) {
+ this.lastName = lastName;
+ }
+
+ public String getCustomerId() {
+ return this.customerId;
+ }
+
+ public void setCustomerId(final String customerId) {
+ this.customerId = customerId;
+ }
+
+ public String getPassword() {
+ return this.password;
+ }
+
+ public void setPassword(final String password) {
+ this.password = password;
+ }
+}
\ No newline at end of file
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/xml/Person.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/xml/Person.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/xml/Person.java 2009-08-26
14:28:57 UTC (rev 17423)
@@ -0,0 +1,30 @@
+// $Id: Order.java 17421 2009-08-26 12:25:39Z 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.validator.xml;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public interface Person {
+
+ String getFirstName();
+
+ String getMiddleName();
+
+ String getLastName();
+}
\ No newline at end of file
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/xml/XmlMappingTest.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/xml/XmlMappingTest.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/xml/XmlMappingTest.java 2009-08-26
14:28:57 UTC (rev 17423)
@@ -0,0 +1,59 @@
+// $Id: Order.java 17421 2009-08-26 12:25:39Z 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.validator.xml;
+
+import java.util.Set;
+import javax.validation.Configuration;
+import javax.validation.ConstraintViolation;
+import javax.validation.Validation;
+import javax.validation.Validator;
+import javax.validation.ValidatorFactory;
+import javax.validation.groups.Default;
+
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.Test;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class XmlMappingTest {
+
+ @Test
+ /**
+ * HV-214
+ */
+ public void testConstraintInheritanceWithXmlConfiguration() {
+
+ final Configuration<?> configuration =
Validation.byDefaultProvider().configure();
+ configuration.addMapping( XmlMappingTest.class.getResourceAsStream(
"mapping.xml" ) );
+
+ final ValidatorFactory validatorFactory = configuration.buildValidatorFactory();
+ final Validator validator = validatorFactory.getValidator();
+
+ final Set<ConstraintViolation<Customer>> violations = validator.validate(
new Customer(), Default.class );
+
+ for ( final ConstraintViolation<Customer> violation : violations ) {
+ System.err.println(
+ violation.getPropertyPath() + " "
+ + violation.getMessage()
+ );
+ }
+
+ assertEquals( violations.size(), 1 );
+ }
+}
Modified: validator/trunk/hibernate-validator/src/test/suite/unit-tests.xml
===================================================================
--- validator/trunk/hibernate-validator/src/test/suite/unit-tests.xml 2009-08-26 12:38:04
UTC (rev 17422)
+++ validator/trunk/hibernate-validator/src/test/suite/unit-tests.xml 2009-08-26 14:28:57
UTC (rev 17423)
@@ -11,8 +11,10 @@
<package
name="org.hibernate.validator.engine.messageinterpolation"/>
<package name="org.hibernate.validator.engine.groups"/>
<package
name="org.hibernate.validator.engine.traversableresolver"/>
+ <package name="org.hibernate.validator.metadata"/>
<package name="org.hibernate.validator.util"/>
<package
name="org.hibernate.validator.util.annotationfactory"/>
+ <package name="org.hibernate.validator.xml"/>
</packages>
</test>
</suite>
\ No newline at end of file