package org.springframework.roo.classpath; import org.apache.commons.lang3.Validate; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Reference; import org.apache.felix.scr.annotations.Service; import org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetails; import org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetailsBuilder; import org.springframework.roo.classpath.details.FieldMetadata; import org.springframework.roo.classpath.details.annotations.AnnotationMetadata; import org.springframework.roo.metadata.MetadataService; import org.springframework.roo.model.JavaSymbolName; import org.springframework.roo.process.manager.FileManager; import org.springframework.roo.project.LogicalPath; import org.springframework.roo.project.ProjectOperations; /** * Implementation of {@link TypeManagementService}. * * @author Alan Stewart * @since 1.1.2 */ @Component @Service public class TypeManagementServiceImpl implements TypeManagementService { @Reference private FileManager fileManager; @Reference private MetadataService metadataService; @Reference private ProjectOperations projectOperations; @Reference private TypeLocationService typeLocationService; @Reference private TypeParsingService typeParsingService; public void addEnumConstant(final String physicalTypeIdentifier, final JavaSymbolName constantName) { Validate.notBlank(physicalTypeIdentifier, "Type identifier not provided"); Validate.notNull(constantName, "Constant name required"); // Obtain the physical type and itd mutable details final PhysicalTypeMetadata ptm = (PhysicalTypeMetadata) metadataService .get(physicalTypeIdentifier); Validate.notNull( ptm, "Java source code unavailable for type " + PhysicalTypeIdentifier .getFriendlyName(physicalTypeIdentifier)); final PhysicalTypeDetails ptd = ptm.getMemberHoldingTypeDetails(); Validate.notNull( ptd, "Java source code details unavailable for type " + PhysicalTypeIdentifier .getFriendlyName(physicalTypeIdentifier)); final ClassOrInterfaceTypeDetailsBuilder cidBuilder = new ClassOrInterfaceTypeDetailsBuilder( (ClassOrInterfaceTypeDetails) ptd); // Ensure it's an enum Validate.isTrue( cidBuilder.getPhysicalTypeCategory() == PhysicalTypeCategory.ENUMERATION, PhysicalTypeIdentifier.getFriendlyName(physicalTypeIdentifier) + " is not an enum"); cidBuilder.addEnumConstant(constantName); createOrUpdateTypeOnDisk(cidBuilder.build()); } public void addField(final FieldMetadata field) { Validate.notNull(field, "Field metadata not provided"); // Obtain the physical type and ITD mutable details final PhysicalTypeMetadata ptm = (PhysicalTypeMetadata) metadataService .get(field.getDeclaredByMetadataId()); Validate.notNull( ptm, "Java source code unavailable for type " + PhysicalTypeIdentifier.getFriendlyName(field .getDeclaredByMetadataId())); final PhysicalTypeDetails ptd = ptm.getMemberHoldingTypeDetails(); Validate.notNull( ptd, "Java source code details unavailable for type " + PhysicalTypeIdentifier.getFriendlyName(field .getDeclaredByMetadataId())); final ClassOrInterfaceTypeDetailsBuilder cidBuilder = new ClassOrInterfaceTypeDetailsBuilder( (ClassOrInterfaceTypeDetails) ptd); // Automatically add JSR 303 (Bean Validation API) support if there is // no current JSR 303 support but a JSR 303 annotation is present boolean jsr303Required = false; for (final AnnotationMetadata annotation : field.getAnnotations()) { if (annotation.getAnnotationType().getFullyQualifiedTypeName() .startsWith("javax.validation")) { jsr303Required = true; break; } } final LogicalPath path = PhysicalTypeIdentifier.getPath(cidBuilder .getDeclaredByMetadataId()); if (jsr303Required) { // It's more likely the version below represents a later version // than any specified in the user's own dependency list projectOperations.addDependency(path.getModule(), "javax.validation", "validation-api", "1.0.0.GA"); } cidBuilder.addField(field); createOrUpdateTypeOnDisk(cidBuilder.build()); } public void createOrUpdateTypeOnDisk(final ClassOrInterfaceTypeDetails cid) { final String fileCanonicalPath = typeLocationService .getPhysicalTypeCanonicalPath(cid.getDeclaredByMetadataId()); final String newContents = typeParsingService .getCompilationUnitContents(cid); fileManager.createOrUpdateTextFileIfRequired(fileCanonicalPath, newContents, true); } @Deprecated public void generateClassFile(final ClassOrInterfaceTypeDetails cid) { createOrUpdateTypeOnDisk(cid); } }