Package org.springframework.roo.addon.layers.service

Source Code of org.springframework.roo.addon.layers.service.ServiceClassMetadataProvider

package org.springframework.roo.addon.layers.service;

import java.util.Collection;
import java.util.HashMap;
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.plural.PluralMetadata;
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.details.MemberHoldingTypeDetails;
import org.springframework.roo.classpath.itd.AbstractMemberDiscoveringItdMetadataProvider;
import org.springframework.roo.classpath.itd.ItdTypeDetailsProvidingMetadataItem;
import org.springframework.roo.classpath.layers.LayerService;
import org.springframework.roo.classpath.layers.LayerType;
import org.springframework.roo.classpath.layers.MemberTypeAdditions;
import org.springframework.roo.classpath.layers.MethodParameter;
import org.springframework.roo.classpath.scanner.MemberDetails;
import org.springframework.roo.model.JavaType;
import org.springframework.roo.process.manager.FileManager;
import org.springframework.roo.project.LogicalPath;
import org.springframework.roo.project.ProjectOperations;

/**
* Provides {@link ServiceClassMetadata} for building the ITD for the
* implementation class of a user project's service.
*
* @author Stefan Schmidt
* @author Andrew Swan
* @since 1.2.0
*/
@Component(immediate = true)
@Service
public class ServiceClassMetadataProvider extends
        AbstractMemberDiscoveringItdMetadataProvider {

    private static final int LAYER_POSITION = LayerType.SERVICE.getPosition();

    @Reference ProjectOperations projectOperations;
    @Reference FileManager fileManager;
    @Reference ServiceLayerTemplateService templateService;

    @Reference private LayerService layerService;

    private final Map<JavaType, String> managedEntityTypes = new HashMap<JavaType, String>();

    protected void activate(final ComponentContext context) {
        metadataDependencyRegistry.addNotificationListener(this);
        metadataDependencyRegistry.registerDependency(
                PhysicalTypeIdentifier.getMetadataIdentiferType(),
                getProvidesType());
        setIgnoreTriggerAnnotations(true);
    }

    @Override
    protected String createLocalIdentifier(final JavaType javaType,
            final LogicalPath path) {
        return ServiceClassMetadata.createIdentifier(javaType, path);
    }

    protected void deactivate(final ComponentContext context) {
        metadataDependencyRegistry.removeNotificationListener(this);
        metadataDependencyRegistry.deregisterDependency(
                PhysicalTypeIdentifier.getMetadataIdentiferType(),
                getProvidesType());
    }

    @Override
    protected String getGovernorPhysicalTypeIdentifier(
            final String metadataIdentificationString) {
        final JavaType javaType = ServiceClassMetadata
                .getJavaType(metadataIdentificationString);
        final LogicalPath path = ServiceClassMetadata
                .getPath(metadataIdentificationString);
        return PhysicalTypeIdentifier.createIdentifier(javaType, path);
    }

    public String getItdUniquenessFilenameSuffix() {
        return "Service";
    }

    @Override
    protected String getLocalMidToRequest(final ItdTypeDetails itdTypeDetails) {
        // Determine the governor for this ITD, and whether any metadata is even
        // hoping to hear about changes to that JavaType and its ITDs
        final JavaType governor = itdTypeDetails.getName();
        final String localMid = managedEntityTypes.get(governor);
        if (localMid != null) {
            return localMid;
        }

        final MemberHoldingTypeDetails memberHoldingTypeDetails = typeLocationService
                .getTypeDetails(governor);
        if (memberHoldingTypeDetails != null) {
            for (final JavaType type : memberHoldingTypeDetails
                    .getLayerEntities()) {
                final String localMidType = managedEntityTypes.get(type);
                if (localMidType != null) {
                    return localMidType;
                }
            }
        }
        return null;
    }

    @Override
    protected ItdTypeDetailsProvidingMetadataItem getMetadata(
            final String metadataIdentificationString,
            final JavaType aspectName,
            final PhysicalTypeMetadata governorPhysicalTypeMetadata,
            final String itdFilename) {
        final ClassOrInterfaceTypeDetails serviceClass = governorPhysicalTypeMetadata
                .getMemberHoldingTypeDetails();
        if (serviceClass == null) {
            return null;
        }

        ServiceInterfaceMetadata serviceInterfaceMetadata = null;
        ClassOrInterfaceTypeDetails serviceInterface = null;
        for (final JavaType implementedType : serviceClass.getImplementsTypes()) {
            final ClassOrInterfaceTypeDetails potentialServiceInterfaceTypeDetails = typeLocationService
                    .getTypeDetails(implementedType);
            if (potentialServiceInterfaceTypeDetails != null) {
                final LogicalPath path = PhysicalTypeIdentifier
                        .getPath(potentialServiceInterfaceTypeDetails
                                .getDeclaredByMetadataId());
                final String implementedTypeId = ServiceInterfaceMetadata
                        .createIdentifier(implementedType, path);
                if ((serviceInterfaceMetadata = (ServiceInterfaceMetadata) metadataService
                        .get(implementedTypeId)) != null) {
                    // Found the metadata for the service interface
                    serviceInterface = potentialServiceInterfaceTypeDetails;
                    break;
                }
            }
        }
        if (serviceInterface == null || serviceInterfaceMetadata == null
                || !serviceInterfaceMetadata.isValid()) {
            return null;
        }

        // Register this provider for changes to the service interface // TODO
        // move this down in case we return null early below?
        metadataDependencyRegistry.registerDependency(
                serviceInterfaceMetadata.getId(), metadataIdentificationString);

        final ServiceAnnotationValues serviceAnnotationValues = serviceInterfaceMetadata
                .getServiceAnnotationValues();
        final JavaType[] domainTypes = serviceAnnotationValues.getDomainTypes();
        if (domainTypes == null) {
            return null;
        }

        /*
         * For each domain type, collect (1) the plural and (2) the additions to
         * make to the service class for calling a lower layer when implementing
         * each service layer method. We use LinkedHashMaps for the latter
         * nested map to ensure repeatable order of code generation.
         */
        final Map<JavaType, String> domainTypePlurals = new HashMap<JavaType, String>();
        final Map<JavaType, JavaType> domainTypeToIdTypeMap = new HashMap<JavaType, JavaType>();
        // Collect the additions for each method for each supported domain type
        final Map<JavaType, Map<ServiceLayerMethod, MemberTypeAdditions>> allCrudAdditions = new LinkedHashMap<JavaType, Map<ServiceLayerMethod, MemberTypeAdditions>>();
        for (final JavaType domainType : domainTypes) {

            final JavaType idType = persistenceMemberLocator
                    .getIdentifierType(domainType);
            if (idType == null) {
                return null;
            }
            domainTypeToIdTypeMap.put(domainType, idType);
            // Collect the plural for this domain type

            final ClassOrInterfaceTypeDetails domainTypeDetails = typeLocationService
                    .getTypeDetails(domainType);
            if (domainTypeDetails == null) {
                return null;
            }
            final LogicalPath path = PhysicalTypeIdentifier
                    .getPath(domainTypeDetails.getDeclaredByMetadataId());
            final String pluralId = PluralMetadata.createIdentifier(domainType,
                    path);
            final PluralMetadata pluralMetadata = (PluralMetadata) metadataService
                    .get(pluralId);
            if (pluralMetadata == null) {
                return null;
            }
            domainTypePlurals.put(domainType, pluralMetadata.getPlural());

            // Maintain a list of entities that are being handled by this layer
            managedEntityTypes.put(domainType, metadataIdentificationString);

            // Collect the additions the service class needs in order to invoke
            // each service layer method
            final Map<ServiceLayerMethod, MemberTypeAdditions> methodAdditions = new LinkedHashMap<ServiceLayerMethod, MemberTypeAdditions>();
            for (final ServiceLayerMethod method : ServiceLayerMethod.values()) {
                final Collection<MethodParameter> methodParameters = MethodParameter
                        .asList(method.getParameters(domainType, idType));
                final MemberTypeAdditions memberTypeAdditions = layerService
                        .getMemberTypeAdditions(metadataIdentificationString,
                                method.getKey(), domainType, idType,
                                LAYER_POSITION, methodParameters);
                if (memberTypeAdditions != null) {
                    // A lower layer implements this method
                    methodAdditions.put(method, memberTypeAdditions);
                }
            }
            allCrudAdditions.put(domainType, methodAdditions);

            // Register this provider for changes to the domain type or its
            // plural
            metadataDependencyRegistry.registerDependency(
                    domainTypeDetails.getDeclaredByMetadataId(),
                    metadataIdentificationString);
            metadataDependencyRegistry.registerDependency(pluralId,
                    metadataIdentificationString);
        }

        final MemberDetails serviceClassDetails = memberDetailsScanner
                .getMemberDetails(getClass().getName(), serviceClass);

        // Adds or removes service from XML configuration
        if (serviceAnnotationValues.useXmlConfiguration()) {
            templateService.addServiceToXmlConfiguration(serviceInterface,
                    serviceClass);
        }
        else {
            templateService.removeServiceFromXmlConfiguration(serviceInterface);
        }

        return new ServiceClassMetadata(metadataIdentificationString,
                aspectName, governorPhysicalTypeMetadata, serviceClassDetails,
                serviceAnnotationValues, domainTypeToIdTypeMap,
                allCrudAdditions, domainTypePlurals, serviceInterface.getName()
                        .getSimpleTypeName());

    }

    public String getProvidesType() {
        return ServiceClassMetadata.getMetadataIdentiferType();
    }
}
TOP

Related Classes of org.springframework.roo.addon.layers.service.ServiceClassMetadataProvider

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.