Package org.springframework.roo.classpath.operations

Source Code of org.springframework.roo.classpath.operations.ClasspathOperationsImpl

package org.springframework.roo.classpath.operations;

import static org.springframework.roo.model.JavaType.OBJECT;
import static org.springframework.roo.model.RooJavaType.ROO_EQUALS;
import static org.springframework.roo.model.RooJavaType.ROO_JAVA_BEAN;
import static org.springframework.roo.model.RooJavaType.ROO_SERIALIZABLE;
import static org.springframework.roo.model.RooJavaType.ROO_TO_STRING;

import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang3.Validate;
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.classpath.PhysicalTypeCategory;
import org.springframework.roo.classpath.PhysicalTypeIdentifier;
import org.springframework.roo.classpath.PhysicalTypeMetadata;
import org.springframework.roo.classpath.TypeLocationService;
import org.springframework.roo.classpath.TypeManagementService;
import org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetails;
import org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetailsBuilder;
import org.springframework.roo.classpath.details.ConstructorMetadata;
import org.springframework.roo.classpath.details.ConstructorMetadataBuilder;
import org.springframework.roo.classpath.details.FieldMetadata;
import org.springframework.roo.classpath.details.annotations.AnnotatedJavaType;
import org.springframework.roo.classpath.details.annotations.AnnotationMetadataBuilder;
import org.springframework.roo.classpath.itd.InvocableMemberBodyBuilder;
import org.springframework.roo.metadata.MetadataService;
import org.springframework.roo.model.JavaSymbolName;
import org.springframework.roo.model.JavaType;
import org.springframework.roo.model.JdkJavaType;
import org.springframework.roo.model.ReservedWords;
import org.springframework.roo.project.LogicalPath;
import org.springframework.roo.project.Path;
import org.springframework.roo.project.PathResolver;
import org.springframework.roo.project.ProjectOperations;
import org.springframework.roo.shell.converters.StaticFieldConverter;

/**
* OSGi implementation of {@link ClasspathOperations}.
*
* @author Andrew Swan
* @since 1.2.0
*/
@Component
@Service
public class ClasspathOperationsImpl implements ClasspathOperations {

    @Reference MetadataService metadataService;
    @Reference PathResolver pathResolver;
    @Reference ProjectOperations projectOperations;
    @Reference StaticFieldConverter staticFieldConverter;
    @Reference TypeLocationService typeLocationService;
    @Reference TypeManagementService typeManagementService;

    @Override
    public void createClass(final JavaType name, final boolean rooAnnotations,
            final LogicalPath path, final JavaType superclass,
            final JavaType implementsType, final boolean createAbstract,
            final boolean permitReservedWords) {
        if (!permitReservedWords) {
            ReservedWords.verifyReservedWordsNotPresent(name);
        }

        Validate.isTrue(
                !JdkJavaType.isPartOfJavaLang(name.getSimpleTypeName()),
                "Class name '%s' is part of java.lang",
                name.getSimpleTypeName());

        int modifier = Modifier.PUBLIC;
        if (createAbstract) {
            modifier |= Modifier.ABSTRACT;
        }

        final String declaredByMetadataId = PhysicalTypeIdentifier
                .createIdentifier(name, path);
        final ClassOrInterfaceTypeDetailsBuilder cidBuilder = new ClassOrInterfaceTypeDetailsBuilder(
                declaredByMetadataId, modifier, name,
                PhysicalTypeCategory.CLASS);

        if (!superclass.equals(OBJECT)) {
            final ClassOrInterfaceTypeDetails superclassClassOrInterfaceTypeDetails = typeLocationService
                    .getTypeDetails(superclass);
            if (superclassClassOrInterfaceTypeDetails != null) {
                cidBuilder
                        .setSuperclass(new ClassOrInterfaceTypeDetailsBuilder(
                                superclassClassOrInterfaceTypeDetails));
            }
        }

        final List<JavaType> extendsTypes = new ArrayList<JavaType>();
        extendsTypes.add(superclass);
        cidBuilder.setExtendsTypes(extendsTypes);

        if (implementsType != null) {
            final Set<JavaType> implementsTypes = new LinkedHashSet<JavaType>();
            final ClassOrInterfaceTypeDetails typeDetails = typeLocationService
                    .getTypeDetails(declaredByMetadataId);
            if (typeDetails != null) {
                implementsTypes.addAll(typeDetails.getImplementsTypes());
            }
            implementsTypes.add(implementsType);
            cidBuilder.setImplementsTypes(implementsTypes);
        }

        if (rooAnnotations) {
            final List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>();
            annotations.add(new AnnotationMetadataBuilder(ROO_JAVA_BEAN));
            annotations.add(new AnnotationMetadataBuilder(ROO_TO_STRING));
            annotations.add(new AnnotationMetadataBuilder(ROO_EQUALS));
            annotations.add(new AnnotationMetadataBuilder(ROO_SERIALIZABLE));
            cidBuilder.setAnnotations(annotations);
        }
        typeManagementService.createOrUpdateTypeOnDisk(cidBuilder.build());
    }

