some cleanup in static metamodel code
This commit is contained in:
parent
862a967a17
commit
43905c657f
|
@ -14,6 +14,7 @@ import javax.lang.model.util.Elements;
|
|||
import org.hibernate.jpamodelgen.model.MetaAttribute;
|
||||
import org.hibernate.jpamodelgen.model.Metamodel;
|
||||
|
||||
import static java.beans.Introspector.decapitalize;
|
||||
import static org.hibernate.jpamodelgen.util.StringUtil.getUpperUnderscoreCaseFromLowerCamelCase;
|
||||
|
||||
/**
|
||||
|
@ -82,19 +83,19 @@ public abstract class AnnotationMetaAttribute implements MetaAttribute {
|
|||
|
||||
@Override
|
||||
public String getPropertyName() {
|
||||
Elements elementsUtil = parent.getContext().getElementUtils();
|
||||
final Elements elementsUtil = parent.getContext().getElementUtils();
|
||||
if ( element.getKind() == ElementKind.FIELD ) {
|
||||
return element.getSimpleName().toString();
|
||||
}
|
||||
else if ( element.getKind() == ElementKind.METHOD ) {
|
||||
String name = element.getSimpleName().toString();
|
||||
final String name = element.getSimpleName().toString();
|
||||
if ( name.startsWith( "get" ) ) {
|
||||
return elementsUtil.getName( Introspector.decapitalize( name.substring( "get".length() ) ) ).toString();
|
||||
return elementsUtil.getName( decapitalize( name.substring( "get".length() ) ) ).toString();
|
||||
}
|
||||
else if ( name.startsWith( "is" ) ) {
|
||||
return ( elementsUtil.getName( Introspector.decapitalize( name.substring( "is".length() ) ) ) ).toString();
|
||||
return ( elementsUtil.getName( decapitalize( name.substring( "is".length() ) ) ) ).toString();
|
||||
}
|
||||
return elementsUtil.getName( Introspector.decapitalize( name ) ).toString();
|
||||
return elementsUtil.getName( decapitalize( name ) ).toString();
|
||||
}
|
||||
else {
|
||||
return elementsUtil.getName( element.getSimpleName() + "/* " + element.getKind() + " */" ).toString();
|
||||
|
|
|
@ -90,6 +90,7 @@ import static org.hibernate.jpamodelgen.util.TypeUtils.getAnnotationMirror;
|
|||
import static org.hibernate.jpamodelgen.util.TypeUtils.getAnnotationValue;
|
||||
import static org.hibernate.jpamodelgen.util.TypeUtils.getAnnotationValueRef;
|
||||
import static org.hibernate.jpamodelgen.util.TypeUtils.hasAnnotation;
|
||||
import static org.hibernate.jpamodelgen.util.TypeUtils.primitiveClassMatchesKind;
|
||||
|
||||
/**
|
||||
* Class used to collect meta information about an annotated type (entity, embeddable or mapped superclass).
|
||||
|
@ -1141,43 +1142,46 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
StringTokenizer tokens,
|
||||
String token) {
|
||||
final Name memberName = candidate.getSimpleName();
|
||||
final TypeMirror type;
|
||||
if ( accessType == AccessType.FIELD && candidate.getKind() == ElementKind.FIELD ) {
|
||||
if ( !fieldMatches(token, memberName) ) {
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
type = candidate.asType();
|
||||
}
|
||||
}
|
||||
else if ( accessType == AccessType.PROPERTY && candidate.getKind() == ElementKind.METHOD ) {
|
||||
if ( !getterMatches(token, memberName) ) {
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
final ExecutableElement method = (ExecutableElement) candidate;
|
||||
type = method.getReturnType();
|
||||
}
|
||||
}
|
||||
else {
|
||||
final TypeMirror type = memberType( candidate, accessType, token, memberName );
|
||||
if (type == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( tokens.hasMoreTokens() ) {
|
||||
if ( type.getKind() == TypeKind.DECLARED ) {
|
||||
final DeclaredType declaredType = (DeclaredType) type;
|
||||
final TypeElement memberType = (TypeElement) declaredType.asElement();
|
||||
memberTypes.put( qualify( entityType.getQualifiedName().toString(), memberName.toString() ),
|
||||
memberType.getQualifiedName().toString() );
|
||||
return memberMatchingPath( memberType, tokens );
|
||||
}
|
||||
return null;
|
||||
else if ( tokens.hasMoreTokens() ) {
|
||||
return type.getKind() == TypeKind.DECLARED
|
||||
? memberForPath( entityType, tokens, (DeclaredType) type, memberName )
|
||||
: null;
|
||||
}
|
||||
else {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
|
||||
private @Nullable Element memberForPath(
|
||||
TypeElement entityType, StringTokenizer tokens, DeclaredType type, Name memberName) {
|
||||
final TypeElement memberType = (TypeElement) type.asElement();
|
||||
memberTypes.put( qualify( entityType.getQualifiedName().toString(), memberName.toString() ),
|
||||
memberType.getQualifiedName().toString() ); // NOTE SIDE EFFECT!
|
||||
return memberMatchingPath( memberType, tokens );
|
||||
}
|
||||
|
||||
private static @Nullable TypeMirror memberType(Element candidate, AccessType accessType, String token, Name memberName) {
|
||||
final ElementKind kind = candidate.getKind();
|
||||
if ( accessType == AccessType.FIELD && kind == ElementKind.FIELD ) {
|
||||
return fieldMatches(token, memberName)
|
||||
? candidate.asType()
|
||||
: null;
|
||||
}
|
||||
else if ( accessType == AccessType.PROPERTY && kind == ElementKind.METHOD ) {
|
||||
final ExecutableElement executable = (ExecutableElement) candidate;
|
||||
return getterMatches(token, memberName)
|
||||
? executable.getReturnType()
|
||||
: null;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean fieldMatches(String token, Name fieldName) {
|
||||
return fieldName.contentEquals( token );
|
||||
}
|
||||
|
@ -1464,30 +1468,12 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
return paramTypeElement.getQualifiedName().contentEquals(itemTypeName);
|
||||
}
|
||||
else if ( kind.isPrimitive() ) {
|
||||
switch ( kind ) {
|
||||
case SHORT:
|
||||
return itemType.equals(Short.class);
|
||||
case INT:
|
||||
return itemType.equals(Integer.class);
|
||||
case LONG:
|
||||
return itemType.equals(Long.class);
|
||||
case BOOLEAN:
|
||||
return itemType.equals(Boolean.class);
|
||||
case FLOAT:
|
||||
return itemType.equals(Float.class);
|
||||
case DOUBLE:
|
||||
return itemType.equals(Double.class);
|
||||
case CHAR:
|
||||
return itemType.equals(Character.class);
|
||||
case BYTE:
|
||||
return itemType.equals(Byte.class);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return primitiveClassMatchesKind( itemType, kind );
|
||||
}
|
||||
else if ( kind == TypeKind.ARRAY ) {
|
||||
final ArrayType arrayType = (ArrayType) parameterType;
|
||||
return itemType.isArray()
|
||||
&& parameterMatches( ((ArrayType) parameterType).getComponentType(), itemType.getComponentType() );
|
||||
&& parameterMatches( arrayType.getComponentType(), itemType.getComponentType() );
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
|
@ -1499,7 +1485,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
if ( componentType.getKind() == TypeKind.DECLARED ) {
|
||||
final DeclaredType declaredType = (DeclaredType) componentType;
|
||||
final TypeElement typeElement = (TypeElement) declaredType.asElement();
|
||||
return typeElement.getQualifiedName().contentEquals("java.lang.Object");
|
||||
return typeElement.getQualifiedName().contentEquals(Constants.JAVA_OBJECT);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
|
@ -1696,12 +1682,17 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
}
|
||||
|
||||
private static boolean parameterIsMissing(String hql, int i, String param, String type) {
|
||||
return !Pattern.compile( ".*(:" + param + "|\\?" + i + ")\\b.*", Pattern.DOTALL ).matcher( hql ).matches()
|
||||
return !hasParameter(hql, i, param)
|
||||
&& !isSessionParameter(type)
|
||||
&& !isPageParam(type)
|
||||
&& !isOrderParam(type);
|
||||
}
|
||||
|
||||
private static boolean hasParameter(String hql, int i, String param) {
|
||||
return Pattern.compile(".*(:" + param + "|\\?" + i + ")\\b.*", Pattern.DOTALL)
|
||||
.matcher(hql).matches();
|
||||
}
|
||||
|
||||
private static boolean isSessionParameter(String type) {
|
||||
return SESSION_TYPES.contains(type);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.jpamodelgen.annotation;
|
||||
|
||||
import org.hibernate.jpamodelgen.Context;
|
||||
import org.hibernate.jpamodelgen.util.Constants;
|
||||
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ElementKind;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.type.ArrayType;
|
||||
import javax.lang.model.type.DeclaredType;
|
||||
import javax.lang.model.type.PrimitiveType;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
import javax.lang.model.util.SimpleTypeVisitor8;
|
||||
import java.io.Serializable;
|
||||
|
||||
import static org.hibernate.jpamodelgen.util.Constants.BASIC_ARRAY_TYPES;
|
||||
import static org.hibernate.jpamodelgen.util.Constants.BASIC_TYPES;
|
||||
import static org.hibernate.jpamodelgen.util.TypeUtils.hasAnnotation;
|
||||
import static org.hibernate.jpamodelgen.util.TypeUtils.isClassOrRecordType;
|
||||
|
||||
/**
|
||||
* Checks whether the visited type is a basic attribute according to the JPA 2 spec
|
||||
* ( section 2.8 Mapping Defaults for Non-Relationship Fields or Properties)
|
||||
*/
|
||||
class BasicAttributeVisitor extends SimpleTypeVisitor8<Boolean, Element> {
|
||||
|
||||
private final Context context;
|
||||
|
||||
public BasicAttributeVisitor(Context context) {
|
||||
super(false);
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitPrimitive(PrimitiveType primitiveType, Element element) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitArray(ArrayType arrayType, Element element) {
|
||||
final TypeElement componentElement = (TypeElement)
|
||||
context.getTypeUtils().asElement( arrayType.getComponentType() );
|
||||
return BASIC_ARRAY_TYPES.contains( componentElement.getQualifiedName().toString() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitDeclared(DeclaredType declaredType, Element element) {
|
||||
final ElementKind kind = element.getKind();
|
||||
if ( kind == ElementKind.ENUM ) {
|
||||
return true;
|
||||
}
|
||||
else if ( isClassOrRecordType(element) || kind == ElementKind.INTERFACE ) {
|
||||
final TypeElement typeElement = (TypeElement) element;
|
||||
return BASIC_TYPES.contains( typeElement.getQualifiedName().toString() )
|
||||
|| hasAnnotation( element, Constants.EMBEDDABLE )
|
||||
|| isSerializable( typeElement );
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isSerializable(TypeElement typeElement) {
|
||||
final TypeMirror serializableType =
|
||||
context.getElementUtils()
|
||||
.getTypeElement(Serializable.class.getName())
|
||||
.asType();
|
||||
return context.getTypeUtils()
|
||||
.isSubtype( typeElement.asType(), serializableType );
|
||||
}
|
||||
}
|
|
@ -19,19 +19,29 @@ import javax.lang.model.type.TypeKind;
|
|||
import javax.lang.model.type.TypeMirror;
|
||||
import javax.lang.model.type.TypeVariable;
|
||||
import javax.lang.model.util.SimpleTypeVisitor8;
|
||||
import javax.lang.model.util.Types;
|
||||
import javax.tools.Diagnostic;
|
||||
|
||||
import org.hibernate.jpamodelgen.Context;
|
||||
import org.hibernate.jpamodelgen.util.AccessType;
|
||||
import org.hibernate.jpamodelgen.util.AccessTypeInformation;
|
||||
import org.hibernate.jpamodelgen.util.Constants;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import static org.hibernate.jpamodelgen.util.TypeUtils.isClassOrRecordType;
|
||||
import static org.hibernate.jpamodelgen.util.Constants.BASIC;
|
||||
import static org.hibernate.jpamodelgen.util.Constants.ELEMENT_COLLECTION;
|
||||
import static org.hibernate.jpamodelgen.util.Constants.EMBEDDED_ID;
|
||||
import static org.hibernate.jpamodelgen.util.Constants.ID;
|
||||
import static org.hibernate.jpamodelgen.util.Constants.MANY_TO_ANY;
|
||||
import static org.hibernate.jpamodelgen.util.Constants.MANY_TO_MANY;
|
||||
import static org.hibernate.jpamodelgen.util.Constants.MANY_TO_ONE;
|
||||
import static org.hibernate.jpamodelgen.util.Constants.ONE_TO_MANY;
|
||||
import static org.hibernate.jpamodelgen.util.Constants.ONE_TO_ONE;
|
||||
import static org.hibernate.jpamodelgen.util.TypeUtils.hasAnnotation;
|
||||
import static org.hibernate.jpamodelgen.util.NullnessUtil.castNonNull;
|
||||
import static org.hibernate.jpamodelgen.util.StringUtil.isProperty;
|
||||
import static org.hibernate.jpamodelgen.util.TypeUtils.DEFAULT_ANNOTATION_PARAMETER_NAME;
|
||||
import static org.hibernate.jpamodelgen.util.TypeUtils.containsAnnotation;
|
||||
import static org.hibernate.jpamodelgen.util.TypeUtils.determineAnnotationSpecifiedAccessType;
|
||||
import static org.hibernate.jpamodelgen.util.TypeUtils.extractClosestRealTypeAsString;
|
||||
import static org.hibernate.jpamodelgen.util.TypeUtils.getAnnotationMirror;
|
||||
|
@ -67,49 +77,36 @@ public class MetaAttributeGenerationVisitor extends SimpleTypeVisitor8<@Nullable
|
|||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable AnnotationMetaAttribute visitPrimitive(PrimitiveType t, Element element) {
|
||||
return new AnnotationMetaSingleAttribute( entity, element, toTypeString( t ) );
|
||||
private Types typeUtils() {
|
||||
return context.getTypeUtils();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable AnnotationMetaAttribute visitArray(ArrayType t, Element element) {
|
||||
// METAGEN-2 - For now we handle arrays as SingularAttribute
|
||||
// The code below is an attempt to be closer to the spec and only allow byte[], Byte[], char[] and Character[]
|
||||
// AnnotationMetaSingleAttribute attribute = null;
|
||||
// TypeMirror componentMirror = t.getComponentType();
|
||||
// if ( TypeKind.CHAR.equals( componentMirror.getKind() )
|
||||
// || TypeKind.BYTE.equals( componentMirror.getKind() ) ) {
|
||||
// attribute = new AnnotationMetaSingleAttribute( entity, element, TypeUtils.toTypeString( t ) );
|
||||
// }
|
||||
// else if ( TypeKind.DECLARED.equals( componentMirror.getKind() ) ) {
|
||||
// TypeElement componentElement = ( TypeElement ) context.getProcessingEnvironment()
|
||||
// .getTypeUtils()
|
||||
// .asElement( componentMirror );
|
||||
// if ( BASIC_ARRAY_TYPES.contains( componentElement.getQualifiedName().toString() ) ) {
|
||||
// attribute = new AnnotationMetaSingleAttribute( entity, element, TypeUtils.toTypeString( t ) );
|
||||
// }
|
||||
// }
|
||||
// return attribute;
|
||||
return new AnnotationMetaSingleAttribute( entity, element, toArrayTypeString( t, context ) );
|
||||
public @Nullable AnnotationMetaAttribute visitPrimitive(PrimitiveType primitiveType, Element element) {
|
||||
return new AnnotationMetaSingleAttribute( entity, element, toTypeString( primitiveType ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable AnnotationMetaAttribute visitTypeVariable(TypeVariable t, Element element) {
|
||||
public @Nullable AnnotationMetaAttribute visitArray(ArrayType arrayType, Element element) {
|
||||
return new AnnotationMetaSingleAttribute( entity, element, toArrayTypeString( arrayType, context ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable AnnotationMetaAttribute visitTypeVariable(TypeVariable typeVariable, Element element) {
|
||||
// METAGEN-29 - for a type variable we use the upper bound
|
||||
final TypeMirror erasedType = context.getTypeUtils().erasure( t.getUpperBound() );
|
||||
return new AnnotationMetaSingleAttribute( entity, element, erasedType.toString() );
|
||||
return new AnnotationMetaSingleAttribute( entity, element,
|
||||
typeUtils().erasure( typeVariable.getUpperBound() ).toString() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable AnnotationMetaAttribute visitDeclared(DeclaredType declaredType, Element element) {
|
||||
final TypeElement returnedElement = (TypeElement) context.getTypeUtils().asElement( declaredType );
|
||||
final TypeElement returnedElement = (TypeElement) typeUtils().asElement( declaredType );
|
||||
// WARNING: .toString() is necessary here since Name equals does not compare to String
|
||||
final String fqNameOfReturnType = returnedElement.getQualifiedName().toString();
|
||||
final String collection = Constants.COLLECTIONS.get( fqNameOfReturnType );
|
||||
final String returnTypeName = returnedElement.getQualifiedName().toString();
|
||||
final String collection = Constants.COLLECTIONS.get( returnTypeName );
|
||||
final String targetEntity = getTargetEntity( element.getAnnotationMirrors() );
|
||||
if ( collection != null ) {
|
||||
return createMetaCollectionAttribute( declaredType, element, fqNameOfReturnType, collection, targetEntity );
|
||||
return createMetaCollectionAttribute( declaredType, element, returnTypeName, collection, targetEntity );
|
||||
}
|
||||
else if ( isBasicAttribute( element, returnedElement ) ) {
|
||||
final String type = targetEntity != null ? targetEntity : returnedElement.getQualifiedName().toString();
|
||||
|
@ -121,15 +118,14 @@ public class MetaAttributeGenerationVisitor extends SimpleTypeVisitor8<@Nullable
|
|||
}
|
||||
|
||||
private AnnotationMetaAttribute createMetaCollectionAttribute(
|
||||
DeclaredType declaredType, Element element, String fqNameOfReturnType, String collection,
|
||||
DeclaredType declaredType, Element element, String returnTypeName, String collection,
|
||||
@Nullable String targetEntity) {
|
||||
if ( containsAnnotation( element, Constants.ELEMENT_COLLECTION ) ) {
|
||||
if ( hasAnnotation( element, ELEMENT_COLLECTION ) ) {
|
||||
final String explicitTargetEntity = getTargetEntity( element.getAnnotationMirrors() );
|
||||
final TypeMirror collectionElementType =
|
||||
getCollectionElementType( declaredType, fqNameOfReturnType, explicitTargetEntity, context );
|
||||
getCollectionElementType( declaredType, returnTypeName, explicitTargetEntity, context );
|
||||
if ( collectionElementType.getKind() == TypeKind.DECLARED ) {
|
||||
final TypeElement collectionElement = (TypeElement)
|
||||
context.getTypeUtils().asElement( collectionElementType );
|
||||
final TypeElement collectionElement = (TypeElement) typeUtils().asElement( collectionElementType );
|
||||
setAccessType( collectionElementType, collectionElement );
|
||||
}
|
||||
}
|
||||
|
@ -138,74 +134,59 @@ public class MetaAttributeGenerationVisitor extends SimpleTypeVisitor8<@Nullable
|
|||
|
||||
private AnnotationMetaAttribute createMetaAttribute(
|
||||
DeclaredType declaredType, Element element, String collection, @Nullable String targetEntity) {
|
||||
if ( containsAnnotation( element,
|
||||
Constants.ONE_TO_MANY, Constants.MANY_TO_MANY,
|
||||
Constants.MANY_TO_ANY, Constants.ELEMENT_COLLECTION ) ) {
|
||||
if ( hasAnnotation( element, ONE_TO_MANY, MANY_TO_MANY, MANY_TO_ANY, ELEMENT_COLLECTION ) ) {
|
||||
final String elementType = getElementType( declaredType, targetEntity );
|
||||
if ( collection.equals( Constants.MAP_ATTRIBUTE ) ) { //TODO: pretty fragile!
|
||||
return new AnnotationMetaMap(
|
||||
entity,
|
||||
element,
|
||||
collection,
|
||||
getMapKeyType( declaredType, element ),
|
||||
getElementType( declaredType, targetEntity )
|
||||
);
|
||||
final String keyType = getMapKeyType( declaredType, element );
|
||||
return new AnnotationMetaMap( entity, element, collection, keyType, elementType );
|
||||
}
|
||||
else {
|
||||
return new AnnotationMetaCollection(
|
||||
entity,
|
||||
element,
|
||||
collection,
|
||||
getElementType( declaredType, targetEntity )
|
||||
);
|
||||
return new AnnotationMetaCollection( entity, element, collection, elementType );
|
||||
}
|
||||
}
|
||||
else {
|
||||
final String typeWithVariablesErased = extractClosestRealTypeAsString( declaredType, context );
|
||||
return new AnnotationMetaSingleAttribute( entity, element, typeWithVariablesErased );
|
||||
return new AnnotationMetaSingleAttribute( entity, element,
|
||||
extractClosestRealTypeAsString( declaredType, context ) );
|
||||
}
|
||||
}
|
||||
|
||||
private void setAccessType(TypeMirror collectionElementType, TypeElement collectionElement) {
|
||||
final AccessTypeInformation accessTypeInfo = context.getAccessTypeInfo( collectionElementType.toString() );
|
||||
final String elementTypeName = collectionElementType.toString();
|
||||
final AccessTypeInformation accessTypeInfo = context.getAccessTypeInfo( elementTypeName );
|
||||
final AccessType entityAccessType = entity.getEntityAccessTypeInfo().getAccessType();
|
||||
if ( accessTypeInfo == null ) {
|
||||
final AccessTypeInformation newAccessTypeInfo = new AccessTypeInformation(
|
||||
collectionElementType.toString(),
|
||||
collectionElement == null ? null : determineAnnotationSpecifiedAccessType( collectionElement ),
|
||||
entity.getEntityAccessTypeInfo().getAccessType()
|
||||
context.addAccessTypeInformation(
|
||||
elementTypeName,
|
||||
new AccessTypeInformation(
|
||||
elementTypeName,
|
||||
collectionElement == null ? null
|
||||
: determineAnnotationSpecifiedAccessType( collectionElement ),
|
||||
entityAccessType
|
||||
)
|
||||
);
|
||||
context.addAccessTypeInformation( collectionElementType.toString(), newAccessTypeInfo );
|
||||
}
|
||||
else {
|
||||
accessTypeInfo.setDefaultAccessType( entity.getEntityAccessTypeInfo().getAccessType() );
|
||||
accessTypeInfo.setDefaultAccessType( entityAccessType );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable AnnotationMetaAttribute visitExecutable(ExecutableType t, Element p) {
|
||||
if ( p.getKind() == ElementKind.METHOD
|
||||
&& isProperty( p.getSimpleName().toString(), toTypeString( t.getReturnType() ) ) ) {
|
||||
return t.getReturnType().accept( this, p );
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
public @Nullable AnnotationMetaAttribute visitExecutable(ExecutableType executable, Element element) {
|
||||
return isPropertyGetter( executable, element )
|
||||
? executable.getReturnType().accept(this, element)
|
||||
: null;
|
||||
}
|
||||
|
||||
private static boolean isPropertyGetter(ExecutableType executable, Element element) {
|
||||
return element.getKind() == ElementKind.METHOD
|
||||
&& isProperty( element.getSimpleName().toString(),
|
||||
toTypeString( executable.getReturnType() ) );
|
||||
}
|
||||
|
||||
private boolean isBasicAttribute(Element element, Element returnedElement) {
|
||||
if ( containsAnnotation( element, Constants.BASIC )
|
||||
|| containsAnnotation( element, Constants.ONE_TO_ONE )
|
||||
|| containsAnnotation( element, Constants.MANY_TO_ONE )
|
||||
|| containsAnnotation( element, Constants.EMBEDDED_ID )
|
||||
|| containsAnnotation( element, Constants.ID ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// METAGEN-28
|
||||
if ( getAnnotationMirror( element, ORG_HIBERNATE_ANNOTATIONS_TYPE ) != null ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return returnedElement.asType().accept( new BasicAttributeVisitor( context ), returnedElement );
|
||||
return hasAnnotation( element, BASIC, ONE_TO_ONE, MANY_TO_ONE, EMBEDDED_ID, ID )
|
||||
|| hasAnnotation( element, ORG_HIBERNATE_ANNOTATIONS_TYPE ) // METAGEN-28
|
||||
|| returnedElement.asType().accept( new BasicAttributeVisitor( context ), returnedElement );
|
||||
}
|
||||
|
||||
private String getMapKeyType(DeclaredType declaredType, Element element) {
|
||||
|
@ -245,13 +226,13 @@ public class MetaAttributeGenerationVisitor extends SimpleTypeVisitor8<@Nullable
|
|||
*/
|
||||
private @Nullable String getTargetEntity(List<? extends AnnotationMirror> annotations) {
|
||||
for ( AnnotationMirror mirror : annotations ) {
|
||||
if ( isAnnotationMirrorOfType( mirror, Constants.ELEMENT_COLLECTION ) ) {
|
||||
if ( isAnnotationMirrorOfType( mirror, ELEMENT_COLLECTION ) ) {
|
||||
return getFullyQualifiedClassNameOfTargetEntity( mirror, "targetClass" );
|
||||
}
|
||||
else if ( isAnnotationMirrorOfType( mirror, Constants.ONE_TO_MANY )
|
||||
|| isAnnotationMirrorOfType( mirror, Constants.MANY_TO_MANY )
|
||||
|| isAnnotationMirrorOfType( mirror, Constants.MANY_TO_ONE )
|
||||
|| isAnnotationMirrorOfType( mirror, Constants.ONE_TO_ONE ) ) {
|
||||
else if ( isAnnotationMirrorOfType( mirror, ONE_TO_MANY )
|
||||
|| isAnnotationMirrorOfType( mirror, MANY_TO_MANY )
|
||||
|| isAnnotationMirrorOfType( mirror, MANY_TO_ONE )
|
||||
|| isAnnotationMirrorOfType( mirror, ONE_TO_ONE ) ) {
|
||||
return getFullyQualifiedClassNameOfTargetEntity( mirror, "targetEntity" );
|
||||
}
|
||||
else if ( isAnnotationMirrorOfType( mirror, ORG_HIBERNATE_ANNOTATIONS_TARGET ) ) {
|
||||
|
@ -276,56 +257,3 @@ public class MetaAttributeGenerationVisitor extends SimpleTypeVisitor8<@Nullable
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the visited type is a basic attribute according to the JPA 2 spec
|
||||
* ( section 2.8 Mapping Defaults for Non-Relationship Fields or Properties)
|
||||
*/
|
||||
class BasicAttributeVisitor extends SimpleTypeVisitor8<Boolean, Element> {
|
||||
|
||||
private final Context context;
|
||||
|
||||
public BasicAttributeVisitor(Context context) {
|
||||
super( false );
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitPrimitive(PrimitiveType primitiveType, Element element) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitArray(ArrayType arrayType, Element element) {
|
||||
final TypeElement componentElement = (TypeElement)
|
||||
context.getTypeUtils().asElement( arrayType.getComponentType() );
|
||||
return Constants.BASIC_ARRAY_TYPES.contains( componentElement.getQualifiedName().toString() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitDeclared(DeclaredType declaredType, Element element) {
|
||||
if ( ElementKind.ENUM.equals( element.getKind() ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( isClassOrRecordType( element )
|
||||
|| element.getKind() == ElementKind.INTERFACE ) {
|
||||
final TypeElement typeElement = (TypeElement) element;
|
||||
final String typeName = typeElement.getQualifiedName().toString();
|
||||
if ( Constants.BASIC_TYPES.contains( typeName ) ) {
|
||||
return true;
|
||||
}
|
||||
if ( containsAnnotation( element, Constants.EMBEDDABLE ) ) {
|
||||
return true;
|
||||
}
|
||||
final TypeMirror serializableType =
|
||||
context.getElementUtils()
|
||||
.getTypeElement(java.io.Serializable.class.getName())
|
||||
.asType();
|
||||
if ( context.getTypeUtils().isSubtype( typeElement.asType(), serializableType) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -93,6 +93,7 @@ public final class Constants {
|
|||
public static final String LIST_ATTRIBUTE = "jakarta.persistence.metamodel.ListAttribute";
|
||||
public static final String MAP_ATTRIBUTE = "jakarta.persistence.metamodel.MapAttribute";
|
||||
|
||||
public static final String JAVA_OBJECT = Object.class.getName();
|
||||
public static final String COLLECTION = java.util.Collection.class.getName();
|
||||
public static final String LIST = java.util.List.class.getName();
|
||||
public static final String MAP = java.util.Map.class.getName();
|
||||
|
|
|
@ -28,6 +28,8 @@ import javax.lang.model.util.SimpleTypeVisitor8;
|
|||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import static org.hibernate.jpamodelgen.util.Constants.JAVA_OBJECT;
|
||||
|
||||
/**
|
||||
* @author Christian Beikov
|
||||
*/
|
||||
|
@ -134,7 +136,7 @@ public final class TypeRenderingVisitor extends SimpleTypeVisitor8<@Nullable Obj
|
|||
if ( typeVariableElement instanceof TypeParameterElement ) {
|
||||
final TypeParameterElement typeParameter = (TypeParameterElement) typeVariableElement;
|
||||
sb.append( typeParameter );
|
||||
if ( !"java.lang.Object".equals( t.getUpperBound().toString() ) && visitedTypeVariables.add( t ) ) {
|
||||
if ( !JAVA_OBJECT.equals( t.getUpperBound().toString() ) && visitedTypeVariables.add( t ) ) {
|
||||
sb.append( " extends " );
|
||||
t.getUpperBound().accept( this, null );
|
||||
visitedTypeVariables.remove( t );
|
||||
|
|
|
@ -17,6 +17,7 @@ import javax.lang.model.element.AnnotationValue;
|
|||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ElementKind;
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
import javax.lang.model.element.Name;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.element.VariableElement;
|
||||
import javax.lang.model.type.ArrayType;
|
||||
|
@ -35,6 +36,7 @@ import org.hibernate.jpamodelgen.MetaModelGenerationException;
|
|||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import static org.hibernate.jpamodelgen.util.Constants.JAVA_OBJECT;
|
||||
import static org.hibernate.jpamodelgen.util.NullnessUtil.castNonNull;
|
||||
import static org.hibernate.jpamodelgen.util.StringUtil.isProperty;
|
||||
|
||||
|
@ -51,6 +53,9 @@ public final class TypeUtils {
|
|||
private static final Map<TypeKind, String> PRIMITIVE_WRAPPERS = new HashMap<>();
|
||||
private static final Map<TypeKind, String> PRIMITIVES = new HashMap<>();
|
||||
|
||||
private static final String PROPERTY = AccessType.PROPERTY.toString();
|
||||
private static final String FIELD = AccessType.FIELD.toString();
|
||||
|
||||
static {
|
||||
PRIMITIVE_WRAPPERS.put( TypeKind.CHAR, "Character" );
|
||||
|
||||
|
@ -131,7 +136,13 @@ public final class TypeUtils {
|
|||
}
|
||||
|
||||
private static @Nullable TypeMirror upperBound(@Nullable TypeMirror bound) {
|
||||
return bound == null || (bound.getKind() == TypeKind.DECLARED && bound.toString().equals("java.lang.Object")) ? null : bound;
|
||||
if ( bound !=null && bound.getKind() == TypeKind.DECLARED ) {
|
||||
final DeclaredType type = (DeclaredType) bound;
|
||||
return type.asElement().getSimpleName().contentEquals(JAVA_OBJECT) ? null : bound;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static @Nullable TypeMirror extractClosestRealType(TypeMirror type, Context context, Set<TypeVariable> beingVisited) {
|
||||
|
@ -316,20 +327,20 @@ public final class TypeUtils {
|
|||
}
|
||||
|
||||
public static TypeMirror getCollectionElementType(
|
||||
DeclaredType t, String fqNameOfReturnedType, @Nullable String explicitTargetEntityName, Context context) {
|
||||
DeclaredType type, String returnTupeName, @Nullable String explicitTargetEntityName, Context context) {
|
||||
if ( explicitTargetEntityName != null ) {
|
||||
return context.getElementUtils().getTypeElement( explicitTargetEntityName ).asType();
|
||||
}
|
||||
else {
|
||||
final List<? extends TypeMirror> typeArguments = t.getTypeArguments();
|
||||
if ( typeArguments.size() == 0 ) {
|
||||
final List<? extends TypeMirror> typeArguments = type.getTypeArguments();
|
||||
if ( typeArguments.isEmpty() ) {
|
||||
throw new MetaModelGenerationException( "Unable to determine collection type" );
|
||||
}
|
||||
else if ( Map.class.getCanonicalName().equals( fqNameOfReturnedType ) ) {
|
||||
return t.getTypeArguments().get( 1 );
|
||||
else if ( Map.class.getCanonicalName().equals( returnTupeName ) ) {
|
||||
return typeArguments.get( 1 );
|
||||
}
|
||||
else {
|
||||
return t.getTypeArguments().get( 0 );
|
||||
return typeArguments.get( 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -460,10 +471,11 @@ public final class TypeUtils {
|
|||
final Object accessType = getAnnotationValue( mirror, DEFAULT_ANNOTATION_PARAMETER_NAME );
|
||||
if ( accessType instanceof VariableElement) {
|
||||
final VariableElement enumValue = (VariableElement) accessType;
|
||||
if ( enumValue.getSimpleName().contentEquals( AccessType.PROPERTY.toString() ) ) {
|
||||
final Name enumValueName = enumValue.getSimpleName();
|
||||
if ( enumValueName.contentEquals(PROPERTY) ) {
|
||||
return AccessType.PROPERTY;
|
||||
}
|
||||
else if ( enumValue.getSimpleName().contentEquals( AccessType.FIELD.toString() ) ) {
|
||||
else if ( enumValueName.contentEquals(FIELD) ) {
|
||||
return AccessType.FIELD;
|
||||
}
|
||||
}
|
||||
|
@ -479,7 +491,7 @@ public final class TypeUtils {
|
|||
final List<? extends TypeMirror> typeArguments = type.getTypeArguments();
|
||||
if ( typeArguments.isEmpty() ) {
|
||||
context.logMessage( Diagnostic.Kind.ERROR, "Unable to determine type argument for " + type );
|
||||
return "java.lang.Object";
|
||||
return JAVA_OBJECT;
|
||||
}
|
||||
else {
|
||||
return extractClosestRealTypeAsString( typeArguments.get( 0 ), context );
|
||||
|
@ -493,6 +505,29 @@ public final class TypeUtils {
|
|||
return kind.isClass() && kind != ElementKind.ENUM;
|
||||
}
|
||||
|
||||
public static boolean primitiveClassMatchesKind(Class<?> itemType, TypeKind kind) {
|
||||
switch (kind) {
|
||||
case SHORT:
|
||||
return itemType.equals(Short.class);
|
||||
case INT:
|
||||
return itemType.equals(Integer.class);
|
||||
case LONG:
|
||||
return itemType.equals(Long.class);
|
||||
case BOOLEAN:
|
||||
return itemType.equals(Boolean.class);
|
||||
case FLOAT:
|
||||
return itemType.equals(Float.class);
|
||||
case DOUBLE:
|
||||
return itemType.equals(Double.class);
|
||||
case CHAR:
|
||||
return itemType.equals(Character.class);
|
||||
case BYTE:
|
||||
return itemType.equals(Byte.class);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static class EmbeddedAttributeVisitor extends SimpleTypeVisitor8<@Nullable String, Element> {
|
||||
private final Context context;
|
||||
|
||||
|
@ -510,11 +545,11 @@ public final class TypeUtils {
|
|||
}
|
||||
|
||||
@Override
|
||||
public @Nullable String visitExecutable(ExecutableType t, Element p) {
|
||||
if ( p.getKind().equals( ElementKind.METHOD ) ) {
|
||||
String string = p.getSimpleName().toString();
|
||||
return isProperty( string, toTypeString( t.getReturnType() ) )
|
||||
? t.getReturnType().accept(this, p)
|
||||
public @Nullable String visitExecutable(ExecutableType executable, Element element) {
|
||||
if ( element.getKind().equals( ElementKind.METHOD ) ) {
|
||||
final String string = element.getSimpleName().toString();
|
||||
return isProperty( string, toTypeString( executable.getReturnType() ) )
|
||||
? executable.getReturnType().accept(this, element)
|
||||
: null;
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -51,6 +51,7 @@ import static org.hibernate.internal.util.StringHelper.qualify;
|
|||
import static org.hibernate.internal.util.StringHelper.root;
|
||||
import static org.hibernate.internal.util.StringHelper.split;
|
||||
import static org.hibernate.internal.util.StringHelper.unroot;
|
||||
import static org.hibernate.jpamodelgen.util.Constants.JAVA_OBJECT;
|
||||
|
||||
/**
|
||||
* Implementation of the {@code Mock} objects based on standard
|
||||
|
@ -696,7 +697,7 @@ public abstract class ProcessorSessionFactory extends MockSessionFactory {
|
|||
List<? extends TypeMirror> typeArguments = declaredType.getTypeArguments();
|
||||
TypeMirror elementType = typeArguments.get(typeArguments.size()-1);
|
||||
return elementType==null
|
||||
? elementUtil.getTypeElement("java.lang.Object").asType()
|
||||
? elementUtil.getTypeElement(JAVA_OBJECT).asType()
|
||||
: elementType;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue