Package org.springframework.roo.classpath.itd

Source Code of org.springframework.roo.classpath.itd.AbstractItdTypeDetailsProvidingMetadataItem

package org.springframework.roo.classpath.itd;

import static java.lang.reflect.Modifier.PRIVATE;
import static java.lang.reflect.Modifier.PUBLIC;

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.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.ItdTypeDetails;
import org.springframework.roo.classpath.details.ItdTypeDetailsBuilder;
import org.springframework.roo.classpath.details.MemberFindingUtils;
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.AnnotationMetadata;
import org.springframework.roo.classpath.details.annotations.AnnotationMetadataBuilder;
import org.springframework.roo.metadata.AbstractMetadataItem;
import org.springframework.roo.model.JavaSymbolName;
import org.springframework.roo.model.JavaType;
import org.springframework.roo.model.JdkJavaType;

/**
* Abstract implementation of {@link ItdTypeDetailsProvidingMetadataItem}, which
* assumes the subclass will require a non-null
* {@link ClassOrInterfaceTypeDetails} representing the governor and wishes to
* build an ITD via the {@link ItdTypeDetailsBuilder} mechanism.
*
* @author Ben Alex
* @since 1.0
*/
public abstract class AbstractItdTypeDetailsProvidingMetadataItem extends
        AbstractMetadataItem implements ItdTypeDetailsProvidingMetadataItem {

    protected JavaType aspectName;
    protected ItdTypeDetailsBuilder builder;
    protected JavaType destination;
    protected PhysicalTypeMetadata governorPhysicalTypeMetadata;
    protected ClassOrInterfaceTypeDetails governorTypeDetails;
    protected ItdTypeDetails itdTypeDetails;

    /**
     * Validates input and constructs a superclass that implements
     * {@link ItdTypeDetailsProvidingMetadataItem}.
     * <p>
     * Exposes the {@link ClassOrInterfaceTypeDetails} of the governor, if
     * available. If they are not available, ensures {@link #isValid()} returns
     * false.
     * <p>
     * Subclasses should generally return immediately if {@link #isValid()} is
     * false. Subclasses should also attempt to set the {@link #itdTypeDetails}
     * to contain the output of their ITD where {@link #isValid()} is true.
     *
     * @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)
     */
    protected AbstractItdTypeDetailsProvidingMetadataItem(
            final String identifier, final JavaType aspectName,
            final PhysicalTypeMetadata governorPhysicalTypeMetadata) {
        super(identifier);
        Validate.notNull(aspectName, "Aspect name required");
        Validate.notNull(governorPhysicalTypeMetadata,
                "Governor physical type metadata required");

        this.aspectName = aspectName;
        this.governorPhysicalTypeMetadata = governorPhysicalTypeMetadata;

        final Object physicalTypeDetails = governorPhysicalTypeMetadata
                .getMemberHoldingTypeDetails();
        if (physicalTypeDetails instanceof ClassOrInterfaceTypeDetails) {
            // We have reliable physical type details
            governorTypeDetails = (ClassOrInterfaceTypeDetails) physicalTypeDetails;
        }
        else {
            // There is a problem
            valid = false;
        }

        destination = governorTypeDetails.getName();

        // Provide the subclass a builder, to make preparing an ITD even easier
        builder = new ItdTypeDetailsBuilder(getId(), governorTypeDetails,
                aspectName, true);
    }

    private void addToImports(final List<JavaType> parameterTypes) {
        if (parameterTypes != null) {
            final List<JavaType> typesToImport = new ArrayList<JavaType>();
            for (final JavaType parameterType : parameterTypes) {
                if (!JdkJavaType.isPartOfJavaLang(parameterType)) {
                    typesToImport.add(parameterType);
                }
            }
            builder.getImportRegistrationResolver().addImports(typesToImport);
        }
    }

    /**
     * Generates the {@link ItdTypeDetails} from the current contents of this
     * instance's {@link ItdTypeDetailsBuilder}.
     *
     * @since 1.2.0
     */
    protected void buildItd() {
        itdTypeDetails = builder.build();
    }

    /**
     * Ensures that the governor extends the given type, i.e. introduces that
     * type as a supertype iff it's not already one
     *
     * @param javaType the type to extend (required)
     * @since 1.2.0
     */
    protected final void ensureGovernorExtends(final JavaType javaType) {
        if (!governorTypeDetails.extendsType(javaType)) {
            builder.addExtendsTypes(javaType);
        }
    }

    /**
     * Ensures that the governor implements the given type.
     *
     * @param javaType the type to implement (required)
     * @since 1.2.0
     */
    protected final void ensureGovernorImplements(final JavaType javaType) {
        if (!governorTypeDetails.implementsType(javaType)) {
            builder.addImplementsType(javaType);
        }
    }

    protected MethodMetadataBuilder getAccessorMethod(final FieldMetadata field) {
        return getAccessorMethod(
                field,
                InvocableMemberBodyBuilder.getInstance().appendFormalLine(
                        "return " + field.getFieldName().getSymbolName() + ";"));
    }

    protected MethodMetadataBuilder getAccessorMethod(
            final FieldMetadata field,
            final InvocableMemberBodyBuilder bodyBuilder) {
        return getMethod(PUBLIC, BeanInfoUtils.getAccessorMethodName(field),
                field.getFieldType(), null, null, bodyBuilder);
    }

    protected MethodMetadataBuilder getAccessorMethod(
            final JavaSymbolName fieldName, final JavaType fieldType) {
        return getAccessorMethod(
                fieldName,
                fieldType,
                InvocableMemberBodyBuilder.getInstance().appendFormalLine(
                        "return " + fieldName + ";"));
    }

    protected MethodMetadataBuilder getAccessorMethod(
            final JavaSymbolName fieldName, final JavaType fieldType,
            final InvocableMemberBodyBuilder bodyBuilder) {
        return getMethod(PUBLIC,
                BeanInfoUtils.getAccessorMethodName(fieldName, fieldType),
                fieldType, null, null, bodyBuilder);
    }

    /**
     * Convenience method for returning a simple private field based on the
     * field name, type, and initializer.
     *
     * @param fieldName the field name
     * @param fieldType the field type
     * @param fieldInitializer the string to initialize the field with
     * @return null if the field exists on the governor, otherwise a new field
     *         with the given field name and type
     */
    protected FieldMetadataBuilder getField(final int modifier,
            final JavaSymbolName fieldName, final JavaType fieldType,
            final String fieldInitializer) {
        if (governorTypeDetails.getField(fieldName) != null) {
            return null;
        }

        addToImports(Arrays.asList(fieldType));
        return new FieldMetadataBuilder(getId(), modifier, fieldName,
                fieldType, fieldInitializer);
    }

    protected FieldMetadataBuilder getField(final JavaSymbolName fieldName,
            final JavaType fieldType) {
        return getField(PRIVATE, fieldName, fieldType, null);
    }

    /**
     * Returns the given method of the governor.
     *
     * @param methodName the name of the method for which to search
     * @param parameterTypes the method's parameter types
     * @return null if there was no such method
     * @see MemberFindingUtils#getDeclaredMethod(org.springframework.roo.classpath.details.MemberHoldingTypeDetails,
     *      JavaSymbolName, List)
     * @since 1.2.0
     */
    protected MethodMetadata getGovernorMethod(final JavaSymbolName methodName,
            final JavaType... parameterTypes) {
        return getGovernorMethod(methodName, Arrays.asList(parameterTypes));
    }

    /**
     * Returns the given method of the governor.
     *
     * @param methodName the name of the method for which to search
     * @param parameterTypes the method's parameter types
     * @return null if there was no such method
     * @see MemberFindingUtils#getDeclaredMethod(org.springframework.roo.classpath.details.MemberHoldingTypeDetails,
     *      JavaSymbolName, List)
     * @since 1.2.0 (previously called methodExists)
     */
    protected MethodMetadata getGovernorMethod(final JavaSymbolName methodName,
            final List<JavaType> parameterTypes) {
        return MemberFindingUtils.getDeclaredMethod(governorTypeDetails,
                methodName, parameterTypes);
    }

    public final ItdTypeDetails getMemberHoldingTypeDetails() {
        return itdTypeDetails;
    }

    /**
     * Returns a public method given the method name, return type, parameter
     * types, parameter names, and method body.
     *
     * @param methodName the method name
     * @param returnType the return type
     * @param parameterTypes a list of parameter types
     * @param parameterNames a list of parameter names
     * @param bodyBuilder the method body
     * @return null if the method exists on the governor, otherwise a new method
     *         is returned
     */
    protected MethodMetadataBuilder getMethod(final int modifier,
            final JavaSymbolName methodName, final JavaType returnType,
            final List<JavaType> parameterTypes,
            final List<JavaSymbolName> parameterNames,
            final InvocableMemberBodyBuilder bodyBuilder) {
        final MethodMetadata method = getGovernorMethod(methodName,
                parameterTypes);
        if (method != null) {
            return null;
        }

        addToImports(parameterTypes);
        return new MethodMetadataBuilder(getId(), modifier, methodName,
                returnType,
                AnnotatedJavaType.convertFromJavaTypes(parameterTypes),
                parameterNames, bodyBuilder);
    }

    protected MethodMetadataBuilder getMutatorMethod(
            final JavaSymbolName fieldName, final JavaType parameterType) {
        return getMutatorMethod(
                fieldName,
                parameterType,
                InvocableMemberBodyBuilder.getInstance().appendFormalLine(
                        "this." + fieldName.getSymbolName() + " = "
                                + fieldName.getSymbolName() + ";"));
    }

    protected MethodMetadataBuilder getMutatorMethod(
            final JavaSymbolName fieldName, final JavaType parameterType,
            final InvocableMemberBodyBuilder bodyBuilder) {
        return getMethod(PUBLIC, BeanInfoUtils.getMutatorMethodName(fieldName),
                JavaType.VOID_PRIMITIVE, Arrays.asList(parameterType),
                Arrays.asList(fieldName), bodyBuilder);
    }

    /**
     * Returns the metadata for an annotation of the given type if the governor
     * does not already have one.
     *
     * @param annotationType the type of annotation to generate (required)
     * @return <code>null</code> if the governor already has that annotation
     */
    protected AnnotationMetadata getTypeAnnotation(final JavaType annotationType) {
        if (governorTypeDetails.getAnnotation(annotationType) != null) {
            return null;
        }
        return new AnnotationMetadataBuilder(annotationType).build();
    }

    /**
     * Indicates whether the governor has a method with the given signature.
     *
     * @param methodName the name of the method for which to search
     * @param parameterTypes the method's parameter types
     * @return see above
     * @since 1.2.0
     */
    protected boolean governorHasMethod(final JavaSymbolName methodName,
            final JavaType... parameterTypes) {
        return getGovernorMethod(methodName, parameterTypes) != null;
    }

    /**
     * Indicates whether the governor has a method with the given signature.
     *
     * @param methodName the name of the method for which to search
     * @param parameterTypes the method's parameter types
     * @return see above
     * @since 1.2.1
     */
    protected boolean governorHasMethod(final JavaSymbolName methodName,
            final List<JavaType> parameterTypes) {
        return getGovernorMethod(methodName, parameterTypes) != null;
    }

    /**
     * Indicates whether the governor has a method with the given method name
     * regardless of method parameters.
     *
     * @param methodName the name of the method for which to search
     * @return see above
     * @since 1.2.0
     */
    protected boolean governorHasMethodWithSameName(
            final JavaSymbolName methodName) {
        return MemberFindingUtils.getDeclaredMethod(governorTypeDetails,
                methodName) != null;
    }

    @Override
    public int hashCode() {
        return builder.build().hashCode();
    }

    /**
     * Determines if the presented class (or any of its superclasses) implements
     * the target interface.
     *
     * @param clazz the cid to search
     * @param interfaceTarget the interface to locate
     * @return true if the class or any of its superclasses contains the
     *         specified interface
     */
    protected boolean isImplementing(final ClassOrInterfaceTypeDetails clazz,
            final JavaType interfaceTarget) {
        if (clazz.getImplementsTypes().contains(interfaceTarget)) {
            return true;
        }
        if (clazz.getSuperclass() != null) {
            return isImplementing(clazz.getSuperclass(), interfaceTarget);
        }
        return false;
    }

    @Override
    public String toString() {
        final ToStringBuilder builder = new ToStringBuilder(this);
        builder.append("identifier", getId());
        builder.append("valid", valid);
        builder.append("aspectName", aspectName);
        builder.append("governor", governorPhysicalTypeMetadata.getId());
        builder.append("itdTypeDetails", itdTypeDetails);
        return builder.toString();
    }
   
    /**
     * Return current aspect name
     * @return
     */
    public JavaType getAspectName() {
    return aspectName;
  }
}
TOP

Related Classes of org.springframework.roo.classpath.itd.AbstractItdTypeDetailsProvidingMetadataItem

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.