    @Override
    public void createConstructor(final JavaType name, final Set<String> fields) {
        final ClassOrInterfaceTypeDetails javaTypeDetails = typeLocationService
                .getTypeDetails(name);
        Validate.notNull(javaTypeDetails,
                "The type specified, '%s', doesn't exist",
                name.getFullyQualifiedTypeName());

        final String declaredByMetadataId = PhysicalTypeIdentifier
                .createIdentifier(name,
                        pathResolver.getFocusedPath(Path.SRC_MAIN_JAVA));
        final List<FieldMetadata> constructorFields = new ArrayList<FieldMetadata>();
        final List<? extends FieldMetadata> declaredFields = javaTypeDetails
                .getDeclaredFields();
        if (fields != null) {
            for (final String field : fields) {
                declared: for (final FieldMetadata declaredField : declaredFields) {
                    if (field.equals(declaredField.getFieldName()
                            .getSymbolName())) {
                        constructorFields.add(declaredField);
                        break declared;
                    }
                }
            }
            if (constructorFields.isEmpty()) {
                // User supplied a set of fields that do not exist in the
                // class, so return without creating any constructor
                return;
            }
        }

        // Search for an existing constructor
        final List<JavaType> parameterTypes = new ArrayList<JavaType>();
        for (final FieldMetadata fieldMetadata : constructorFields) {
            parameterTypes.add(fieldMetadata.getFieldType());
        }

        final ConstructorMetadata result = javaTypeDetails
                .getDeclaredConstructor(parameterTypes);
        if (result != null) {
            // Found an existing constructor on this class
            return;
        }

        final List<JavaSymbolName> parameterNames = new ArrayList<JavaSymbolName>();

        final InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder();
        bodyBuilder.appendFormalLine("super();");
        for (final FieldMetadata field : constructorFields) {
            final String fieldName = field.getFieldName().getSymbolName();
            bodyBuilder.appendFormalLine("this." + fieldName + " = "
                    + fieldName + ";");
            parameterNames.add(field.getFieldName());
        }

        // Create the constructor
        final ConstructorMetadataBuilder constructorBuilder = new ConstructorMetadataBuilder(
                declaredByMetadataId);
        constructorBuilder.setModifier(Modifier.PUBLIC);
        constructorBuilder.setParameterTypes(AnnotatedJavaType
                .convertFromJavaTypes(parameterTypes));
        constructorBuilder.setParameterNames(parameterNames);
        constructorBuilder.setBodyBuilder(bodyBuilder);

        final ClassOrInterfaceTypeDetailsBuilder cidBuilder = new ClassOrInterfaceTypeDetailsBuilder(
                javaTypeDetails);
        cidBuilder.addConstructor(constructorBuilder);
        typeManagementService.createOrUpdateTypeOnDisk(cidBuilder.build());
    }

    @Override
    public void createEnum(final JavaType name, final LogicalPath path,
            final boolean permitReservedWords) {
        if (!permitReservedWords) {
            ReservedWords.verifyReservedWordsNotPresent(name);
        }
        final String physicalTypeId = PhysicalTypeIdentifier.createIdentifier(
                name, path);
        final ClassOrInterfaceTypeDetailsBuilder cidBuilder = new ClassOrInterfaceTypeDetailsBuilder(
                physicalTypeId, Modifier.PUBLIC, name,
                PhysicalTypeCategory.ENUMERATION);
        typeManagementService.createOrUpdateTypeOnDisk(cidBuilder.build());
    }

    @Override
    public void createInterface(final JavaType name, final LogicalPath path,
            final boolean permitReservedWords) {
        if (!permitReservedWords) {
            ReservedWords.verifyReservedWordsNotPresent(name);
        }

        final String declaredByMetadataId = PhysicalTypeIdentifier
                .createIdentifier(name, path);
        final ClassOrInterfaceTypeDetailsBuilder cidBuilder = new ClassOrInterfaceTypeDetailsBuilder(
                declaredByMetadataId, Modifier.PUBLIC, name,
                PhysicalTypeCategory.INTERFACE);
        typeManagementService.createOrUpdateTypeOnDisk(cidBuilder.build());
    }

    @Override
    public void enumConstant(final JavaType name,
            final JavaSymbolName fieldName, final boolean permitReservedWords) {
        if (!permitReservedWords) {
            // No need to check the "name" as if the class exists it is assumed
            // it is a legal name
            ReservedWords.verifyReservedWordsNotPresent(fieldName);
        }

        final String declaredByMetadataId = PhysicalTypeIdentifier
                .createIdentifier(name,
                        pathResolver.getFocusedPath(Path.SRC_MAIN_JAVA));
        typeManagementService.addEnumConstant(declaredByMetadataId, fieldName);
    }

    @Override
    public void focus(final JavaType type) {
        Validate.notNull(type, "Specify the type to focus on");
        final String physicalTypeIdentifier = typeLocationService
                .getPhysicalTypeIdentifier(type);
        Validate.notNull(physicalTypeIdentifier, "Cannot locate the type %s",
                type.getFullyQualifiedTypeName());
        final PhysicalTypeMetadata ptm = (PhysicalTypeMetadata) metadataService
                .get(physicalTypeIdentifier);
        Validate.notNull(ptm, "Class %s does not exist",
                PhysicalTypeIdentifier.getFriendlyName(physicalTypeIdentifier));
    }

    @Override
    public boolean isProjectAvailable() {
        return projectOperations.isFocusedProjectAvailable();
    }

    protected void activate(final ComponentContext context) {
        staticFieldConverter.add(InheritanceType.class);
    }

    protected void deactivate(final ComponentContext context) {
        staticFieldConverter.remove(InheritanceType.class);
    }
}
TOP

Related Classes of org.springframework.roo.classpath.operations.ClasspathOperationsImpl

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.