package org.springframework.roo.addon.dbre; import static org.springframework.roo.model.RooJavaType.ROO_DB_MANAGED; import java.util.List; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Reference; import org.apache.felix.scr.annotations.Service; import org.osgi.service.component.ComponentContext; import org.springframework.roo.addon.dbre.model.Database; import org.springframework.roo.addon.dbre.model.DbreModelService; import org.springframework.roo.classpath.PhysicalTypeIdentifier; import org.springframework.roo.classpath.PhysicalTypeMetadata; import org.springframework.roo.classpath.TypeManagementService; import org.springframework.roo.classpath.customdata.CustomDataKeys; import org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetails; import org.springframework.roo.classpath.details.FieldMetadata; import org.springframework.roo.classpath.itd.AbstractItdMetadataProvider; import org.springframework.roo.classpath.itd.ItdTypeDetailsProvidingMetadataItem; import org.springframework.roo.model.JavaType; import org.springframework.roo.project.LogicalPath; /** * Implementation of {@link DbreMetadataProvider}. * * @author Alan Stewart * @since 1.1 */ @Component(immediate = true) @Service public class DbreMetadataProviderImpl extends AbstractItdMetadataProvider implements DbreMetadataProvider { @Reference private DbreModelService dbreModelService; @Reference private TypeManagementService typeManagementService; protected void activate(final ComponentContext context) { metadataDependencyRegistry.registerDependency( PhysicalTypeIdentifier.getMetadataIdentiferType(), getProvidesType()); addMetadataTrigger(ROO_DB_MANAGED); } @Override protected String createLocalIdentifier(final JavaType javaType, final LogicalPath path) { return DbreMetadata.createIdentifier(javaType, path); } protected void deactivate(final ComponentContext context) { metadataDependencyRegistry.deregisterDependency( PhysicalTypeIdentifier.getMetadataIdentiferType(), getProvidesType()); removeMetadataTrigger(ROO_DB_MANAGED); } @Override protected String getGovernorPhysicalTypeIdentifier( final String metadataIdentificationString) { final JavaType javaType = DbreMetadata .getJavaType(metadataIdentificationString); final LogicalPath path = DbreMetadata .getPath(metadataIdentificationString); return PhysicalTypeIdentifier.createIdentifier(javaType, path); } private IdentifierHolder getIdentifierHolder(final JavaType javaType) { final List<FieldMetadata> identifierFields = persistenceMemberLocator .getIdentifierFields(javaType); if (identifierFields.isEmpty()) { return null; } final FieldMetadata identifierField = identifierFields.get(0); final boolean embeddedIdField = identifierField.getCustomData().get( CustomDataKeys.EMBEDDED_ID_FIELD) != null; final List<FieldMetadata> embeddedIdFields = persistenceMemberLocator .getEmbeddedIdentifierFields(javaType); return new IdentifierHolder(identifierField, embeddedIdField, embeddedIdFields); } public String getItdUniquenessFilenameSuffix() { return "DbManaged"; } @Override protected ItdTypeDetailsProvidingMetadataItem getMetadata( final String metadataIdentificationString, final JavaType aspectName, final PhysicalTypeMetadata governorPhysicalTypeMetadata, final String itdFilename) { // We need to parse the annotation, which we expect to be present final DbManagedAnnotationValues annotationValues = new DbManagedAnnotationValues( governorPhysicalTypeMetadata); if (!annotationValues.isAnnotationFound()) { return null; } // Abort if the database couldn't be deserialized. This can occur if the // DBRE XML file has been deleted or is empty. final Database database = dbreModelService.getDatabase(false); if (database == null) { return null; } // We know governor type details are non-null and can be safely cast final JavaType javaType = governorPhysicalTypeMetadata .getMemberHoldingTypeDetails().getName(); final IdentifierHolder identifierHolder = getIdentifierHolder(javaType); if (identifierHolder == null) { return null; } final FieldMetadata versionField = getVersionField(javaType, metadataIdentificationString); // Search for database-managed entities final Iterable<ClassOrInterfaceTypeDetails> managedEntities = typeLocationService .findClassesOrInterfaceDetailsWithAnnotation(ROO_DB_MANAGED); boolean found = false; for (final ClassOrInterfaceTypeDetails managedEntity : managedEntities) { if (managedEntity.getName().equals(javaType)) { found = true; break; } } if (!found) { final String mid = typeLocationService .getPhysicalTypeIdentifier(javaType); metadataDependencyRegistry.registerDependency(mid, metadataIdentificationString); return null; } final DbreMetadata dbreMetadata = new DbreMetadata( metadataIdentificationString, aspectName, governorPhysicalTypeMetadata, annotationValues, identifierHolder, versionField, managedEntities, database); final ClassOrInterfaceTypeDetails updatedGovernor = dbreMetadata .getUpdatedGovernor(); if (updatedGovernor != null) { typeManagementService.createOrUpdateTypeOnDisk(updatedGovernor); } return dbreMetadata; } public String getProvidesType() { return DbreMetadata.getMetadataIdentiferType(); } private FieldMetadata getVersionField(final JavaType domainType, final String metadataIdentificationString) { return persistenceMemberLocator.getVersionField(domainType); } }