Revision: 790
http://stripes.svn.sourceforge.net/stripes/?rev=790&view=rev
Author: bengunter
Date: 2008-01-21 10:44:14 -0800 (Mon, 21 Jan 2008)
Log Message:
-----------
Fixed STS-78 (at long last!). When validation info is loaded for a class,
Stripes climbs the class hierarchy checking each class for conflicts in the
annotations. The @Validate and @ValidateNestedProperties for a single property
must be present on only one element (getter, setter or field) in a single class.
Modified Paths:
--------------
trunk/stripes/src/net/sourceforge/stripes/validation/DefaultValidationMetadataProvider.java
Modified:
trunk/stripes/src/net/sourceforge/stripes/validation/DefaultValidationMetadataProvider.java
===================================================================
---
trunk/stripes/src/net/sourceforge/stripes/validation/DefaultValidationMetadataProvider.java
2008-01-21 17:00:29 UTC (rev 789)
+++
trunk/stripes/src/net/sourceforge/stripes/validation/DefaultValidationMetadataProvider.java
2008-01-21 18:44:14 UTC (rev 790)
@@ -79,8 +79,11 @@
* @param clazz a class
* @return A map of (possibly nested) property names to [EMAIL PROTECTED]
ValidationMetadata} for the
* property.
+ * @throws StripesRuntimeException if conflicts are found in the
validation annotations, as
+ * determined by [EMAIL PROTECTED]
#checkForValidationAnnotationConflicts(Class)}
*/
protected Map<String, ValidationMetadata> loadForClass(Class<?> clazz) {
+ checkForValidationAnnotationConflicts(clazz);
Map<String, ValidationMetadata> meta = new HashMap<String,
ValidationMetadata>();
try {
PropertyDescriptor[] pds =
Introspector.getBeanInfo(clazz).getPropertyDescriptors();
@@ -177,4 +180,117 @@
return Collections.unmodifiableMap(meta);
}
+
+ /**
+ * Checks the given class and all its superclasses to ensure there are no
conflicts in the
+ * [EMAIL PROTECTED] Validate} and [EMAIL PROTECTED]
ValidateNestedProperties} annotations. These annotations may be
+ * applied to exactly one of the getter method, setter method, or field to
which they apply.
+ * They must be applied together on the same element. If any conflicts are
found in the class
+ * hierarchy, a [EMAIL PROTECTED] StripesRuntimeException} is thrown
explaining what went wrong.
+ *
+ * @param clazz the class to check
+ * @throws StripesRuntimeException if any conflicts are found
+ */
+ protected void checkForValidationAnnotationConflicts(Class<?> clazz) {
+ try {
+ do {
+ PropertyDescriptor[] pds =
Introspector.getBeanInfo(clazz).getPropertyDescriptors();
+ for (PropertyDescriptor pd : pds) {
+ String propertyName = pd.getName();
+ Method accessor = pd.getReadMethod();
+ Method mutator = pd.getWriteMethod();
+ Field field = null;
+ try {
+ field = clazz.getDeclaredField(propertyName);
+ }
+ catch (NoSuchFieldException e) {
+ }
+
+ boolean onAccessor = accessor != null
+ && Modifier.isPublic(accessor.getModifiers())
+ && accessor.getDeclaringClass().equals(clazz)
+ && (accessor.isAnnotationPresent(Validate.class)
|| accessor
+
.isAnnotationPresent(ValidateNestedProperties.class));
+ boolean onMutator = mutator != null
+ && Modifier.isPublic(mutator.getModifiers())
+ && mutator.getDeclaringClass().equals(clazz)
+ && (mutator.isAnnotationPresent(Validate.class) ||
mutator
+
.isAnnotationPresent(ValidateNestedProperties.class));
+ boolean onField = field != null
+ && !Modifier.isStatic(field.getModifiers())
+ && field.getDeclaringClass().equals(clazz)
+ && (field.isAnnotationPresent(Validate.class) ||
field
+
.isAnnotationPresent(ValidateNestedProperties.class));
+
+ // I don't think George Boole would like this ...
+ int count = 0;
+ if (onAccessor) ++count;
+ if (onMutator) ++count;
+ if (onField) ++count;
+
+ // must be 0 or 1
+ if (count > 1) {
+ StringBuilder buf = new StringBuilder(
+ "There are conflicting @Validate and/or
@ValidateNestedProperties annotations in ")
+ .append(clazz)
+ .append(". The following elements are
improperly annotated for the '")
+ .append(propertyName).append("' property:\n");
+ if (onAccessor) {
+ boolean hasSimple =
accessor.isAnnotationPresent(Validate.class);
+ boolean hasNested = accessor
+
.isAnnotationPresent(ValidateNestedProperties.class);
+ buf.append("--> Getter method
").append(accessor.getName()).append(
+ " is annotated with ");
+ if (hasSimple)
+ buf.append("@Validate");
+ if (hasSimple && hasNested)
+ buf.append(" and ");
+ if (hasNested)
+ buf.append("@ValidateNestedProperties");
+ buf.append('\n');
+ }
+ if (onMutator) {
+ boolean hasSimple =
mutator.isAnnotationPresent(Validate.class);
+ boolean hasNested = mutator
+
.isAnnotationPresent(ValidateNestedProperties.class);
+ buf.append("--> Setter method
").append(mutator.getName()).append(
+ " is annotated with ");
+ if (hasSimple)
+ buf.append("@Validate");
+ if (hasSimple && hasNested)
+ buf.append(" and ");
+ if (hasNested)
+ buf.append("@ValidateNestedProperties");
+ buf.append('\n');
+ }
+ if (onField) {
+ boolean hasSimple =
field.isAnnotationPresent(Validate.class);
+ boolean hasNested = field
+
.isAnnotationPresent(ValidateNestedProperties.class);
+ buf.append("--> Field
").append(field.getName()).append(
+ " is annotated with ");
+ if (hasSimple)
+ buf.append("@Validate");
+ if (hasSimple && hasNested)
+ buf.append(" and ");
+ if (hasNested)
+ buf.append("@ValidateNestedProperties");
+ buf.append('\n');
+ }
+ throw new StripesRuntimeException(buf.toString());
+ }
+ }
+ } while ((clazz = clazz.getSuperclass()) != null);
+ }
+ catch (RuntimeException e) {
+ log.error(e, "Failure checking @Validate annotations ",
getClass().getName());
+ throw e;
+ }
+ catch (Exception e) {
+ log.error(e, "Failure checking @Validate annotations ",
getClass().getName());
+ StripesRuntimeException sre = new
StripesRuntimeException(e.getMessage(), e);
+ sre.setStackTrace(e.getStackTrace());
+ throw sre;
+ }
+ }
}
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Stripes-development mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/stripes-development