package org.springframework.roo.addon.jpa.addon.identifier; import static org.springframework.roo.model.RooJavaType.ROO_IDENTIFIER; import java.util.List; import java.util.logging.Logger; import org.apache.commons.lang3.Validate; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Service; import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceReference; import org.osgi.service.component.ComponentContext; import org.springframework.roo.addon.configurable.addon.ConfigurableMetadataProvider; import org.springframework.roo.addon.javabean.addon.SerializableMetadataProvider; import org.springframework.roo.addon.jpa.addon.AbstractIdentifierServiceAwareMetadataProvider; import org.springframework.roo.classpath.PhysicalTypeIdentifier; import org.springframework.roo.classpath.PhysicalTypeIdentifierNamingUtils; import org.springframework.roo.classpath.PhysicalTypeMetadata; import org.springframework.roo.classpath.itd.ItdTriggerBasedMetadataProvider; import org.springframework.roo.classpath.itd.ItdTriggerBasedMetadataProviderTracker; import org.springframework.roo.classpath.itd.ItdTypeDetailsProvidingMetadataItem; import org.springframework.roo.metadata.MetadataDependencyRegistry; import org.springframework.roo.metadata.internal.MetadataDependencyRegistryTracker; import org.springframework.roo.model.JavaType; import org.springframework.roo.model.RooJavaType; import org.springframework.roo.project.LogicalPath; import org.springframework.roo.project.ProjectMetadata; import org.springframework.roo.project.ProjectOperations; import org.springframework.roo.support.logging.HandlerUtils; /** * Implementation of {@link IdentifierMetadataProvider}. * * @author Alan Stewart * @author Enrique Ruiz at DISID Corporation S.L. * @since 1.1 */ @Component @Service public class IdentifierMetadataProviderImpl extends AbstractIdentifierServiceAwareMetadataProvider implements IdentifierMetadataProvider { protected final static Logger LOGGER = HandlerUtils .getLogger(IdentifierMetadataProviderImpl.class); private ProjectOperations projectOperations; protected MetadataDependencyRegistryTracker registryTracker = null; protected ItdTriggerBasedMetadataProviderTracker configurableMetadataProviderTracker = null; protected ItdTriggerBasedMetadataProviderTracker serializableMetadataProviderTracker = null; /** * This service is being activated so setup it: * <ul> * <li>Create and open the {@link MetadataDependencyRegistryTracker}.</li> * <li>Create and open one {@link ItdTriggerBasedMetadataProviderTracker} * for each {@link ConfigurableMetadataProvider} and {@link SerializableMetadataProvider}.</li> * <li>Registers {@link RooJavaType#ROO_IDENTIFIER} as additional * JavaType that will trigger metadata registration.</li> * </ul> */ @Override protected void activate(final ComponentContext cContext) { context = cContext.getBundleContext(); this.registryTracker = new MetadataDependencyRegistryTracker(context, null, PhysicalTypeIdentifier.getMetadataIdentiferType(), getProvidesType()); this.registryTracker.open(); addMetadataTrigger(ROO_IDENTIFIER); this.configurableMetadataProviderTracker = new ItdTriggerBasedMetadataProviderTracker(context, ConfigurableMetadataProvider.class, ROO_IDENTIFIER); this.configurableMetadataProviderTracker.open(); this.serializableMetadataProviderTracker = new ItdTriggerBasedMetadataProviderTracker(context, SerializableMetadataProvider.class, ROO_IDENTIFIER); this.serializableMetadataProviderTracker.open(); } /** * This service is being deactivated so unregister upstream-downstream * dependencies, triggers, matchers and listeners. * * @param context */ protected void deactivate(final ComponentContext context) { MetadataDependencyRegistry registry = this.registryTracker.getService(); registry.deregisterDependency(PhysicalTypeIdentifier.getMetadataIdentiferType(), getProvidesType()); this.registryTracker.close(); removeMetadataTrigger(ROO_IDENTIFIER); ItdTriggerBasedMetadataProvider metadataProvider = this.configurableMetadataProviderTracker.getService(); metadataProvider.removeMetadataTrigger(ROO_IDENTIFIER); this.configurableMetadataProviderTracker.close(); metadataProvider = this.serializableMetadataProviderTracker.getService(); metadataProvider.removeMetadataTrigger(ROO_IDENTIFIER); this.serializableMetadataProviderTracker.close(); } @Override protected String createLocalIdentifier(final JavaType javaType, final LogicalPath path) { return IdentifierMetadata.createIdentifier(javaType, path); } @Override protected String getGovernorPhysicalTypeIdentifier(final String metadataIdentificationString) { final JavaType javaType = IdentifierMetadata.getJavaType(metadataIdentificationString); final LogicalPath path = IdentifierMetadata.getPath(metadataIdentificationString); return PhysicalTypeIdentifier.createIdentifier(javaType, path); } public String getItdUniquenessFilenameSuffix() { return "Identifier"; } @Override protected ItdTypeDetailsProvidingMetadataItem getMetadata( final String metadataIdentificationString, final JavaType aspectName, final PhysicalTypeMetadata governorPhysicalTypeMetadata, final String itdFilename) { if (projectOperations == null) { projectOperations = getProjectOperations(); } Validate.notNull(projectOperations, "ProjectOperations is required"); final IdentifierAnnotationValues annotationValues = new IdentifierAnnotationValues(governorPhysicalTypeMetadata); if (!annotationValues.isAnnotationFound()) { return null; } // We know governor type details are non-null and can be safely cast final JavaType javaType = IdentifierMetadata.getJavaType(metadataIdentificationString); final List<Identifier> identifierServiceResult = getIdentifiersForType(javaType); final LogicalPath path = PhysicalTypeIdentifierNamingUtils.getPath(metadataIdentificationString); if (projectOperations.isProjectAvailable(path.getModule())) { // If the project itself changes, we want a chance to refresh this // item getMetadataDependencyRegistry().registerDependency( ProjectMetadata.getProjectIdentifier(path.getModule()), metadataIdentificationString); } return new IdentifierMetadata(metadataIdentificationString, aspectName, governorPhysicalTypeMetadata, annotationValues, identifierServiceResult); } public String getProvidesType() { return IdentifierMetadata.getMetadataIdentifierType(); } protected ProjectOperations getProjectOperations() { // Get all Services implement ProjectOperations interface try { ServiceReference<?>[] references = context.getAllServiceReferences(ProjectOperations.class.getName(), null); for (ServiceReference<?> ref : references) { return (ProjectOperations) context.getService(ref); } return null; } catch (InvalidSyntaxException e) { LOGGER.warning("Cannot load ProjectOperations on IdentifierMetadataProviderImpl."); return null; } } }