package org.springframework.roo.addon.layers.repository.jpa.addon.test;
import static org.springframework.roo.model.RooJavaType.ROO_REPOSITORY_JPA_INTEGRATION_TEST;
import java.util.Set;
import org.apache.commons.lang3.Validate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;
import org.osgi.service.component.ComponentContext;
import org.springframework.roo.addon.jpa.addon.entity.JpaEntityMetadata;
import org.springframework.roo.addon.layers.repository.jpa.addon.RepositoryJpaMetadata;
import org.springframework.roo.addon.plural.addon.PluralService;
import org.springframework.roo.classpath.PhysicalTypeIdentifier;
import org.springframework.roo.classpath.PhysicalTypeMetadata;
import org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetails;
import org.springframework.roo.classpath.details.ItdTypeDetails;
import org.springframework.roo.classpath.itd.AbstractMemberDiscoveringItdMetadataProvider;
import org.springframework.roo.classpath.itd.ItdTypeDetailsProvidingMetadataItem;
import org.springframework.roo.classpath.persistence.PersistenceMemberLocator;
import org.springframework.roo.metadata.MetadataDependencyRegistry;
import org.springframework.roo.metadata.internal.MetadataDependencyRegistryTracker;
import org.springframework.roo.model.JavaSymbolName;
import org.springframework.roo.model.JavaType;
import org.springframework.roo.model.RooJavaType;
import org.springframework.roo.project.LogicalPath;
/**
* Implementation of {@link RepositoryJpaIntegrationTestMetadataProvider}.
*
* @author Sergio Clares
* @since 2.0
*/
@Component
@Service
public class RepositoryJpaIntegrationTestMetadataProviderImpl extends
AbstractMemberDiscoveringItdMetadataProvider implements
RepositoryJpaIntegrationTestMetadataProvider {
protected MetadataDependencyRegistryTracker registryTracker = null;
/**
* This service is being activated so setup it:
* <ul>
* <li>Create and open the {@link MetadataDependencyRegistryTracker}.</li>
* <li>Registers {@link RooJavaType#ROO_REPOSITORY_JPA_INTEGRATION_TEST} as
* additional JavaType that will trigger metadata registration.</li>
* </ul>
*/
@Override
protected void activate(final ComponentContext cContext) {
super.activate(cContext);
this.registryTracker =
new MetadataDependencyRegistryTracker(cContext.getBundleContext(), this,
PhysicalTypeIdentifier.getMetadataIdentiferType(), getProvidesType());
this.registryTracker.open();
addMetadataTrigger(ROO_REPOSITORY_JPA_INTEGRATION_TEST);
}
/**
* 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.removeNotificationListener(this);
registry.deregisterDependency(PhysicalTypeIdentifier.getMetadataIdentiferType(),
getProvidesType());
this.registryTracker.close();
removeMetadataTrigger(ROO_REPOSITORY_JPA_INTEGRATION_TEST);
}
@Override
protected String createLocalIdentifier(final JavaType javaType, final LogicalPath path) {
return RepositoryJpaIntegrationTestMetadata.createIdentifier(javaType, path);
}
@Override
protected String getGovernorPhysicalTypeIdentifier(final String metadataIdentificationString) {
final JavaType javaType =
RepositoryJpaIntegrationTestMetadata.getJavaType(metadataIdentificationString);
final LogicalPath path =
RepositoryJpaIntegrationTestMetadata.getPath(metadataIdentificationString);
return PhysicalTypeIdentifier.createIdentifier(javaType, path);
}
@Override
protected String getLocalMidToRequest(final ItdTypeDetails itdTypeDetails) {
return getLocalMid(itdTypeDetails);
}
@Override
public String getItdUniquenessFilenameSuffix() {
return "RepositoryJpaIntegrationTest";
}
@Override
protected ItdTypeDetailsProvidingMetadataItem getMetadata(
final String metadataIdentificationString, final JavaType aspectName,
final PhysicalTypeMetadata governorPhysicalTypeMetadata, final String itdFilename) {
final RepositoryJpaIntegrationTestAnnotationValues annotationValues =
new RepositoryJpaIntegrationTestAnnotationValues(governorPhysicalTypeMetadata);
// Find SpringJpaDataDetachableConfiguration class
Set<JavaType> jpaConfigurationClasses =
getTypeLocationService().findTypesWithAnnotation(
RooJavaType.ROO_JPA_REPOSITORY_CONFIGURATION);
Validate
.isTrue(
!jpaConfigurationClasses.isEmpty(),
"Couldn't find the 'SpringDataJpaDetachableRepositoryConfiguration' on the project for '%s'",
this.getClass().getName());
JavaType jpaDetachableRepositoryClass = jpaConfigurationClasses.iterator().next();
// Get repository metadata
JavaType repositoryInterface = annotationValues.getTargetClass();
ClassOrInterfaceTypeDetails repositoryDetails =
getTypeLocationService().getTypeDetails(repositoryInterface);
Validate.notNull(repositoryDetails.getAnnotation(RooJavaType.ROO_REPOSITORY_JPA),
"Couldn't find @RooJpaRepository in '%s'", repositoryInterface.getSimpleTypeName());
String repositoryMetadataId = RepositoryJpaMetadata.createIdentifier(repositoryDetails);
RepositoryJpaMetadata repositoryMetadata = getMetadataService().get(repositoryMetadataId);
if (repositoryMetadata == null) {
return null;
}
// Get entity identifier info
JavaType entity = repositoryMetadata.getEntity();
JavaType identifierType = getPersistenceMemberLocator().getIdentifierType(entity);
JavaSymbolName identifierAccessorMethodName =
getPersistenceMemberLocator().getIdentifierAccessor(entity).getMethodName();
// Get entity metadata
ClassOrInterfaceTypeDetails entityDetails = getTypeLocationService().getTypeDetails(entity);
String jpaEntityMetadataId = JpaEntityMetadata.createIdentifier(entityDetails);
JpaEntityMetadata jpaEntityMetadata = getMetadataService().get(jpaEntityMetadataId);
if (jpaEntityMetadata == null) {
return null;
}
// Get entity read only
boolean isReadOnly = jpaEntityMetadata.isReadOnly();
// Get entity plural
String entityPlural = getPluralService().getPlural(entity);
// Get repository default return type
JavaType defaultReturnType = repositoryMetadata.getDefaultReturnType();
return new RepositoryJpaIntegrationTestMetadata(metadataIdentificationString, aspectName,
governorPhysicalTypeMetadata, annotationValues, jpaDetachableRepositoryClass,
identifierType, identifierAccessorMethodName, entityPlural, entity, defaultReturnType,
isReadOnly);
}
public String getProvidesType() {
return RepositoryJpaIntegrationTestMetadata.getMetadataIdentiferType();
}
protected PersistenceMemberLocator getPersistenceMemberLocator() {
return this.serviceManager.getServiceInstance(this, PersistenceMemberLocator.class);
}
protected PluralService getPluralService() {
return this.serviceManager.getServiceInstance(this, PluralService.class);
}
}