package org.springframework.roo.classpath.details; import org.apache.commons.lang3.Validate; import org.springframework.roo.classpath.details.annotations.AnnotationAttributeValue; import org.springframework.roo.classpath.details.annotations.AnnotationMetadata; import org.springframework.roo.classpath.details.annotations.ArrayAttributeValue; import org.springframework.roo.classpath.details.annotations.BooleanAttributeValue; import org.springframework.roo.classpath.details.annotations.CharAttributeValue; import org.springframework.roo.classpath.details.annotations.ClassAttributeValue; import org.springframework.roo.classpath.details.annotations.DoubleAttributeValue; import org.springframework.roo.classpath.details.annotations.EnumAttributeValue; import org.springframework.roo.classpath.details.annotations.IntegerAttributeValue; import org.springframework.roo.classpath.details.annotations.LongAttributeValue; import org.springframework.roo.classpath.details.annotations.NestedAnnotationAttributeValue; import org.springframework.roo.classpath.details.annotations.StringAttributeValue; import org.springframework.roo.model.EnumDetails; import org.springframework.roo.model.ImportRegistrationResolver; import org.springframework.roo.model.JavaSymbolName; import org.springframework.roo.model.JavaType; /** * Utilities to use with {@link AnnotationMetadata}. * * @author Ben Alex * @author Alan Stewart * @since 1.0 */ public abstract class AnnotationMetadataUtils { private static String computeAttributeValue(final AnnotationAttributeValue<?> value, final ImportRegistrationResolver resolver) { String attributeValue = null; if (value instanceof BooleanAttributeValue) { attributeValue = ((BooleanAttributeValue) value).getValue().toString(); } else if (value instanceof CharAttributeValue) { attributeValue = "'" + ((CharAttributeValue) value).getValue().toString() + "'"; } else if (value instanceof ClassAttributeValue) { final JavaType clazz = ((ClassAttributeValue) value).getValue(); if (resolver == null || resolver.isFullyQualifiedFormRequiredAfterAutoImport(clazz)) { attributeValue = clazz.getFullyQualifiedTypeName() + ".class"; } else { attributeValue = clazz.getSimpleTypeName() + ".class"; } } else if (value instanceof DoubleAttributeValue) { final DoubleAttributeValue dbl = (DoubleAttributeValue) value; if (dbl.isFloatingPrecisionOnly()) { attributeValue = dbl.getValue().toString() + "F"; } else { attributeValue = dbl.getValue().toString() + "D"; } } else if (value instanceof EnumAttributeValue) { final EnumDetails enumDetails = ((EnumAttributeValue) value).getValue(); final JavaType clazz = enumDetails.getType(); if (resolver == null || resolver.isFullyQualifiedFormRequiredAfterAutoImport(clazz)) { attributeValue = clazz.getFullyQualifiedTypeName() + "." + enumDetails.getField().getSymbolName(); } else { attributeValue = clazz.getSimpleTypeName() + "." + enumDetails.getField().getSymbolName(); } } else if (value instanceof IntegerAttributeValue) { attributeValue = ((IntegerAttributeValue) value).getValue().toString(); } else if (value instanceof LongAttributeValue) { attributeValue = ((LongAttributeValue) value).getValue().toString() + "L"; } else if (value instanceof StringAttributeValue) { attributeValue = "\"" + ((StringAttributeValue) value).getValue() + "\""; } else if (value instanceof NestedAnnotationAttributeValue) { final AnnotationMetadata annotationMetadata = ((NestedAnnotationAttributeValue) value).getValue(); final StringBuilder data = new StringBuilder("@"); final JavaType annotationType = annotationMetadata.getAnnotationType(); if (resolver == null || resolver.isFullyQualifiedFormRequiredAfterAutoImport(annotationType)) { data.append(annotationType.getFullyQualifiedTypeName()); } else { data.append(annotationType.getSimpleTypeName()); } if (!annotationMetadata.getAttributeNames().isEmpty()) { data.append("("); int i = 0; for (final JavaSymbolName attributeName : annotationMetadata.getAttributeNames()) { i++; if (i > 1) { data.append(", "); } data.append(attributeName.getSymbolName()).append(" = "); data.append(computeAttributeValue(annotationMetadata.getAttribute(attributeName), resolver)); } data.append(")"); } attributeValue = data.toString(); } else if (value instanceof ArrayAttributeValue<?>) { final ArrayAttributeValue<?> array = (ArrayAttributeValue<?>) value; final StringBuilder data = new StringBuilder("{ "); int i = 0; for (final AnnotationAttributeValue<?> val : array.getValue()) { i++; if (i > 1) { data.append(", "); } data.append(computeAttributeValue(val, resolver)); } data.append(" }"); attributeValue = data.toString(); } return attributeValue; } /** * Converts the annotation into a string-based form. * * @param annotation to covert (required) * @return a string-based representation (never null) */ public static String toSourceForm(final AnnotationMetadata annotation) { return toSourceForm(annotation, null); } /** * Converts the annotation into a string-based form. * * @param annotation to covert (required) * @param resolver to use for automatic addition of used types (may be null) * @return a string-based representation (never null) */ public static String toSourceForm(final AnnotationMetadata annotation, final ImportRegistrationResolver resolver) { Validate.notNull(annotation, "Annotation required"); final StringBuilder sb = new StringBuilder(); sb.append("@"); if (resolver != null) { if (resolver.isFullyQualifiedFormRequiredAfterAutoImport(annotation.getAnnotationType())) { sb.append(annotation.getAnnotationType().getFullyQualifiedTypeName()); } else { sb.append(annotation.getAnnotationType().getSimpleTypeName()); } } else { sb.append(annotation.getAnnotationType().getFullyQualifiedTypeName()); } if (annotation.getAttributeNames().isEmpty()) { return sb.toString(); } sb.append("("); boolean requireComma = false; for (final JavaSymbolName attributeName : annotation.getAttributeNames()) { // Add a comma, to separate the last annotation attribute if (requireComma) { sb.append(", "); requireComma = false; } // Compute the value final AnnotationAttributeValue<?> value = annotation.getAttribute(attributeName); final String attributeValue = computeAttributeValue(value, resolver); if (attributeValue != null) { // We have a supported attribute if (!"value".equals(attributeName.getSymbolName()) || annotation.getAttributeNames().size() > 1) { sb.append(attributeName.getSymbolName()); sb.append(" = "); } sb.append(attributeValue); requireComma = true; } } sb.append(")"); return sb.toString(); } }