[hibernate-commits] Hibernate SVN: r18937 - in validator/trunk/hibernate-validator/src: test/java/org/hibernate/validator/engine/serialization and 1 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Mon Mar 8 16:52:31 EST 2010


Author: hardy.ferentschik
Date: 2010-03-08 16:52:30 -0500 (Mon, 08 Mar 2010)
New Revision: 18937

Added:
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/serialization/CustomConstraintSerializableTest.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/serialization/DummyEmailValidator.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/serialization/Email.java
Modified:
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/util/annotationfactory/AnnotationProxy.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/util/TestUtil.java
Log:
HV-291 Made sure AnnotationProxy serializable. Note, it is still not guaranteed that the ConstraintViolation will be serializable since it might contain unserailizable information.

Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/util/annotationfactory/AnnotationProxy.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/util/annotationfactory/AnnotationProxy.java	2010-03-08 21:18:03 UTC (rev 18936)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/util/annotationfactory/AnnotationProxy.java	2010-03-08 21:52:30 UTC (rev 18937)
@@ -17,15 +17,15 @@
 */
 package org.hibernate.validator.util.annotationfactory;
 
+import java.io.Serializable;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
-import java.util.Comparator;
+import java.security.AccessController;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.SortedSet;
 import java.util.TreeSet;
-import java.security.AccessController;
 
 import org.hibernate.validator.util.GetDeclaredMethods;
 
@@ -53,21 +53,20 @@
  * @author Davide Marchignoli
  * @see java.lang.annotation.Annotation
  */
