Class Type

  • All Implemented Interfaces:
    java.lang.Comparable<Type>, Writable

    public class Type
    extends ModelElement
    implements java.lang.Comparable<Type>
    Represents (a reference to) the type of a bean property, parameter etc. Types are managed per generated source file. Each type corresponds to a TypeMirror, i.e. there are different instances for e.g. Set<String> and Set<Integer>.

    Allows for a unified handling of declared and primitive types and usage within templates. Instances are obtained through TypeFactory.

    • Field Detail

      • typeUtils

        private final TypeUtils typeUtils
      • typeMirror

        private final javax.lang.model.type.TypeMirror typeMirror
      • typeElement

        private final javax.lang.model.element.TypeElement typeElement
      • typeParameters

        private final java.util.List<Type> typeParameters
      • componentType

        private final Type componentType
      • topLevelType

        private final Type topLevelType
      • packageName

        private final java.lang.String packageName
      • name

        private final java.lang.String name
      • nameWithTopLevelTypeName

        private final java.lang.String nameWithTopLevelTypeName
      • qualifiedName

        private final java.lang.String qualifiedName
      • isInterface

        private final boolean isInterface
      • isEnumType

        private final boolean isEnumType
      • isIterableType

        private final boolean isIterableType
      • isCollectionType

        private final boolean isCollectionType
      • isMapType

        private final boolean isMapType
      • isVoid

        private final boolean isVoid
      • isStream

        private final boolean isStream
      • isLiteral

        private final boolean isLiteral
      • loggingVerbose

        private final boolean loggingVerbose
      • enumConstants

        private final java.util.List<java.lang.String> enumConstants
      • toBeImportedTypes

        private final java.util.Map<java.lang.String,​java.lang.String> toBeImportedTypes
      • notToBeImportedTypes

        private final java.util.Map<java.lang.String,​java.lang.String> notToBeImportedTypes
      • isToBeImported

        private java.lang.Boolean isToBeImported
      • readAccessors

        private java.util.Map<java.lang.String,​ReadAccessor> readAccessors
      • allMethods

        private java.util.List<javax.lang.model.element.ExecutableElement> allMethods
      • allFields

        private java.util.List<javax.lang.model.element.VariableElement> allFields
      • recordComponents

        private java.util.List<javax.lang.model.element.Element> recordComponents
      • setters

        private java.util.List<Accessor> setters
      • adders

        private java.util.List<Accessor> adders
      • alternativeTargetAccessors

        private java.util.List<Accessor> alternativeTargetAccessors
      • boundingBase

        private Type boundingBase
      • boundTypes

        private java.util.List<Type> boundTypes
      • boxedEquivalent

        private Type boxedEquivalent
      • hasAccessibleConstructor

        private java.lang.Boolean hasAccessibleConstructor
      • filters

        private final Filters filters
    • Constructor Detail

      • Type

        public Type​(TypeUtils typeUtils,
                    ElementUtils elementUtils,
                    TypeFactory typeFactory,
                    AccessorNamingUtils accessorNaming,
                    javax.lang.model.type.TypeMirror typeMirror,
                    javax.lang.model.element.TypeElement typeElement,
                    java.util.List<Type> typeParameters,
                    ImplementationType implementationType,
                    Type componentType,
                    java.lang.String packageName,
                    java.lang.String name,
                    java.lang.String qualifiedName,
                    boolean isInterface,
                    boolean isEnumType,
                    boolean isIterableType,
                    boolean isCollectionType,
                    boolean isMapType,
                    boolean isStreamType,
                    java.util.Map<java.lang.String,​java.lang.String> toBeImportedTypes,
                    java.util.Map<java.lang.String,​java.lang.String> notToBeImportedTypes,
                    java.lang.Boolean isToBeImported,
                    boolean isLiteral,
                    boolean loggingVerbose)
    • Method Detail

      • getTypeMirror

        public javax.lang.model.type.TypeMirror getTypeMirror()
      • getTypeElement

        public javax.lang.model.element.TypeElement getTypeElement()
      • getPackageName

        public java.lang.String getPackageName()
      • getName

        public java.lang.String getName()
      • createReferenceName

        public java.lang.String createReferenceName()
        Returns a String that could be used in generated code to reference to this Type.

        The first time a name is referred-to it will be marked as to be imported. For instance LocalDateTime can be one of java.time.LocalDateTime and org.joda.LocalDateTime)

        If the java.time variant is referred to first, the java.time.LocalDateTime will be imported and the org.joda variant will be referred to with its FQN.

        If the type is nested and its top level type is to be imported then the name including its top level type will be returned.

        Returns:
        Just the name if this Type will be imported, the name up to the top level Type (if the top level type is important, otherwise the fully-qualified name.
      • getTypeParameters

        public java.util.List<Type> getTypeParameters()
      • getComponentType

        public Type getComponentType()
      • isPrimitive

        public boolean isPrimitive()
      • isInterface

        public boolean isInterface()
      • isEnumType

        public boolean isEnumType()
      • isVoid

        public boolean isVoid()
      • isAbstract

        public boolean isAbstract()
      • isString

        public boolean isString()
      • getEnumConstants

        public java.util.List<java.lang.String> getEnumConstants()
        Returns:
        this type's enum constants in case it is an enum, an empty list otherwise.
      • getImplementationType

        public Type getImplementationType()
        Returns the implementation type to be instantiated in case this type is an interface iterable, collection or map type. The type will have the correct type arguments, so if this type e.g. represents Set<String>, the implementation type is HashSet<String>.
        Returns:
        The implementation type to be instantiated in case this type is an interface iterable, collection or map type, null otherwise.
      • isIterableType

        public boolean isIterableType()
        Whether this type is a sub-type of Iterable or an array type.
        Returns:
        true if this type is a sub-type of Iterable or an array type, false otherwise.
      • isIterableOrStreamType

        public boolean isIterableOrStreamType()
        Whether this type is a sub-type ofIterable, Stream or an array type
        Returns:
        true if this type is a sub-type ofIterable, Stream or an array type, false otherwise
      • isCollectionType

        public boolean isCollectionType()
      • isMapType

        public boolean isMapType()
      • hasStringMapSignature

        private boolean hasStringMapSignature()
      • isCollectionOrMapType

        public boolean isCollectionOrMapType()
      • isArrayType

        public boolean isArrayType()
      • isTypeVar

        public boolean isTypeVar()
      • isIntersection

        public boolean isIntersection()
      • isJavaLangType

        public boolean isJavaLangType()
      • isRecord

        public boolean isRecord()
      • isStreamType

        public boolean isStreamType()
        Whether this type is a sub-type of Stream.
        Returns:
        true it this type is a sub-type of Stream, false otherwise
      • hasSuperBound

        public boolean hasSuperBound()
        A wild card type can have two types of bounds (mutual exclusive): extends and super.
        Returns:
        true if the bound has a wild card super bound (e.g. ? super Number)
      • hasExtendsBound

        public boolean hasExtendsBound()
        A wild card type can have two types of bounds (mutual exclusive): extends and super.
        Returns:
        true if the bound has a wild card super bound (e.g. ? extends Number)
      • hasLowerBound

        public boolean hasLowerBound()
        A type variable type can have two types of bounds (mutual exclusive): lower and upper. Note that its use is only permitted on a definition (not on the place where its used). For instance: <T super Number> T map( T in)
        Returns:
        true if the bound has a type variable lower bound (e.g. T super Number)
      • hasUpperBound

        public boolean hasUpperBound()
        A type variable type can have two types of bounds (mutual exclusive): lower and upper. Note that its use is only permitted on a definition (not on the place where its used). For instance: ><T extends Number> T map( T in)
        Returns:
        true if the bound has a type variable upper bound (e.g. T extends Number)
      • getFullyQualifiedName

        public java.lang.String getFullyQualifiedName()
      • getImportName

        public java.lang.String getImportName()
        Returns:
        The name of this type as to be used within import statements.
      • getImportTypes

        public java.util.Set<Type> getImportTypes()
        Description copied from class: ModelElement
        Returns a set containing those Types referenced by this model element for which an import statement needs to be declared.
        Specified by:
        getImportTypes in class ModelElement
        Returns:
        A set with type referenced by this model element. Must not be null.
      • isTopLevelTypeToBeImported

        protected boolean isTopLevelTypeToBeImported()
      • isToBeImported

        public boolean isToBeImported()
        Whether this type is to be imported by means of an import statement in the currently generated source file (it can be referenced in the generated source using its simple name) or not (referenced using the FQN).
        Returns:
        true if the type is imported, false otherwise.
      • shouldUseSimpleName

        private boolean shouldUseSimpleName()
      • erasure

        public Type erasure()
      • withoutBounds

        public Type withoutBounds()
      • isAssignableTo

        public boolean isAssignableTo​(Type other)
        Whether this type is assignable to the given other type, considering the "extends / upper bounds" as well.
        Parameters:
        other - The other type.
        Returns:
        true if and only if this type is assignable to the given other type.
      • isRawAssignableTo

        public boolean isRawAssignableTo​(Type other)
        Whether this type is raw assignable to the given other type. We can't make a verdict on typevars, they need to be resolved first.
        Parameters:
        other - The other type.
        Returns:
        true if and only if this type is assignable to the given other type.
      • asRawType

        public Type asRawType()
        removes any bounds from this type.
        Returns:
        the raw type
      • getReadAccessor

        public ReadAccessor getReadAccessor​(java.lang.String propertyName)
      • getPresenceChecker

        public PresenceCheckAccessor getPresenceChecker​(java.lang.String propertyName)
      • getPropertyReadAccessors

        public java.util.Map<java.lang.String,​ReadAccessor> getPropertyReadAccessors()
        getPropertyReadAccessors
        Returns:
        an unmodifiable map of all read accessors (including 'is' for booleans), indexed by property name
      • getPropertyPresenceCheckers

        public java.util.Map<java.lang.String,​PresenceCheckAccessor> getPropertyPresenceCheckers()
        getPropertyPresenceCheckers
        Returns:
        an unmodifiable map of all presence checkers, indexed by property name
      • getPropertyWriteAccessors

        public java.util.Map<java.lang.String,​Accessor> getPropertyWriteAccessors​(CollectionMappingStrategyGem cmStrategy)
        getPropertyWriteAccessors returns a map of the write accessors according to the CollectionMappingStrategy. These accessors include:
        • setters, the obvious candidate :-), getSetters()
        • readAccessors, for collections that do not have a setter, e.g. for JAXB generated collection attributes getPropertyReadAccessors()
        • adders, typically for from table generated entities, getAdders()
        Parameters:
        cmStrategy - collection mapping strategy
        Returns:
        an unmodifiable map of all write accessors indexed by property name
      • getRecordComponents

        public java.util.List<javax.lang.model.element.Element> getRecordComponents()
      • determinePreferredType

        private Type determinePreferredType​(Accessor readAccessor)
      • determineTargetType

        private Type determineTargetType​(Accessor candidate)
      • getAllMethods

        private java.util.List<javax.lang.model.element.ExecutableElement> getAllMethods()
      • getAllFields

        private java.util.List<javax.lang.model.element.VariableElement> getAllFields()
      • nullSafeTypeElementListConversion

        private <T> java.util.List<T> nullSafeTypeElementListConversion​(java.util.function.Function<javax.lang.model.element.TypeElement,​java.util.List<T>> conversionFunction)
      • getPropertyName

        private java.lang.String getPropertyName​(Accessor accessor)
      • getPropertyName

        private java.lang.String getPropertyName​(javax.lang.model.element.ExecutableElement element)
      • getAdderForType

        private Accessor getAdderForType​(Type collectionProperty,
                                         java.lang.String pluralPropertyName)
        Tries to find an addMethod in this type for given collection property in this type. Matching occurs on:
        1. The generic type parameter type of the collection should match the adder method argument
        2. When there are more candidates, property name is made singular (as good as is possible). This routine looks for a matching add method name.
        3. The singularization rules of Dali are used to make a property name singular. This routine looks for a matching add method name.
        Parameters:
        collectionProperty - property type (assumed collection) to find the adder method for
        pluralPropertyName - the property name (assumed plural)
        Returns:
        corresponding adder method for getter when present
      • getAccessorCandidates

        private java.util.List<Accessor> getAccessorCandidates​(Type property,
                                                               java.lang.Class<?> superclass)
        Returns all accessor candidates that start with "add" and have exactly one argument whose type matches the collection or stream property's type argument.
        Parameters:
        property - the collection or stream property
        superclass - the superclass to use for type argument lookup
        Returns:
        accessor candidates
      • boxed

        private javax.lang.model.type.TypeMirror boxed​(javax.lang.model.type.TypeMirror possiblePrimitive)
      • getSetters

        private java.util.List<Accessor> getSetters()
        getSetters
        Returns:
        an unmodifiable list of all setters
      • getAdders

        private java.util.List<Accessor> getAdders()
        Alternative accessors could be a getter for a collection / map. By means of the Collection.addAll(Collection) or Map.putAll(Map) this getter can still be used as targetAccessor. JAXB XJC tool generates such constructs. This method can be extended when new cases come along. getAdders
        Returns:
        an unmodifiable list of all adders
      • getAlternativeTargetAccessors

        private java.util.List<Accessor> getAlternativeTargetAccessors()
        Alternative accessors could be a getter for a collection. By means of the Collection.addAll(java.util.Collection) this getter can still be used as targetAccessor. JAXB XJC tool generates such constructs. This method can be extended when new cases come along.
        Returns:
        an unmodifiable list of alternative target accessors.
      • correspondingSetterMethodExists

        private boolean correspondingSetterMethodExists​(Accessor getterMethod,
                                                        java.util.List<Accessor> setterMethods)
      • isCollectionOrMapOrStream

        private boolean isCollectionOrMapOrStream​(Accessor getterMethod)
      • isCollection

        private boolean isCollection​(javax.lang.model.type.TypeMirror candidate)
      • isStream

        private boolean isStream​(javax.lang.model.type.TypeMirror candidate)
      • isMap

        private boolean isMap​(javax.lang.model.type.TypeMirror candidate)
      • isSubType

        private boolean isSubType​(javax.lang.model.type.TypeMirror candidate,
                                  java.lang.Class<?> clazz)
      • distanceTo

        public int distanceTo​(Type assignableOther)
        Returns the length of the shortest path in the type hierarchy between this type and the specified other type. Returns -1 if this type is not assignable to the other type. Returns 0 if this type is equal to the other type. Returns 1, if the other type is a direct super type of this type, and so on.
        Parameters:
        assignableOther - the other type
        Returns:
        the length of the shortest path in the type hierarchy between this type and the specified other type
      • distanceTo

        private int distanceTo​(javax.lang.model.type.TypeMirror base,
                               javax.lang.model.type.TypeMirror targetType)
      • canAccess

        public boolean canAccess​(Type type,
                                 javax.lang.model.element.ExecutableElement method)
        Parameters:
        type - the type declaring the method
        method - the method to check
        Returns:
        Whether this type can access the given method declared on the given type.
      • getNull

        public java.lang.String getNull()
        Returns:
        A valid Java expression most suitable for representing null - useful for dealing with primitives from FTL.
      • getSensibleDefault

        public java.lang.String getSensibleDefault()
      • hashCode

        public int hashCode()
        Overrides:
        hashCode in class java.lang.Object
      • equals

        public boolean equals​(java.lang.Object obj)
        Overrides:
        equals in class java.lang.Object
      • compareTo

        public int compareTo​(Type o)
        Specified by:
        compareTo in interface java.lang.Comparable<Type>
      • toString

        public java.lang.String toString()
        Overrides:
        toString in class java.lang.Object
      • describe

        public java.lang.String describe()
        Returns:
        a string representation of the type for use in messages
      • getIdentification

        public java.lang.String getIdentification()
        Returns:
        an identification that can be used as part in a forged method name.
      • getTypeBound

        public Type getTypeBound()
        Establishes the type bound:
        1. <? extends Number>, returns Number
        2. <? super Number>, returns Number
        3. <?>, returns Object
        4. <T extends Number>, returns Number
        Returns:
        the bound for this parameter
      • getTypeBounds

        public java.util.List<Type> getTypeBounds()
      • hasAccessibleConstructor

        public boolean hasAccessibleConstructor()
      • getDirectSuperTypes

        public java.util.List<Type> getDirectSuperTypes()
        Returns the direct supertypes of a type. The interface types, if any, will appear last in the list.
        Returns:
        the direct supertypes, or an empty list if none
      • determineTypeArguments

        public java.util.List<Type> determineTypeArguments​(java.lang.Class<?> superclass)
        Searches for the given superclass and collects all type arguments for the given class
        Parameters:
        superclass - the superclass or interface the generic type arguments are searched for
        Returns:
        a list of type arguments or null, if superclass was not found
      • isNative

        public boolean isNative()
        All primitive types and their corresponding boxed types are considered native.
        Returns:
        true when native.
      • isLiteral

        public boolean isLiteral()
      • resolveParameterToType

        public Type.ResolvedPair resolveParameterToType​(Type declared,
                                                        Type parameterized)
        Steps through the declaredType in order to find a match for this typeVar Type. It aligns with the provided parameterized type where this typeVar type is used. For example: this: T declaredType: JAXBElement<String> parameterizedType: JAXBElement<T> result: String this: T, T[] or ? extends T, declaredType: E.g. Callable<? extends T> parameterizedType: Callable<BigDecimal> return: BigDecimal
        Parameters:
        declared - the type
        parameterized - the parameterized type
        Returns:
        - the same type when this is not a type var in the broadest sense (T, T[], or ? extends T) - the matching parameter in the parameterized type when this is a type var when found - null in all other cases
      • isWildCardBoundByTypeVar

        public boolean isWildCardBoundByTypeVar()
      • isArrayTypeVar

        public boolean isArrayTypeVar()
      • getBoxedEquivalent

        public Type getBoxedEquivalent()
        Gets the boxed equivalent type if the type is primitive, int will return Integer
        Returns:
        boxed equivalent
      • trimSimpleClassName

        private java.lang.String trimSimpleClassName​(java.lang.String className)
        It strips all the [] from the className. E.g.
             trimSimpleClassName("String[][][]") -> "String"
             trimSimpleClassName("String[]") -> "String"
         
        Parameters:
        className - that needs to be trimmed
        Returns:
        the trimmed className, or null if the className was null
      • nameWithTopLevelTypeName

        private static java.lang.String nameWithTopLevelTypeName​(javax.lang.model.element.TypeElement element,
                                                                 java.lang.String name)
      • topLevelType

        private static Type topLevelType​(javax.lang.model.element.TypeElement typeElement,
                                         TypeFactory typeFactory)
      • isEnumSet

        public boolean isEnumSet()