/addon-layers-service/src/main/java/org/springframework/roo/addon/layers/service/ServiceClassMetadata.java
http://github.com/SpringSource/spring-roo · Java · 168 lines · 125 code · 16 blank · 27 comment · 10 complexity · 3c6b814649b67ee95748eb6d2db62536 MD5 · raw file
- package org.springframework.roo.addon.layers.service;
- import static org.springframework.roo.model.SpringJavaType.SERVICE;
- import static org.springframework.roo.model.SpringJavaType.TRANSACTIONAL;
- import java.lang.reflect.Modifier;
- import java.util.Map;
- import java.util.Map.Entry;
- import org.apache.commons.lang3.Validate;
- import org.apache.commons.lang3.builder.ToStringBuilder;
- import org.springframework.roo.classpath.PhysicalTypeIdentifierNamingUtils;
- import org.springframework.roo.classpath.PhysicalTypeMetadata;
- import org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetails;
- import org.springframework.roo.classpath.details.MethodMetadataBuilder;
- import org.springframework.roo.classpath.details.annotations.AnnotatedJavaType;
- import org.springframework.roo.classpath.details.annotations.AnnotationMetadata;
- import org.springframework.roo.classpath.details.annotations.AnnotationMetadataBuilder;
- import org.springframework.roo.classpath.itd.AbstractItdTypeDetailsProvidingMetadataItem;
- import org.springframework.roo.classpath.itd.InvocableMemberBodyBuilder;
- import org.springframework.roo.classpath.layers.MemberTypeAdditions;
- import org.springframework.roo.classpath.scanner.MemberDetails;
- import org.springframework.roo.metadata.MetadataIdentificationUtils;
- import org.springframework.roo.model.JavaSymbolName;
- import org.springframework.roo.model.JavaType;
- import org.springframework.roo.project.LogicalPath;
- /**
- * @author Stefan Schmidt
- * @since 1.2.0
- */
- public class ServiceClassMetadata extends
- AbstractItdTypeDetailsProvidingMetadataItem {
- private static final String PROVIDES_TYPE_STRING = ServiceClassMetadata.class
- .getName();
- private static final String PROVIDES_TYPE = MetadataIdentificationUtils
- .create(PROVIDES_TYPE_STRING);
- public static String createIdentifier(final JavaType javaType,
- final LogicalPath path) {
- return PhysicalTypeIdentifierNamingUtils.createIdentifier(
- PROVIDES_TYPE_STRING, javaType, path);
- }
- public static JavaType getJavaType(final String metadataIdentificationString) {
- return PhysicalTypeIdentifierNamingUtils.getJavaType(
- PROVIDES_TYPE_STRING, metadataIdentificationString);
- }
- public static String getMetadataIdentiferType() {
- return PROVIDES_TYPE;
- }
- public static LogicalPath getPath(final String metadataIdentificationString) {
- return PhysicalTypeIdentifierNamingUtils.getPath(PROVIDES_TYPE_STRING,
- metadataIdentificationString);
- }
- public static boolean isValid(final String metadataIdentificationString) {
- return PhysicalTypeIdentifierNamingUtils.isValid(PROVIDES_TYPE_STRING,
- metadataIdentificationString);
- }
- /**
- * Constructor
- *
- * @param identifier the identifier for this item of metadata (required)
- * @param aspectName the Java type of the ITD (required)
- * @param governorPhysicalTypeMetadata the governor, which is expected to
- * contain a {@link ClassOrInterfaceTypeDetails} (required)
- * @param governorDetails (required)
- * @param annotationValues (required)
- * @param domainTypeToIdTypeMap (required)
- * @param allCrudAdditions any additions to be made to the service class in
- * order to invoke lower-layer methods (required)
- * @param domainTypePlurals the plurals of each domain type managed by the
- * service
- */
- public ServiceClassMetadata(
- final String identifier,
- final JavaType aspectName,
- final PhysicalTypeMetadata governorPhysicalTypeMetadata,
- final MemberDetails governorDetails,
- final ServiceAnnotationValues annotationValues,
- final Map<JavaType, JavaType> domainTypeToIdTypeMap,
- final Map<JavaType, Map<ServiceLayerMethod, MemberTypeAdditions>> allCrudAdditions,
- final Map<JavaType, String> domainTypePlurals) {
- super(identifier, aspectName, governorPhysicalTypeMetadata);
- Validate.notNull(allCrudAdditions, "CRUD additions required");
- Validate.notNull(annotationValues, "Annotation values required");
- Validate.notNull(governorDetails, "Governor details required");
- Validate.notNull(domainTypePlurals, "Domain type plurals required");
- for (final Entry<JavaType, JavaType> entry : domainTypeToIdTypeMap
- .entrySet()) {
- final JavaType domainType = entry.getKey();
- final JavaType idType = entry.getValue();
- final Map<ServiceLayerMethod, MemberTypeAdditions> crudAdditions = allCrudAdditions
- .get(domainType);
- for (final ServiceLayerMethod method : ServiceLayerMethod.values()) {
- final JavaSymbolName methodName = method.getSymbolName(
- annotationValues, domainType,
- domainTypePlurals.get(domainType));
- if (methodName != null
- && !governorDetails.isMethodDeclaredByAnother(
- methodName,
- method.getParameterTypes(domainType, idType),
- getId())) {
- // The method is desired and the service class' Java file
- // doesn't contain it, so generate it
- final MemberTypeAdditions lowerLayerCallAdditions = crudAdditions
- .get(method);
- if (lowerLayerCallAdditions != null) {
- // A lower layer implements it
- lowerLayerCallAdditions.copyAdditionsTo(builder,
- governorTypeDetails);
- }
- final String body = method.getBody(lowerLayerCallAdditions);
- final InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder();
- bodyBuilder.appendFormalLine(body);
- builder.addMethod(new MethodMetadataBuilder(getId(),
- Modifier.PUBLIC, methodName, method
- .getReturnType(domainType),
- AnnotatedJavaType.convertFromJavaTypes(method
- .getParameterTypes(domainType, idType)),
- method.getParameterNames(domainType, idType),
- bodyBuilder));
- }
- }
- }
- // Introduce the @Service annotation via the ITD if it's not already on
- // the service's Java class
- final AnnotationMetadata serviceAnnotation = new AnnotationMetadataBuilder(
- SERVICE).build();
- if (!governorDetails.isRequestingAnnotatedWith(serviceAnnotation,
- getId())) {
- builder.addAnnotation(serviceAnnotation);
- }
- // Introduce the @Transactional annotation via the ITD if it's not
- // already on the service's Java class
- if (annotationValues.isTransactional()) {
- final AnnotationMetadata transactionalAnnotation = new AnnotationMetadataBuilder(
- TRANSACTIONAL).build();
- if (!governorDetails.isRequestingAnnotatedWith(serviceAnnotation,
- getId())) {
- builder.addAnnotation(transactionalAnnotation);
- }
- }
- // Create a representation of the desired output ITD
- itdTypeDetails = builder.build();
- }
- @Override
- public String toString() {
- final ToStringBuilder builder = new ToStringBuilder(this);
- builder.append("identifier", getId());
- builder.append("valid", valid);
- builder.append("aspectName", aspectName);
- builder.append("destinationType", destination);
- builder.append("governor", governorPhysicalTypeMetadata.getId());
- builder.append("itdTypeDetails", itdTypeDetails);
- return builder.toString();
- }
- }