Return-Path: Delivered-To: apmail-incubator-bval-commits-archive@minotaur.apache.org Received: (qmail 75040 invoked from network); 22 Sep 2010 01:16:00 -0000 Received: from unknown (HELO mail.apache.org) (140.211.11.3) by 140.211.11.9 with SMTP; 22 Sep 2010 01:16:00 -0000 Received: (qmail 26404 invoked by uid 500); 22 Sep 2010 01:16:00 -0000 Delivered-To: apmail-incubator-bval-commits-archive@incubator.apache.org Received: (qmail 26374 invoked by uid 500); 22 Sep 2010 01:16:00 -0000 Mailing-List: contact bval-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: bval-dev@incubator.apache.org Delivered-To: mailing list bval-commits@incubator.apache.org Received: (qmail 26366 invoked by uid 99); 22 Sep 2010 01:16:00 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 22 Sep 2010 01:16:00 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 22 Sep 2010 01:15:59 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 2E063238890A; Wed, 22 Sep 2010 01:15:39 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r999711 - in /incubator/bval/sandbox/lang3-work/bval-jsr303/src/main/java/org/apache/bval/jsr303: ConstraintAnnotationAttributes.java util/ConstraintDefinitionValidator.java Date: Wed, 22 Sep 2010 01:15:39 -0000 To: bval-commits@incubator.apache.org From: mbenson@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20100922011539.2E063238890A@eris.apache.org> Author: mbenson Date: Wed Sep 22 01:15:38 2010 New Revision: 999711 URL: http://svn.apache.org/viewvc?rev=999711&view=rev Log: more centralization of well-known constraint annotation attributes' handling Modified: incubator/bval/sandbox/lang3-work/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConstraintAnnotationAttributes.java incubator/bval/sandbox/lang3-work/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/ConstraintDefinitionValidator.java Modified: incubator/bval/sandbox/lang3-work/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConstraintAnnotationAttributes.java URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConstraintAnnotationAttributes.java?rev=999711&r1=999710&r2=999711&view=diff ============================================================================== --- incubator/bval/sandbox/lang3-work/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConstraintAnnotationAttributes.java (original) +++ incubator/bval/sandbox/lang3-work/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConstraintAnnotationAttributes.java Wed Sep 22 01:15:38 2010 @@ -17,13 +17,18 @@ package org.apache.bval.jsr303; import java.lang.annotation.Annotation; +import java.lang.reflect.Array; +import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.Locale; import java.util.Map; import javax.validation.Constraint; +import javax.validation.ConstraintDefinitionException; import javax.validation.Payload; +import javax.validation.ValidationException; +import org.apache.bval.jsr303.util.SecureActions; import org.apache.commons.lang3.reflect.TypeUtils; /** @@ -50,7 +55,7 @@ public enum ConstraintAnnotationAttribut /** * "value" for multi-valued constraints */ - VALUE; + VALUE(true); @SuppressWarnings("unused") private static class Types { @@ -61,12 +66,18 @@ public enum ConstraintAnnotationAttribut } private Type type; + private boolean permitNullDefaultValue; private ConstraintAnnotationAttributes() { + this(false); + } + + private ConstraintAnnotationAttributes(boolean permitNullDefaultValue) { + this.permitNullDefaultValue = permitNullDefaultValue; try { this.type = Types.class.getDeclaredField(getAttributeName()).getGenericType(); } catch (Exception e) { - //should never happen + // should never happen throw new RuntimeException(e); } } @@ -120,4 +131,71 @@ public enum ConstraintAnnotationAttribut } return result; } + + /** + * Verify that this attribute is validly defined on the given type. + * + * @param type + * @throws ConstraintDefinitionException + */ + public void validateOn(Class type) { + Method m = SecureActions.getMethod(type, getAttributeName()); + if (m == null) { + throw new ConstraintDefinitionException(String.format("Annotation %1$s has no %2$s() method", type, + getAttributeName())); + } + + if (!TypeUtils.isAssignable(m.getReturnType(), getType())) { + throw new ConstraintDefinitionException(String.format("Return type for %1$s() must be of type %2$s", + getAttributeName(), getType())); + } + Object defaultValue = m.getDefaultValue(); + if (defaultValue == null && permitNullDefaultValue) { + return; + } + if (TypeUtils.isArrayType(getType()) && Array.getLength(defaultValue) > 0) { + throw new ConstraintDefinitionException(String.format("Default value for %1$s() must be an empty array", + getAttributeName())); + } + } + + /** + * Benign means of checking for an attribute's existence. + * + * @param type + * @return whether the attribute was (properly) declared + */ + public boolean isDeclaredOn(Class type) { + Method m = SecureActions.getMethod(type, getAttributeName()); + if (m == null) { + return false; + } + if (!TypeUtils.isAssignable(m.getReturnType(), getType())) { + return false; + } + Object defaultValue = m.getDefaultValue(); + if (defaultValue == null && permitNullDefaultValue) { + return true; + } + if (TypeUtils.isArrayType(getType()) && Array.getLength(defaultValue) > 0) { + return false; + } + return true; + } + + /** + * Get the value of this attribute from the specified constraint annotation. + * + * @param constraint + * @return Object + */ + public Object getValue(Annotation constraint) { + validateOn(constraint.annotationType()); + try { + return SecureActions.getAnnotationValue(constraint, getAttributeName()); + } catch (Exception e) { + throw new ValidationException(String.format("Could not get value of %1$s() from %2$s", getType(), + constraint)); + } + } } Modified: incubator/bval/sandbox/lang3-work/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/ConstraintDefinitionValidator.java URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/ConstraintDefinitionValidator.java?rev=999711&r1=999710&r2=999711&view=diff ============================================================================== --- incubator/bval/sandbox/lang3-work/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/ConstraintDefinitionValidator.java (original) +++ incubator/bval/sandbox/lang3-work/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/ConstraintDefinitionValidator.java Wed Sep 22 01:15:38 2010 @@ -20,6 +20,9 @@ package org.apache.bval.jsr303.util; import javax.validation.Constraint; import javax.validation.ConstraintDefinitionException; + +import org.apache.bval.jsr303.ConstraintAnnotationAttributes; + import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.Locale; @@ -41,94 +44,12 @@ public class ConstraintDefinitionValidat * In case the constraint is invalid. */ public static void validateConstraintDefinition(Annotation annotation) { - validGroups(annotation); - validPayload(annotation); - validMessage(annotation); + ConstraintAnnotationAttributes.GROUPS.validateOn(annotation.annotationType()); + ConstraintAnnotationAttributes.PAYLOAD.validateOn(annotation.annotationType()); + ConstraintAnnotationAttributes.MESSAGE.validateOn(annotation.annotationType()); validAttributes(annotation); } - - /** - * Check that the annotation: - *
    - *
  • Has a groups() method.
  • - *
  • Whose default value is an empty Class[] array.
  • - *
