package org.springframework.roo.addon.op4j; import static org.springframework.roo.model.JavaType.OBJECT; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.builder.ToStringBuilder; import org.springframework.roo.classpath.PhysicalTypeCategory; import org.springframework.roo.classpath.PhysicalTypeIdentifierNamingUtils; import org.springframework.roo.classpath.PhysicalTypeMetadata; import org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetails; import org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetailsBuilder; import org.springframework.roo.classpath.details.FieldMetadataBuilder; import org.springframework.roo.classpath.itd.AbstractItdTypeDetailsProvidingMetadataItem; import org.springframework.roo.metadata.MetadataIdentificationUtils; import org.springframework.roo.model.DataType; import org.springframework.roo.model.JavaSymbolName; import org.springframework.roo.model.JavaType; import org.springframework.roo.project.LogicalPath; /** * Metadata to be triggered by {@link RooOp4j} annotation * * @author Stefan Schmidt * @since 1.1 */ public class Op4jMetadata extends AbstractItdTypeDetailsProvidingMetadataItem { // fully-qualified? private static final JavaType JAVA_RUN_TYPE_TYPES = new JavaType( "org.javaruntype.type.Types"); private static final JavaType KEYS = new JavaType("Keys"); // TODO should be private static final JavaType OP4J_GET = new JavaType( "org.op4j.functions.Get"); private static final String PROVIDES_TYPE_STRING = Op4jMetadata.class .getName(); private static final String PROVIDES_TYPE = MetadataIdentificationUtils .create(PROVIDES_TYPE_STRING); public static String createIdentifier(final JavaType javaType, final LogicalPath path) { return PhysicalTypeIdentifierNamingUtils.createIdentifier( PROVIDES_TYPE_STRING, javaType, path); } public static JavaType getJavaType(final String metadataIdentificationString) { return PhysicalTypeIdentifierNamingUtils.getJavaType( PROVIDES_TYPE_STRING, metadataIdentificationString); } public static String getMetadataIdentiferType() { return PROVIDES_TYPE; } public static LogicalPath getPath(final String metadataIdentificationString) { return PhysicalTypeIdentifierNamingUtils.getPath(PROVIDES_TYPE_STRING, metadataIdentificationString); } public static boolean isValid(final String metadataIdentificationString) { return PhysicalTypeIdentifierNamingUtils.isValid(PROVIDES_TYPE_STRING, metadataIdentificationString); } public Op4jMetadata(final String identifier, final JavaType aspectName, final PhysicalTypeMetadata governorPhysicalTypeMetadata) { super(identifier, aspectName, governorPhysicalTypeMetadata); Validate.isTrue(isValid(identifier), "Metadata identification string '" + identifier + "' does not appear to be a valid"); if (!isValid()) { return; } builder.addInnerType(getInnerType()); // Create a representation of the desired output ITD itdTypeDetails = builder.build(); } private ClassOrInterfaceTypeDetails getInnerType() { final List<FieldMetadataBuilder> fields = new ArrayList<FieldMetadataBuilder>(); builder.getImportRegistrationResolver().addImports(OP4J_GET, JAVA_RUN_TYPE_TYPES); final String targetName = super.destination.getSimpleTypeName(); final String initializer = "Get.attrOf(Types.forClass(" + targetName + ".class),\"" + targetName.toLowerCase() + "\")"; final List<JavaType> parameters = Arrays.asList(OBJECT, destination); final JavaType function = new JavaType("org.op4j.functions.Function", 0, DataType.TYPE, null, parameters); final int fieldModifier = Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL; final FieldMetadataBuilder fieldBuilder = new FieldMetadataBuilder( getId(), fieldModifier, new JavaSymbolName( targetName.toUpperCase()), function, initializer); fields.add(fieldBuilder); final ClassOrInterfaceTypeDetailsBuilder cidBuilder = new ClassOrInterfaceTypeDetailsBuilder( getId(), Modifier.PUBLIC | Modifier.STATIC, KEYS, PhysicalTypeCategory.CLASS); cidBuilder.setDeclaredFields(fields); return cidBuilder.build(); } @Override public String toString() { final ToStringBuilder builder = new ToStringBuilder(this); builder.append("identifier", getId()); builder.append("valid", valid); builder.append("aspectName", aspectName); builder.append("destinationType", destination); builder.append("governor", governorPhysicalTypeMetadata.getId()); builder.append("itdTypeDetails", itdTypeDetails); return builder.toString(); } }