Package org.eclipse.persistence.internal.jpa.modelgen.visitors

Source Code of org.eclipse.persistence.internal.jpa.modelgen.visitors.TypeVisitor

/*******************************************************************************
* Copyright (c) 1998, 2010 Oracle. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
*     08/10/2009-2.0 Guy Pelletier
*       - 267391: JPA 2.0 implement/extend/use an APT tooling library for MetaModel API canonical classes
******************************************************************************/
package org.eclipse.persistence.internal.jpa.modelgen.visitors;

import javax.lang.model.type.ArrayType;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.ErrorType;
import javax.lang.model.type.ExecutableType;
import javax.lang.model.type.NoType;
import javax.lang.model.type.NullType;
import javax.lang.model.type.PrimitiveType;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.type.TypeVariable;
import javax.lang.model.type.WildcardType;
import javax.lang.model.util.SimpleTypeVisitor6;

import org.eclipse.persistence.internal.jpa.metadata.accessors.objects.MetadataAnnotatedElement;
import org.eclipse.persistence.internal.jpa.metadata.accessors.objects.MetadataClass;
import org.eclipse.persistence.internal.jpa.metadata.accessors.objects.MetadataMethod;
import org.eclipse.persistence.internal.jpa.modelgen.MetadataMirrorFactory;

/**
* A type visitor.
*
* @author Guy Pelletier
* @since EclipseLink 1.2
*/
public class TypeVisitor<R, P> extends SimpleTypeVisitor6<MetadataAnnotatedElement, MetadataAnnotatedElement> {
    public static String GENERIC_TYPE = "? extends Object";
   
    /**
     * INTERNAL:
     */
    public TypeVisitor() {}
   
    /**
     * INTERNAL:
     * Visit a declared array field.
     */
    @Override
    public MetadataAnnotatedElement visitArray(ArrayType arrayType, MetadataAnnotatedElement annotatedElement) {
        annotatedElement.setType(arrayType.toString());
        return annotatedElement;
    }
   
    /**
     * INTERNAL:
     * Visit a declared field or Class.
     */
    @Override
    public MetadataAnnotatedElement visitDeclared(DeclaredType declaredType, MetadataAnnotatedElement annotatedElement) {
        // Get the metadata class of the declared type from the factory.
        MetadataMirrorFactory factory = (MetadataMirrorFactory) annotatedElement.getMetadataFactory();
        MetadataClass cls = factory.getMetadataClass(declaredType);
       
        // Set the type, which is the class name.
        annotatedElement.setType(cls.getName());
       
        // Set the generic types. Internally EclipseLink wants the class name
        // in the 0 position of the generic list.
        annotatedElement.addGenericType(cls.getName());
       
        for (TypeMirror typeArgument : declaredType.getTypeArguments()) {
            // Set the type from the metadata class as it may be a generic and
            // we don't want to set the letter type, rather our default GENERIC_TYPE.
            annotatedElement.addGenericType(factory.getMetadataClass(typeArgument).getType());
        }
       
        return annotatedElement;
    }

    /**
     * INTERNAL:
     */
    @Override
    public MetadataAnnotatedElement visitError(ErrorType errorType, MetadataAnnotatedElement annotatedElement) {
        // We will hit this case when there exists a compile error on the model.
        // However our annotation processor will still be called and we
        // therefore want to ensure our annotatedElement still has a type set
        // on it and not null. This will avoid exceptions when we go through
        // the pre-processing of our metadata classes.
        annotatedElement.setType(GENERIC_TYPE);
        return annotatedElement;
    }

    /**
     * INTERNAL:
     * Visit a method.
     */
    @Override
    public MetadataAnnotatedElement visitExecutable(ExecutableType executableType, MetadataAnnotatedElement annotatedElement) {
        MetadataMirrorFactory factory = ((MetadataMirrorFactory) annotatedElement.getMetadataFactory());
        MetadataMethod method = (MetadataMethod) annotatedElement;
       
        // Set the parameters.
        for (TypeMirror parameter : executableType.getParameterTypes()) {
            method.addParameter(factory.getMetadataClass(parameter).getType());
        }
       
        // Visit the return type (will set the type and generic types).
        executableType.getReturnType().accept(this, method);
        method.setReturnType(method.getType());
       
        return method;
    }
   
    /**
     * INTERNAL:
     * Method that returns void.
     */
    @Override
    public MetadataAnnotatedElement visitNoType(NoType noType, MetadataAnnotatedElement annotatedElement) {
        // Should this be Void.class?
        annotatedElement.setType(GENERIC_TYPE);
        return annotatedElement;
    }

    /**
     * INTERNAL:
     */
    @Override
    public MetadataAnnotatedElement visitNull(NullType nullType, MetadataAnnotatedElement annotatedElement) {
        // We will hit this case when there exists a compile error on the model??
        // However our annotation processor will still be called and we
        // therefore want to ensure our annotatedElement still has a type set
        // on it and not null. This will avoid exceptions when we go through
        // the pre-processing of our metadata classes.
        annotatedElement.setType(GENERIC_TYPE);
        return annotatedElement;
    }

    /**
     * INTERNAL:
     * Visit a declared primitive field.
     */
    @Override
    public MetadataAnnotatedElement visitPrimitive(PrimitiveType primitiveType, MetadataAnnotatedElement annotatedElement) {
        // We can not set the boxed type here. We must preserve the actual type
        // otherwise during accessor pre-process a validation exception will
        // occur under property access since we'll look for the equivalent
        // set method with the boxed class which will not be found. We deal with
        // boxing the type when generating the canonical model.
        annotatedElement.setPrimitiveType(primitiveType);
        return annotatedElement;
    }

    /**
     * INTERNAL:
     */
    @Override
    public MetadataAnnotatedElement visitTypeVariable(TypeVariable typeVariable, MetadataAnnotatedElement annotatedElement) {
        annotatedElement.setType(GENERIC_TYPE);
        return annotatedElement;
    }

    /**
     * INTERNAL:
     */
    @Override
    public MetadataAnnotatedElement visitWildcard(WildcardType wildcardType, MetadataAnnotatedElement annotatedElement) {
        annotatedElement.setType(wildcardType.toString());
        return annotatedElement;
    }
}
TOP

Related Classes of org.eclipse.persistence.internal.jpa.modelgen.visitors.TypeVisitor

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.