- * - * @param annotation - * The annotation to check. - */ - private static void validGroups(Annotation annotation) { - // Ensure that it has a groups() method... - Method groupsMethod = SecureActions.getMethod(annotation.annotationType(), "groups"); - if ( groupsMethod == null ) { - throw new ConstraintDefinitionException("Constraint definition " + annotation + " has no groups() method"); - } - - // ...whose default value is an empty array - Object defaultGroupsValue = groupsMethod.getDefaultValue(); - if ( defaultGroupsValue instanceof Class[] ) { - if ( ((Class[]) defaultGroupsValue).length != 0 ) { - throw new ConstraintDefinitionException("Default value for groups() must be an empty array"); - } - } - else { - throw new ConstraintDefinitionException("Return type for groups() must be of type Class[]"); - } - } - - /** - * Check that the annotation: - *
    - *
  • Has a payload() method.
  • - *
  • Whose default value is an empty Class[] array.
  • - *
- * - * @param annotation - * The annotation to check. - */ - private static void validPayload(Annotation annotation) { - // Ensure that it has a payload() method... - Method payloadMethod = SecureActions.getMethod(annotation.annotationType(), "payload"); - if ( payloadMethod == null ) { - throw new ConstraintDefinitionException("Constraint definition " + annotation + " has no payload() method"); - } - - // ...whose default value is an empty array - Object defaultPayloadValue = payloadMethod.getDefaultValue(); - if ( defaultPayloadValue instanceof Class[] ) { - if ( ((Class[]) defaultPayloadValue).length != 0 ) { - throw new ConstraintDefinitionException("Default value for payload() must be an empty array"); - } - } - else { - throw new ConstraintDefinitionException("Return type for payload() must be of type Class[]"); - } - } - - /** - * Check that the annotation: - *
    - *
  • Has a message() method.
  • - *
  • Whose default value is a {@link String}.
  • - *
- * - * @param annotation - * The annotation to check. - */ - private static void validMessage(Annotation annotation) { - // Ensure that it has a message() method... - Method messageMethod = SecureActions.getMethod(annotation.annotationType(), "message"); - if ( messageMethod == null ) { - throw new ConstraintDefinitionException("Constraint definition " + annotation + " has no message() method"); - } - - // ...whose default value is a String - Object defaultMessageValue = messageMethod.getDefaultValue(); - if ( !(defaultMessageValue instanceof String) ) { - throw new ConstraintDefinitionException("Return type for message() must be of type String"); - } - } - + /** * Check that the annotation has no methods that start with "valid". * @@ -137,10 +58,11 @@ public class ConstraintDefinitionValidat */ private static void validAttributes(Annotation annotation) { Method[] methods = SecureActions.getDeclaredMethods(annotation.annotationType()); - for ( Method method : methods ) { + for (Method method : methods) { // Currently case insensitive, the spec is unclear about this - if ( method.getName().toLowerCase(Locale.ENGLISH).startsWith("valid") ) { - throw new ConstraintDefinitionException("A constraint annotation cannot have methods which start with 'valid'"); + if (method.getName().toLowerCase(Locale.ENGLISH).startsWith("valid")) { + throw new ConstraintDefinitionException( + "A constraint annotation cannot have methods which start with 'valid'"); } } }