package org.springframework.roo.addon.layers.repository.mongo; import static org.springframework.roo.classpath.customdata.CustomDataKeys.IDENTIFIER_ACCESSOR_METHOD; import static org.springframework.roo.classpath.customdata.CustomDataKeys.IDENTIFIER_FIELD; import static org.springframework.roo.classpath.customdata.CustomDataKeys.IDENTIFIER_MUTATOR_METHOD; import static org.springframework.roo.classpath.customdata.CustomDataKeys.PERSISTENT_TYPE; import static org.springframework.roo.model.RooJavaType.ROO_MONGO_ENTITY; import java.util.Arrays; 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.PhysicalTypeIdentifier; import org.springframework.roo.classpath.PhysicalTypeMetadata; import org.springframework.roo.classpath.customdata.taggers.AnnotatedTypeMatcher; import org.springframework.roo.classpath.customdata.taggers.CustomDataKeyDecorator; import org.springframework.roo.classpath.customdata.taggers.FieldMatcher; import org.springframework.roo.classpath.customdata.taggers.MethodMatcher; import org.springframework.roo.classpath.details.MemberFindingUtils; import org.springframework.roo.classpath.details.annotations.AnnotationMetadataBuilder; import org.springframework.roo.classpath.itd.AbstractItdMetadataProvider; import org.springframework.roo.classpath.itd.ItdTypeDetailsProvidingMetadataItem; import org.springframework.roo.classpath.scanner.MemberDetails; import org.springframework.roo.model.JavaType; import org.springframework.roo.model.SpringJavaType; import org.springframework.roo.project.LogicalPath; /** * Implementation of {@link MongoEntityMetadataProvider}. * * @author Stefan Schmidt * @since 1.2.0 */ @Component(immediate = true) @Service public class MongoEntityMetadataProviderImpl extends AbstractItdMetadataProvider implements MongoEntityMetadataProvider { private static final FieldMatcher ID_FIELD_MATCHER = new FieldMatcher( IDENTIFIER_FIELD, AnnotationMetadataBuilder.getInstance(SpringJavaType.DATA_ID .getFullyQualifiedTypeName())); private static final MethodMatcher ID_ACCESSOR_MATCHER = new MethodMatcher( Arrays.asList(ID_FIELD_MATCHER), IDENTIFIER_ACCESSOR_METHOD, true); private static final MethodMatcher ID_MUTATOR_MATCHER = new MethodMatcher( Arrays.asList(ID_FIELD_MATCHER), IDENTIFIER_MUTATOR_METHOD, false); private static final AnnotatedTypeMatcher PERSISTENT_TYPE_MATCHER = new AnnotatedTypeMatcher( PERSISTENT_TYPE, ROO_MONGO_ENTITY); @Reference private CustomDataKeyDecorator customDataKeyDecorator; @SuppressWarnings("unchecked") protected void activate(final ComponentContext context) { super.setDependsOnGovernorBeingAClass(false); metadataDependencyRegistry.registerDependency( PhysicalTypeIdentifier.getMetadataIdentiferType(), getProvidesType()); addMetadataTrigger(ROO_MONGO_ENTITY); customDataKeyDecorator.registerMatchers(getClass(), PERSISTENT_TYPE_MATCHER, ID_FIELD_MATCHER, ID_ACCESSOR_MATCHER, ID_MUTATOR_MATCHER); } @Override protected String createLocalIdentifier(final JavaType javaType, final LogicalPath path) { return MongoEntityMetadata.createIdentifier(javaType, path); } protected void deactivate(final ComponentContext context) { metadataDependencyRegistry.deregisterDependency( PhysicalTypeIdentifier.getMetadataIdentiferType(), getProvidesType()); removeMetadataTrigger(ROO_MONGO_ENTITY); customDataKeyDecorator.unregisterMatchers(getClass()); } @Override protected String getGovernorPhysicalTypeIdentifier( final String metadataIdentificationString) { final JavaType javaType = MongoEntityMetadata .getJavaType(metadataIdentificationString); final LogicalPath path = MongoEntityMetadata .getPath(metadataIdentificationString); return PhysicalTypeIdentifier.createIdentifier(javaType, path); } public String getItdUniquenessFilenameSuffix() { return "Mongo_Entity"; } @Override protected ItdTypeDetailsProvidingMetadataItem getMetadata( final String metadataIdentificationString, final JavaType aspectName, final PhysicalTypeMetadata governorPhysicalType, final String itdFilename) { final MongoEntityAnnotationValues annotationValues = new MongoEntityAnnotationValues( governorPhysicalType); final JavaType identifierType = annotationValues.getIdentifierType(); if (!annotationValues.isAnnotationFound() || identifierType == null) { return null; } // Get the governor's member details final MemberDetails memberDetails = getMemberDetails(governorPhysicalType); if (memberDetails == null) { return null; } final MongoEntityMetadata parent = getParentMetadata(governorPhysicalType .getMemberHoldingTypeDetails()); // If the parent is null, but the type has a super class it is likely // that the we don't have information to proceed if (parent == null && governorPhysicalType.getMemberHoldingTypeDetails() .getSuperclass() != null) { // If the superclass is not annotated with the RooMongoEntity // trigger // annotation then we can be pretty sure that we don't have enough // information to proceed if (MemberFindingUtils.getAnnotationOfType(governorPhysicalType .getMemberHoldingTypeDetails().getAnnotations(), ROO_MONGO_ENTITY) != null) { return null; } } return new MongoEntityMetadata(metadataIdentificationString, aspectName, governorPhysicalType, parent, identifierType, memberDetails); } public String getProvidesType() { return MongoEntityMetadata.getMetadataIdentiferType(); } }