Package org.springframework.roo.addon.layers.repository.mongo

Source Code of org.springframework.roo.addon.layers.repository.mongo.MongoEntityMetadata

package org.springframework.roo.addon.layers.repository.mongo;

import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

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.BeanInfoUtils;
import org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetails;
import org.springframework.roo.classpath.details.FieldMetadata;
import org.springframework.roo.classpath.details.FieldMetadataBuilder;
import org.springframework.roo.classpath.details.MethodMetadata;
import org.springframework.roo.classpath.details.MethodMetadataBuilder;
import org.springframework.roo.classpath.details.annotations.AnnotatedJavaType;
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.scanner.MemberDetails;
import org.springframework.roo.metadata.MetadataIdentificationUtils;
import org.springframework.roo.model.JavaSymbolName;
import org.springframework.roo.model.JavaType;
import org.springframework.roo.model.SpringJavaType;
import org.springframework.roo.project.LogicalPath;

/**
* Creates metadata for domain entity ITDs (annotated with
* {@link RooMongoEntity}.
*
* @author Stefan Schmidt
* @since 1.2.0
*/
public class MongoEntityMetadata extends
        AbstractItdTypeDetailsProvidingMetadataItem {

    private static final String PROVIDES_TYPE_STRING = MongoEntityMetadata.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);
    }

    private MemberDetails memberDetails;
    private MongoEntityMetadata parent;
    private JavaType idType;
    private FieldMetadata idField;

    /**
     * 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 parent
     * @param idType the type of the entity's identifier field (required)
     * @param governorMemberDetails the member details of the entity
     */
    public MongoEntityMetadata(final String identifier,
            final JavaType aspectName,
            final PhysicalTypeMetadata governorPhysicalTypeMetadata,
            MongoEntityMetadata parent, final JavaType idType,
            final MemberDetails memberDetails) {
        super(identifier, aspectName, governorPhysicalTypeMetadata);
        Validate.notNull(idType, "Id type required");
        Validate.notNull(memberDetails, "Entity MemberDetails required");

        if (!isValid()) {
            return;
        }

        this.memberDetails = memberDetails;
        this.parent = parent;
        this.idType = idType;

        builder.addAnnotation(getTypeAnnotation(SpringJavaType.PERSISTENT));

        idField = getIdentifierField();
        if (idField != null) {
            builder.addField(idField);
            builder.addMethod(getIdentifierAccessor());
            builder.addMethod(getIdentifierMutator());
        }

        // Build the ITD
        itdTypeDetails = builder.build();
    }

    private MethodMetadataBuilder getIdentifierAccessor() {
        if (parent != null) {
            final MethodMetadataBuilder parentIdAccessor = parent
                    .getIdentifierAccessor();
            if (parentIdAccessor != null
                    && parentIdAccessor.getReturnType().equals(idType)) {
                return parentIdAccessor;
            }
        }

        JavaSymbolName requiredAccessorName = BeanInfoUtils
                .getAccessorMethodName(idField);

        // See if the user provided the field
        if (!getId().equals(idField.getDeclaredByMetadataId())) {
            // Locate an existing accessor
            final MethodMetadata method = memberDetails.getMethod(
                    requiredAccessorName, new ArrayList<JavaType>());
            if (method != null) {
                if (Modifier.isPublic(method.getModifier())) {
                    // Method exists and is public so return it
                    return new MethodMetadataBuilder(method);
                }

                // Method is not public so make the required accessor name
                // unique
                requiredAccessorName = new JavaSymbolName(
                        requiredAccessorName.getSymbolName() + "_");
            }
        }

        // We declared the field in this ITD, so produce a public accessor for
        // it
        final InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder();
        bodyBuilder.appendFormalLine("return this."
                + idField.getFieldName().getSymbolName() + ";");

        return new MethodMetadataBuilder(getId(), Modifier.PUBLIC,
                requiredAccessorName, idField.getFieldType(), bodyBuilder);
    }

    private FieldMetadata getIdentifierField() {
        if (parent != null) {
            final FieldMetadata parentIdField = parent.getIdentifierField();
            if (parentIdField.getFieldType().equals(idType)) {
                return parentIdField;
            }
        }

        // Try to locate an existing field with DATA_ID
        final List<FieldMetadata> idFields = governorTypeDetails
                .getFieldsWithAnnotation(SpringJavaType.DATA_ID);
        if (!idFields.isEmpty()) {
            return idFields.get(0);
        }
        final JavaSymbolName idFieldName = governorTypeDetails
                .getUniqueFieldName("id");
        final FieldMetadataBuilder fieldBuilder = new FieldMetadataBuilder(
                getId(), Modifier.PRIVATE, idFieldName, idType, null);
        fieldBuilder.addAnnotation(new AnnotationMetadataBuilder(
                SpringJavaType.DATA_ID));
        return fieldBuilder.build();
    }

    private MethodMetadataBuilder getIdentifierMutator() {
        if (parent != null) {
            final MethodMetadataBuilder parentIdMutator = parent
                    .getIdentifierMutator();
            if (parentIdMutator != null
                    && parentIdMutator.getParameterTypes().get(0).getJavaType()
                            .equals(idType)) {
                return parentIdMutator;
            }
        }

        JavaSymbolName requiredMutatorName = BeanInfoUtils
                .getMutatorMethodName(idField);

        final List<JavaType> parameterTypes = Arrays.asList(idField
                .getFieldType());
        final List<JavaSymbolName> parameterNames = Arrays
                .asList(new JavaSymbolName("id"));

        // See if the user provided the field
        if (!getId().equals(idField.getDeclaredByMetadataId())) {
            // Locate an existing mutator
            final MethodMetadata method = memberDetails.getMethod(
                    requiredMutatorName, parameterTypes);
            if (method != null) {
                if (Modifier.isPublic(method.getModifier())) {
                    // Method exists and is public so return it
                    return new MethodMetadataBuilder(method);
                }

                // Method is not public so make the required mutator name unique
                requiredMutatorName = new JavaSymbolName(
                        requiredMutatorName.getSymbolName() + "_");
            }
        }

        // We declared the field in this ITD, so produce a public mutator for it
        final InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder();
        bodyBuilder.appendFormalLine("this."
                + idField.getFieldName().getSymbolName() + " = id;");

        return new MethodMetadataBuilder(getId(), Modifier.PUBLIC,
                requiredMutatorName, JavaType.VOID_PRIMITIVE,
                AnnotatedJavaType.convertFromJavaTypes(parameterTypes),
                parameterNames, bodyBuilder);
    }

    @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();
    }
}
TOP

Related Classes of org.springframework.roo.addon.layers.repository.mongo.MongoEntityMetadata

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.