package org.springframework.roo.addon.solr; import static org.springframework.roo.model.RooJavaType.ROO_SOLR_SEARCHABLE; import java.util.LinkedHashMap; import java.util.Map; 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.jpa.activerecord.JpaActiveRecordMetadata; import org.springframework.roo.addon.jpa.activerecord.JpaActiveRecordMetadataProvider; import org.springframework.roo.addon.plural.PluralMetadata; import org.springframework.roo.classpath.PhysicalTypeIdentifier; import org.springframework.roo.classpath.PhysicalTypeIdentifierNamingUtils; import org.springframework.roo.classpath.PhysicalTypeMetadata; import org.springframework.roo.classpath.details.BeanInfoUtils; import org.springframework.roo.classpath.details.FieldMetadata; import org.springframework.roo.classpath.details.ItdTypeDetails; import org.springframework.roo.classpath.details.MethodMetadata; import org.springframework.roo.classpath.itd.AbstractMemberDiscoveringItdMetadataProvider; import org.springframework.roo.classpath.itd.ItdTypeDetailsProvidingMetadataItem; import org.springframework.roo.classpath.scanner.MemberDetails; import org.springframework.roo.metadata.MetadataIdentificationUtils; import org.springframework.roo.model.JavaType; import org.springframework.roo.project.LogicalPath; /** * Provides {@link SolrMetadata}. * * @author Stefan Schmidt * @since 1.1 */ @Component(immediate = true) @Service public class SolrMetadataProvider extends AbstractMemberDiscoveringItdMetadataProvider { @Reference private JpaActiveRecordMetadataProvider jpaActiveRecordMetadataProvider; protected void activate(final ComponentContext context) { metadataDependencyRegistry.registerDependency( PhysicalTypeIdentifier.getMetadataIdentiferType(), getProvidesType()); jpaActiveRecordMetadataProvider.addMetadataTrigger(ROO_SOLR_SEARCHABLE); addMetadataTrigger(ROO_SOLR_SEARCHABLE); } @Override protected String createLocalIdentifier(final JavaType javaType, final LogicalPath path) { return SolrMetadata.createIdentifier(javaType, path); } protected void deactivate(final ComponentContext context) { metadataDependencyRegistry.deregisterDependency( PhysicalTypeIdentifier.getMetadataIdentiferType(), getProvidesType()); jpaActiveRecordMetadataProvider .removeMetadataTrigger(ROO_SOLR_SEARCHABLE); removeMetadataTrigger(ROO_SOLR_SEARCHABLE); } @Override protected String getGovernorPhysicalTypeIdentifier( final String metadataIdentificationString) { final JavaType javaType = SolrMetadata .getJavaType(metadataIdentificationString); final LogicalPath path = SolrMetadata .getPath(metadataIdentificationString); return PhysicalTypeIdentifier.createIdentifier(javaType, path); } public String getItdUniquenessFilenameSuffix() { return "SolrSearch"; } @Override protected String getLocalMidToRequest(final ItdTypeDetails itdTypeDetails) { // Determine if this ITD presents a method we're interested in (namely // accessors) for (final MethodMetadata method : itdTypeDetails.getDeclaredMethods()) { if (BeanInfoUtils.isAccessorMethod(method) && !method.getMethodName().getSymbolName().startsWith("is")) { // We care about this ITD, so formally request an update so we // can scan for it and process it // Determine the governor for this ITD, and the Path the ITD is // stored within final JavaType governorType = itdTypeDetails.getName(); final String providesType = MetadataIdentificationUtils .getMetadataClass(itdTypeDetails .getDeclaredByMetadataId()); final LogicalPath itdPath = PhysicalTypeIdentifierNamingUtils .getPath(providesType, itdTypeDetails.getDeclaredByMetadataId()); // Produce the local MID we're going to use and make the request return createLocalIdentifier(governorType, itdPath); } } return null; } @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 SolrSearchAnnotationValues annotationValues = new SolrSearchAnnotationValues( governorPhysicalTypeMetadata); if (!annotationValues.isAnnotationFound() || annotationValues.searchMethod == null) { return null; } // Acquire bean info (we need getters details, specifically) final JavaType javaType = SolrMetadata .getJavaType(metadataIdentificationString); final LogicalPath path = SolrMetadata .getPath(metadataIdentificationString); final String jpaActiveRecordMetadataKey = JpaActiveRecordMetadata .createIdentifier(javaType, path); // We want to be notified if the getter info changes in any way metadataDependencyRegistry.registerDependency( jpaActiveRecordMetadataKey, metadataIdentificationString); final JpaActiveRecordMetadata jpaActiveRecordMetadata = (JpaActiveRecordMetadata) metadataService .get(jpaActiveRecordMetadataKey); // Abort if we don't have getter information available if (jpaActiveRecordMetadata == null || !jpaActiveRecordMetadata.isValid()) { return null; } // Otherwise go off and create the Solr metadata String beanPlural = javaType.getSimpleTypeName() + "s"; final PluralMetadata pluralMetadata = (PluralMetadata) metadataService .get(PluralMetadata.createIdentifier(javaType, path)); if (pluralMetadata != null && pluralMetadata.isValid()) { beanPlural = pluralMetadata.getPlural(); } final MemberDetails memberDetails = getMemberDetails(governorPhysicalTypeMetadata); final Map<MethodMetadata, FieldMetadata> accessorDetails = new LinkedHashMap<MethodMetadata, FieldMetadata>(); for (final MethodMetadata method : memberDetails.getMethods()) { if (BeanInfoUtils.isAccessorMethod(method) && !method.getMethodName().getSymbolName().startsWith("is")) { final FieldMetadata field = BeanInfoUtils .getFieldForJavaBeanMethod(memberDetails, method); if (field != null) { accessorDetails.put(method, field); } // Track any changes to that method (eg it goes away) metadataDependencyRegistry.registerDependency( method.getDeclaredByMetadataId(), metadataIdentificationString); } } final MethodMetadata identifierAccessor = persistenceMemberLocator .getIdentifierAccessor(javaType); if (identifierAccessor == null) { return null; } final FieldMetadata versionField = persistenceMemberLocator .getVersionField(javaType); return new SolrMetadata(metadataIdentificationString, aspectName, annotationValues, governorPhysicalTypeMetadata, identifierAccessor, versionField, accessorDetails, beanPlural); } public String getProvidesType() { return SolrMetadata.getMetadataIdentiferType(); } }