package org.springframework.roo.addon.layers.repository.jpa.addon; 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.osgi.service.component.ComponentContext; import org.springframework.roo.classpath.MetadataLocatorUtils; import org.springframework.roo.classpath.TypeLocationService; import org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetails; import org.springframework.roo.classpath.details.DefaultPhysicalTypeMetadata; import org.springframework.roo.metadata.MetadataDependencyRegistry; import org.springframework.roo.metadata.MetadataService; import org.springframework.roo.model.JavaType; import org.springframework.roo.model.RooJavaType; import java.util.Collection; /** * The {@link RepositoryJpaLocator} implementation. * * @author Stefan Schmidt * @author Andrew Swan * @author Jose Manuel Vivó * @since 1.2.0 */ @Component @Service public class RepositoryJpaLocatorImpl implements RepositoryJpaLocator { @Reference private TypeLocationService typeLocationService; @Reference private MetadataDependencyRegistry dependencyRegistry; @Reference private MetadataService metadataService; private MetadataLocatorUtils<JavaType> util; protected void activate(final ComponentContext cContext) { util = new MetadataLocatorUtils<JavaType>(new Evaluator(typeLocationService)); dependencyRegistry.addNotificationListener(util); } public Collection<ClassOrInterfaceTypeDetails> getRepositories(final JavaType domainType) { return util.getValue(domainType, RooJavaType.ROO_REPOSITORY_JPA); } @Override public ClassOrInterfaceTypeDetails getRepository(JavaType domainType) { Validate.notNull(domainType, "domainType is required"); Collection<ClassOrInterfaceTypeDetails> repositories = getRepositories(domainType); if (repositories.isEmpty()) { return null; } else if (repositories.size() > 1) { throw new IllegalStateException("Found " + repositories.size() + " repositories for " + domainType.getFullyQualifiedTypeName()); } return repositories.iterator().next(); } @Override public RepositoryJpaMetadata getRepositoryMetadata(JavaType domainType) { ClassOrInterfaceTypeDetails repository = getRepository(domainType); return metadataService.get(RepositoryJpaMetadata.createIdentifier(repository)); } @Override public ClassOrInterfaceTypeDetails getFirstRepository(JavaType domainType) { Validate.notNull(domainType, "domainType is required"); Collection<ClassOrInterfaceTypeDetails> repositories = getRepositories(domainType); if (repositories.isEmpty()) { return null; } return repositories.iterator().next(); } @Override public RepositoryJpaMetadata getFirstRepositoryMetadata(JavaType domainType) { ClassOrInterfaceTypeDetails repository = getFirstRepository(domainType); return metadataService.get(RepositoryJpaMetadata.createIdentifier(repository)); } private class Evaluator extends MetadataLocatorUtils.LocatorEvaluatorByAnnotation { public Evaluator(TypeLocationService typeLocationService) { super(typeLocationService); } @Override public boolean evaluateForKey(JavaType key, ClassOrInterfaceTypeDetails valueToEvalueate, JavaType context) { final RepositoryJpaAnnotationValues annotationValues = new RepositoryJpaAnnotationValues(new DefaultPhysicalTypeMetadata( valueToEvalueate.getDeclaredByMetadataId(), typeLocationService.getPhysicalTypeCanonicalPath(valueToEvalueate .getDeclaredByMetadataId()), valueToEvalueate)); return annotationValues.getEntity() != null && annotationValues.getEntity().equals(key); } @Override public JavaType evalueteForEvict(String streamDependency) { if (RepositoryJpaMetadata.isValid(streamDependency)) { return RepositoryJpaMetadata.getJavaType(streamDependency); } return null; } } }