-public class AnnotationProxy implements Annotation, InvocationHandler {
+public class AnnotationProxy implements Annotation, InvocationHandler, Serializable {
 
+	private static final long serialVersionUID = 6907601010599429454L;
 	private final Class<? extends Annotation> annotationType;
-	//FIXME it's probably better to use String as a key rather than Method
-	//      to speed up and avoid any fancy permsize/GC issue
-	//      I'd better check the litterature on the subject
-	private final Map<Method, Object> values;
+	private final Map<String, Object> values;
 
+
 	public AnnotationProxy(AnnotationDescriptor descriptor) {
 		this.annotationType = descriptor.type();
 		values = getAnnotationValues( descriptor );
 	}
 
-	private Map<Method, Object> getAnnotationValues(AnnotationDescriptor descriptor) {
-		Map<Method, Object> result = new HashMap<Method, Object>();
+	private Map<String, Object> getAnnotationValues(AnnotationDescriptor descriptor) {
+		Map<String, Object> result = new HashMap<String, Object>();
 		int processedValuesFromDescriptor = 0;
 		GetDeclaredMethods action = GetDeclaredMethods.action( annotationType );
 		final Method[] declaredMethods;
@@ -79,25 +78,25 @@
 		}
 		for ( Method m : declaredMethods ) {
 			if ( descriptor.containsElement( m.getName() ) ) {
-				result.put( m, descriptor.valueOf( m.getName() ) );
+				result.put( m.getName(), descriptor.valueOf( m.getName() ) );
 				processedValuesFromDescriptor++;
 			}
 			else if ( m.getDefaultValue() != null ) {
-				result.put( m, m.getDefaultValue() );
+				result.put( m.getName(), m.getDefaultValue() );
 			}
 			else {
 				throw new IllegalArgumentException( "No value provided for " + m.getName() );
 			}
 		}
 		if ( processedValuesFromDescriptor != descriptor.numberOfElements() ) {
-			throw new RuntimeException( "Trying to instanciate " + annotationType + " with unknown paramters." );
+			throw new RuntimeException( "Trying to instantiate " + annotationType + " with unknown paramters." );
 		}
 		return result;
 	}
 
 	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
-		if ( values.containsKey( method ) ) {
-			return values.get( method );
+		if ( values.containsKey( method.getName() ) ) {
+			return values.get( method.getName() );
 		}
 		return method.invoke( this, args );
 	}
@@ -109,8 +108,8 @@
 	public String toString() {
 		StringBuilder result = new StringBuilder();
 		result.append( '@' ).append( annotationType().getName() ).append( '(' );
-		for ( Method m : getRegisteredMethodsInAlphabeticalOrder() ) {
-			result.append( m.getName() ).append( '=' ).append( values.get( m ) ).append( ", " );
+		for ( String s : getRegisteredMethodsInAlphabeticalOrder() ) {
+			result.append( s ).append( '=' ).append( values.get( s ) ).append( ", " );
 		}
 		// remove last separator:
 		if ( values.size() > 0 ) {
@@ -124,15 +123,8 @@
 		return result.toString();
 	}
 
-	private SortedSet<Method> getRegisteredMethodsInAlphabeticalOrder() {
-		SortedSet<Method> result = new TreeSet<Method>(
-				new Comparator<Method>() {
-					public int compare(Method o1, Method o2) {
-						return o1.getName().compareTo( o2.getName() );
-					}
-				}
-		);
-		//List<Method> result = new LinkedList<Method>();
+	private SortedSet<String> getRegisteredMethodsInAlphabeticalOrder() {
+		SortedSet<String> result = new TreeSet<String>();
 		result.addAll( values.keySet() );
 		return result;
 	}

Added: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/serialization/CustomConstraintSerializableTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/serialization/CustomConstraintSerializableTest.java	                        (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/serialization/CustomConstraintSerializableTest.java	2010-03-08 21:52:30 UTC (rev 18937)
@@ -0,0 +1,99 @@
+// $Id:$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2009, Red Hat, Inc. and/or its affiliates, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.hibernate.validator.engine.serialization;
+
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.Set;
+import javax.validation.ConstraintViolation;
+import javax.validation.Validator;
+
+import org.testng.annotations.Test;
+
+import org.hibernate.validator.util.TestUtil;
+
+
+/**
+ * A <b>sscce</b> (Short, Self Contained, Correct Example) showing that the
+ * simple custom Email validation constraint taken from <a href="http://blog.jteam.nl/2009/08/04/bean-validation-integrating-jsr-303-with-spring/"
+ * >this blog</a> gives a validation result that is not Serializable with
+ * Hibernate Validator 4.0.2.GA with underlying cause that
+ * <p/>
+ * <code>org.hibernate.validator.util.annotationfactory.AnnotationProxy</code>
+ * <p/>
+ * <p/>
+ * Note that Hibernate Validator does not guarantee at all that a
+ * {@link ConstraintViolation} is Serializable because an entity need not be
+ * Serializable, but otherwise there should not be much of a problem (right?).
+ *
+ * @author Henno Vermeulen
+ * @author Hardy Ferentschik
+ */
+public class CustomConstraintSerializableTest {
+
+	@Test
+	public void testSerializeHibernateEmail() throws Exception {
+		Validator validator = TestUtil.getValidator();
+
+		HibernateEmail invalidHibernateEmail = new HibernateEmail();
+		invalidHibernateEmail.email = "test@";
+
+		Set<ConstraintViolation<HibernateEmail>> constraintViolations = validator.validate( invalidHibernateEmail );
+		doSerialize( constraintViolations.iterator().next() );
+	}
+
+	/**
+	 * HV-291
+	 *
+	 * @throws Exception in case the test fails
+	 */
+	@Test
+	public void testSerializeCustomEmail() throws Exception {
+		Validator validator = TestUtil.getValidator();
+
+		CustomEmail invalidCustomEmail = new CustomEmail();
+		invalidCustomEmail.email = "test@";
+		Set<ConstraintViolation<CustomEmail>> constraintViolations = validator.validate( invalidCustomEmail );
+		doSerialize( constraintViolations.iterator().next() );
+	}
+
+	public static byte[] doSerialize(Object obj) throws Exception {
+		ByteArrayOutputStream baos = new ByteArrayOutputStream( 512 );
+		ObjectOutputStream out = new ObjectOutputStream( baos );
+		out.writeObject( obj );
+		out.close();
+		return baos.toByteArray();
+	}
+
+	static class CustomEmail implements Serializable {
+		private static final long serialVersionUID = -9095271389455131159L;
+
+		@Email
+		String email;
+
+	}
+
+	static class HibernateEmail implements Serializable {
+		private static final long serialVersionUID = 7206154160792549270L;
+
+		@org.hibernate.validator.constraints.Email
+		String email;
+	}
+}
+


Property changes on: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/serialization/CustomConstraintSerializableTest.java
___________________________________________________________________
Name: svn:keywords
   + Id

Added: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/serialization/DummyEmailValidator.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/serialization/DummyEmailValidator.java	                        (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/serialization/DummyEmailValidator.java	2010-03-08 21:52:30 UTC (rev 18937)
@@ -0,0 +1,35 @@
+// $Id:$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2009, Red Hat, Inc. and/or its affiliates, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.hibernate.validator.engine.serialization;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class DummyEmailValidator implements ConstraintValidator<Email, String> {
+	public void initialize(Email annotation) {
+	}
+
+	public boolean isValid(String value, ConstraintValidatorContext context) {
+		return false;
+	}
+}
+
+


Property changes on: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/serialization/DummyEmailValidator.java
___________________________________________________________________
Name: svn:keywords
   + Id

Added: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/serialization/Email.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/serialization/Email.java	                        (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/serialization/Email.java	2010-03-08 21:52:30 UTC (rev 18937)
@@ -0,0 +1,52 @@
+// $Id:$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2009, Red Hat, Inc. and/or its affiliates, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.hibernate.validator.engine.serialization;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import javax.validation.Constraint;
+import javax.validation.Payload;
+import javax.validation.ReportAsSingleViolation;
+import javax.validation.constraints.Pattern;
+
+/**
+ * Denotes that a field should contain a valid email address.
+ * <p/>
+ * <p/>
+ * Taken from <a href="http://blog.jteam.nl/2009/08/04/bean-validation-integrating-jsr-303-with-spring/"
+ * >this blog</a>.
+ *
+ * @author Hardy Ferentschik
+ */
+ at Documented
+ at Constraint(validatedBy = { DummyEmailValidator.class })
+ at Target({ ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE })
+ at Retention(RetentionPolicy.RUNTIME)
+ at Pattern(regexp = ".+ at .+\\.[a-z]+")
+ at ReportAsSingleViolation
+public @interface Email {
+
+	public abstract String message() default "{org.hibernate.validator.engine.serialization.Email.message}";
+
+	public abstract Class<?>[] groups() default { };
+
+	public abstract Class<? extends Payload>[] payload() default { };
+}


Property changes on: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/engine/serialization/Email.java
___________________________________________________________________
Name: svn:keywords
   + Id

Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/util/TestUtil.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/util/TestUtil.java	2010-03-08 21:18:03 UTC (rev 18936)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/util/TestUtil.java	2010-03-08 21:52:30 UTC (rev 18937)
@@ -118,7 +118,7 @@
 			actualMessages.add( violation.getMessage() );
 		}
 
-		assertTrue( actualMessages.size() == messages.length, "Wrong number or error messages" );
+		assertTrue( actualMessages.size() == messages.length, "Wrong number of error messages" );
 
 		for ( String expectedMessage : messages ) {
 			assertTrue(
@@ -128,11 +128,11 @@
 			actualMessages.remove( expectedMessage );
 		}
 		assertTrue(
-				actualMessages.isEmpty(), "Actual messages contained more messages as specidied expected messages"
+				actualMessages.isEmpty(), "Actual messages contained more messages as specified expected messages"
 		);
 	}
 
-	public static <T> void assertCorrectConstraintTypes(Set<ConstraintViolation<T>> violations, Class<?>... expectedConsraintTypes) {
+	public static <T> void assertCorrectConstraintTypes(Set<ConstraintViolation<T>> violations, Class<?>... expectedConstraintTypes) {
 		List<String> actualConstraintTypes = new ArrayList<String>();
 		for ( ConstraintViolation<?> violation : violations ) {
 			actualConstraintTypes.add(
@@ -141,10 +141,10 @@
 		}
 
 		assertEquals(
-				expectedConsraintTypes.length, actualConstraintTypes.size(), "Wrong number of constraint types."
+				expectedConstraintTypes.length, actualConstraintTypes.size(), "Wrong number of constraint types."
 		);
 
-		for ( Class<?> expectedConstraintType : expectedConsraintTypes ) {
+		for ( Class<?> expectedConstraintType : expectedConstraintTypes ) {
 			assertTrue(
 					actualConstraintTypes.contains( expectedConstraintType.getName() ),
 					"The constraint type " + expectedConstraintType.getName() + " should have been violated."



More information about the hibernate-commits mailing list