HHH-16633 clean up

This commit is contained in:
Gavin King 2023-07-09 15:21:51 +02:00
parent 87a320615c
commit 16b433ebf1
9 changed files with 405 additions and 513 deletions

View File

@ -19,7 +19,6 @@ import javax.lang.model.SourceVersion;
import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element; import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind; import javax.lang.model.element.ElementKind;
import javax.lang.model.element.Name;
import javax.lang.model.element.PackageElement; import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement; import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType; import javax.lang.model.type.DeclaredType;
@ -31,7 +30,6 @@ import javax.tools.Diagnostic;
import org.hibernate.jpamodelgen.annotation.AnnotationMetaEntity; import org.hibernate.jpamodelgen.annotation.AnnotationMetaEntity;
import org.hibernate.jpamodelgen.annotation.AnnotationMetaPackage; import org.hibernate.jpamodelgen.annotation.AnnotationMetaPackage;
import org.hibernate.jpamodelgen.annotation.ProcessLaterException;
import org.hibernate.jpamodelgen.model.Metamodel; import org.hibernate.jpamodelgen.model.Metamodel;
import org.hibernate.jpamodelgen.util.Constants; import org.hibernate.jpamodelgen.util.Constants;
import org.hibernate.jpamodelgen.util.StringUtil; import org.hibernate.jpamodelgen.util.StringUtil;
@ -179,7 +177,7 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
private void processClasses(RoundEnvironment roundEnvironment) { private void processClasses(RoundEnvironment roundEnvironment) {
for ( CharSequence elementName : new HashSet<>( context.getElementsToRedo() ) ) { for ( CharSequence elementName : new HashSet<>( context.getElementsToRedo() ) ) {
context.logMessage( Diagnostic.Kind.OTHER, "Redoing element: " + elementName ); context.logMessage( Diagnostic.Kind.OTHER, "Redoing element '" + elementName + "'" );
final TypeElement typeElement = context.getElementUtils().getTypeElement( elementName ); final TypeElement typeElement = context.getElementUtils().getTypeElement( elementName );
try { try {
final AnnotationMetaEntity metaEntity = final AnnotationMetaEntity metaEntity =
@ -193,19 +191,20 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
} }
for ( Element element : roundEnvironment.getRootElements() ) { for ( Element element : roundEnvironment.getRootElements() ) {
try {
if ( isJPAEntity( element ) ) { if ( isJPAEntity( element ) ) {
context.logMessage( Diagnostic.Kind.OTHER, "Processing annotated class " + element ); context.logMessage( Diagnostic.Kind.OTHER, "Processing annotated entity class '" + element + "'" );
handleRootElementAnnotationMirrors( element ); handleRootElementAnnotationMirrors( element );
} }
else if ( hasAuxiliaryAnnotations( element ) ) { else if ( hasAuxiliaryAnnotations( element ) ) {
context.logMessage( Diagnostic.Kind.OTHER, "Processing annotated class " + element ); context.logMessage( Diagnostic.Kind.OTHER, "Processing annotated class '" + element + "'" );
handleRootElementAuxiliaryAnnotationMirrors( element ); handleRootElementAuxiliaryAnnotationMirrors( element );
} }
else if ( element instanceof TypeElement ) { else if ( element instanceof TypeElement ) {
final TypeElement typeElement = (TypeElement) element; final TypeElement typeElement = (TypeElement) element;
try {
for ( Element member : typeElement.getEnclosedElements() ) { for ( Element member : typeElement.getEnclosedElements() ) {
if ( containsAnnotation( member, HQL, SQL, FIND ) ) { if ( containsAnnotation( member, HQL, SQL, FIND ) ) {
context.logMessage( Diagnostic.Kind.OTHER, "Processing annotated class '" + element + "'" );
final AnnotationMetaEntity metaEntity = final AnnotationMetaEntity metaEntity =
AnnotationMetaEntity.create( typeElement, context, false ); AnnotationMetaEntity.create( typeElement, context, false );
context.addMetaAuxiliary( metaEntity.getQualifiedName(), metaEntity ); context.addMetaAuxiliary( metaEntity.getQualifiedName(), metaEntity );
@ -213,13 +212,14 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
} }
} }
} }
catch (ProcessLaterException processLaterException) { }
final Name qualifiedName = typeElement.getQualifiedName(); catch ( ProcessLaterException processLaterException ) {
if ( element instanceof TypeElement ) {
context.logMessage( context.logMessage(
Diagnostic.Kind.OTHER, Diagnostic.Kind.OTHER,
"Could not process: " + qualifiedName + " (will redo in next round)" "Could not process '" + element + "' (will redo in next round)"
); );
context.addElementToRedo( qualifiedName ); context.addElementToRedo( ( (TypeElement) element).getQualifiedName() );
} }
} }
} }
@ -231,7 +231,7 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
if ( context.isAlreadyGenerated( aux.getQualifiedName() ) ) { if ( context.isAlreadyGenerated( aux.getQualifiedName() ) ) {
continue; continue;
} }
context.logMessage( Diagnostic.Kind.OTHER, "Writing meta model for auxiliary " + aux ); context.logMessage( Diagnostic.Kind.OTHER, "Writing metamodel for auxiliary '" + aux + "'" );
ClassWriter.writeFile( aux, context ); ClassWriter.writeFile( aux, context );
context.markGenerated( aux.getQualifiedName() ); context.markGenerated( aux.getQualifiedName() );
} }
@ -240,7 +240,7 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
if ( context.isAlreadyGenerated( entity.getQualifiedName() ) ) { if ( context.isAlreadyGenerated( entity.getQualifiedName() ) ) {
continue; continue;
} }
context.logMessage( Diagnostic.Kind.OTHER, "Writing meta model for entity " + entity ); context.logMessage( Diagnostic.Kind.OTHER, "Writing metamodel for entity '" + entity + "'" );
ClassWriter.writeFile( entity, context ); ClassWriter.writeFile( entity, context );
context.markGenerated( entity.getQualifiedName() ); context.markGenerated( entity.getQualifiedName() );
} }
@ -261,7 +261,8 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
continue; continue;
} }
context.logMessage( context.logMessage(
Diagnostic.Kind.OTHER, "Writing meta model for embeddable/mapped superclass" + entity Diagnostic.Kind.OTHER,
"Writing meta model for embeddable/mapped superclass " + entity
); );
ClassWriter.writeFile( entity, context ); ClassWriter.writeFile( entity, context );
context.markGenerated( entity.getQualifiedName() ); context.markGenerated( entity.getQualifiedName() );
@ -270,7 +271,8 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
toProcessEntities.removeAll( processedEntities ); toProcessEntities.removeAll( processedEntities );
if ( toProcessEntities.size() >= toProcessCountBeforeLoop ) { if ( toProcessEntities.size() >= toProcessCountBeforeLoop ) {
context.logMessage( context.logMessage(
Diagnostic.Kind.ERROR, "Potential endless loop in generation of entities." Diagnostic.Kind.ERROR,
"Potential endless loop in generation of entities."
); );
} }
} }
@ -339,22 +341,22 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
private void handleRootElementAnnotationMirrors(final Element element) { private void handleRootElementAnnotationMirrors(final Element element) {
for ( AnnotationMirror mirror : element.getAnnotationMirrors() ) { for ( AnnotationMirror mirror : element.getAnnotationMirrors() ) {
if ( element.getKind() == ElementKind.CLASS ) { if ( element.getKind() == ElementKind.CLASS ) {
final String fqn = ( (TypeElement) element ).getQualifiedName().toString(); final String qualifiedName = ( (TypeElement) element ).getQualifiedName().toString();
final Metamodel alreadyExistingMetaEntity = tryGettingExistingEntityFromContext( mirror, fqn ); final Metamodel alreadyExistingMetaEntity = tryGettingExistingEntityFromContext( mirror, qualifiedName );
if ( alreadyExistingMetaEntity != null && alreadyExistingMetaEntity.isMetaComplete() ) { if ( alreadyExistingMetaEntity != null && alreadyExistingMetaEntity.isMetaComplete() ) {
String msg = "Skipping processing of annotations for " + fqn + " since xml configuration is metadata complete."; context.logMessage(
context.logMessage( Diagnostic.Kind.OTHER, msg ); Diagnostic.Kind.OTHER,
"Skipping processing of annotations for '" + qualifiedName
+ "' since xml configuration is metadata complete.");
} }
else { else {
boolean requiresLazyMemberInitialization = false; boolean requiresLazyMemberInitialization = false;
AnnotationMetaEntity metaEntity;
if ( containsAnnotation( element, Constants.EMBEDDABLE ) || if ( containsAnnotation( element, Constants.EMBEDDABLE ) ||
containsAnnotation( element, Constants.MAPPED_SUPERCLASS ) ) { containsAnnotation( element, Constants.MAPPED_SUPERCLASS ) ) {
requiresLazyMemberInitialization = true; requiresLazyMemberInitialization = true;
} }
final AnnotationMetaEntity metaEntity =
metaEntity = AnnotationMetaEntity.create( (TypeElement) element, context, requiresLazyMemberInitialization ); AnnotationMetaEntity.create( (TypeElement) element, context, requiresLazyMemberInitialization );
if ( alreadyExistingMetaEntity != null ) { if ( alreadyExistingMetaEntity != null ) {
metaEntity.mergeInMembers( alreadyExistingMetaEntity ); metaEntity.mergeInMembers( alreadyExistingMetaEntity );
} }
@ -378,14 +380,14 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
//TODO: handle PackageElement //TODO: handle PackageElement
} }
private @Nullable Metamodel tryGettingExistingEntityFromContext(AnnotationMirror mirror, String fqn) { private @Nullable Metamodel tryGettingExistingEntityFromContext(AnnotationMirror mirror, String qualifiedName) {
Metamodel alreadyExistingMetaEntity = null; Metamodel alreadyExistingMetaEntity = null;
if ( isAnnotationMirrorOfType( mirror, Constants.ENTITY ) if ( isAnnotationMirrorOfType( mirror, Constants.ENTITY )
|| isAnnotationMirrorOfType( mirror, Constants.MAPPED_SUPERCLASS ) ) { || isAnnotationMirrorOfType( mirror, Constants.MAPPED_SUPERCLASS ) ) {
alreadyExistingMetaEntity = context.getMetaEntity( fqn ); alreadyExistingMetaEntity = context.getMetaEntity( qualifiedName );
} }
else if ( isAnnotationMirrorOfType( mirror, Constants.EMBEDDABLE ) ) { else if ( isAnnotationMirrorOfType( mirror, Constants.EMBEDDABLE ) ) {
alreadyExistingMetaEntity = context.getMetaEmbeddable( fqn ); alreadyExistingMetaEntity = context.getMetaEmbeddable( qualifiedName );
} }
return alreadyExistingMetaEntity; return alreadyExistingMetaEntity;
} }

View File

@ -4,7 +4,7 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later. * 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>. * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/ */
package org.hibernate.jpamodelgen.annotation; package org.hibernate.jpamodelgen;
public class ProcessLaterException extends RuntimeException { public class ProcessLaterException extends RuntimeException {
} }

View File

@ -0,0 +1,198 @@
/*
* 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.internal.util.StringHelper;
import org.hibernate.jpamodelgen.model.MetaAttribute;
import org.hibernate.jpamodelgen.model.Metamodel;
import org.hibernate.jpamodelgen.util.Constants;
import java.util.List;
import java.util.Locale;
import static org.hibernate.jpamodelgen.util.StringUtil.getUpperUnderscoreCaseFromLowerCamelCase;
/**
* @author Gavin King
*/
public abstract class AbstractFinderMethod implements MetaAttribute {
final Metamodel annotationMetaEntity;
final String methodName;
final String entity;
final boolean belongsToDao;
final String sessionType;
final boolean usingEntityManager;
final List<String> fetchProfiles;
final List<String> paramNames;
final List<String> paramTypes;
public AbstractFinderMethod(
Metamodel annotationMetaEntity,
String methodName,
String entity,
boolean belongsToDao,
String sessionType,
List<String> fetchProfiles, List<String> paramNames, List<String> paramTypes) {
this.annotationMetaEntity = annotationMetaEntity;
this.methodName = methodName;
this.entity = entity;
this.belongsToDao = belongsToDao;
this.sessionType = sessionType;
this.fetchProfiles = fetchProfiles;
this.paramNames = paramNames;
this.paramTypes = paramTypes;
usingEntityManager = Constants.ENTITY_MANAGER.equals(sessionType);
}
@Override
public boolean hasTypedAttribute() {
return true;
}
@Override
public boolean hasStringAttribute() {
return false;
}
@Override
public String getMetaType() {
throw new UnsupportedOperationException();
}
@Override
public String getPropertyName() {
return methodName;
}
@Override
public String getTypeDeclaration() {
return entity;
}
@Override
public Metamodel getHostingEntity() {
return annotationMetaEntity;
}
@Override
public String getAttributeNameDeclarationString() {
return new StringBuilder()
.append("public static final String ")
.append(constantName())
.append(" = \"!")
.append(annotationMetaEntity.getQualifiedName())
.append('.')
.append(methodName)
.append("(")
.append(parameterList())
.append(")")
.append("\";")
.toString();
}
private String parameterList() {
return paramTypes.stream()
.map(this::strip)
.map(annotationMetaEntity::importType)
.reduce((x, y) -> x + ',' + y)
.orElse("");
}
private String strip(String type) {
int index = type.indexOf("<");
String stripped = index > 0 ? type.substring(0, index) : type;
return type.endsWith("...") ? stripped + "..." : stripped;
}
String constantName() {
return getUpperUnderscoreCaseFromLowerCamelCase(methodName) + "_BY_"
+ paramNames.stream()
.map(StringHelper::unqualify)
.map(name -> name.toUpperCase(Locale.ROOT))
.reduce((x,y) -> x + "_AND_" + y)
.orElse("");
}
void comment(StringBuilder declaration) {
declaration
.append("\n/**\n * @see ")
.append(annotationMetaEntity.getQualifiedName())
.append("#")
.append(methodName)
.append("(")
.append(parameterList())
.append(")")
.append("\n **/\n");
}
void unwrapSession(StringBuilder declaration) {
if ( usingEntityManager ) {
declaration
.append(".unwrap(")
.append(annotationMetaEntity.importType(Constants.HIB_SESSION))
.append(".class)\n\t\t\t");
}
}
void enableFetchProfile(StringBuilder declaration) {
// if ( !usingEntityManager ) {
// declaration
// .append("\n\t\t\t.enableFetchProfile(")
// .append(constantName())
// .append(")");
// }
// currently unused: no way to specify explicit fetch profiles
for ( String profile : fetchProfiles ) {
declaration
.append("\n\t\t\t.enableFetchProfile(")
.append(profile)
.append(")");
}
}
void preamble(StringBuilder declaration) {
modifiers( declaration );
declaration
.append(annotationMetaEntity.importType(entity));
declaration
.append(" ")
.append(methodName);
parameters( declaration) ;
declaration
.append(" {")
.append("\n\treturn entityManager");
}
void modifiers(StringBuilder declaration) {
declaration
.append(belongsToDao ? "@Override\npublic " : "public static ");
}
void parameters(StringBuilder declaration) {
declaration
.append("(");
if ( !belongsToDao ) {
declaration
.append(annotationMetaEntity.importType(Constants.ENTITY_MANAGER))
.append(" entityManager");
}
for ( int i = 0; i < paramNames.size(); i ++ ) {
if ( !belongsToDao || i > 0 ) {
declaration
.append(", ");
}
declaration
.append(annotationMetaEntity.importType(paramTypes.get(i)))
.append(" ")
.append(paramNames.get(i));
}
declaration
.append(')');
}
}

View File

@ -13,7 +13,8 @@ import javax.lang.model.util.Elements;
import org.hibernate.jpamodelgen.model.MetaAttribute; import org.hibernate.jpamodelgen.model.MetaAttribute;
import org.hibernate.jpamodelgen.model.Metamodel; import org.hibernate.jpamodelgen.model.Metamodel;
import org.hibernate.jpamodelgen.util.StringUtil;
import static org.hibernate.jpamodelgen.util.StringUtil.getUpperUnderscoreCaseFromLowerCamelCase;
/** /**
* Captures all information about an annotated persistent attribute. * Captures all information about an annotated persistent attribute.
@ -70,7 +71,7 @@ public abstract class AnnotationMetaAttribute implements MetaAttribute {
.append("public static final ") .append("public static final ")
.append(parent.importType(String.class.getName())) .append(parent.importType(String.class.getName()))
.append(" ") .append(" ")
.append(StringUtil.getUpperUnderscoreCaseFromLowerCamelCase(getPropertyName())) .append(getUpperUnderscoreCaseFromLowerCamelCase(getPropertyName()))
.append(" = ") .append(" = ")
.append("\"") .append("\"")
.append(getPropertyName()) .append(getPropertyName())

View File

@ -11,15 +11,7 @@ import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.*;
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.Modifier;
import javax.lang.model.element.Name;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.DeclaredType; import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.ExecutableType; import javax.lang.model.type.ExecutableType;
import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeKind;
@ -32,6 +24,7 @@ import org.hibernate.Session;
import org.hibernate.StatelessSession; import org.hibernate.StatelessSession;
import org.hibernate.jpamodelgen.Context; import org.hibernate.jpamodelgen.Context;
import org.hibernate.jpamodelgen.ImportContextImpl; import org.hibernate.jpamodelgen.ImportContextImpl;
import org.hibernate.jpamodelgen.ProcessLaterException;
import org.hibernate.jpamodelgen.model.ImportContext; import org.hibernate.jpamodelgen.model.ImportContext;
import org.hibernate.jpamodelgen.model.MetaAttribute; import org.hibernate.jpamodelgen.model.MetaAttribute;
import org.hibernate.jpamodelgen.model.Metamodel; import org.hibernate.jpamodelgen.model.Metamodel;
@ -712,32 +705,4 @@ public class AnnotationMetaEntity extends AnnotationMeta {
&& !isPageParam(type) && !isPageParam(type)
&& !isOrderParam(type); && !isOrderParam(type);
} }
// private void checkHqlSyntax(ExecutableElement method, AnnotationMirror mirror, String queryString) {
// final ANTLRErrorListener errorListener = new ErrorHandler( method, mirror, queryString );
// final HqlLexer hqlLexer = HqlParseTreeBuilder.INSTANCE.buildHqlLexer( queryString );
// final HqlParser hqlParser = HqlParseTreeBuilder.INSTANCE.buildHqlParser( queryString, hqlLexer );
// hqlLexer.addErrorListener( errorListener );
// hqlParser.getInterpreter().setPredictionMode( PredictionMode.SLL );
// hqlParser.removeErrorListeners();
// hqlParser.addErrorListener( errorListener );
// hqlParser.setErrorHandler( new BailErrorStrategy() );
//
// try {
// hqlParser.statement();
// }
// catch ( ParseCancellationException e) {
// // reset the input token stream and parser state
// hqlLexer.reset();
// hqlParser.reset();
//
// // fall back to LL(k)-based parsing
// hqlParser.getInterpreter().setPredictionMode( PredictionMode.LL );
// hqlParser.setErrorHandler( new DefaultErrorStrategy() );
//
// hqlParser.statement();
// }
// }
} }

View File

@ -7,7 +7,6 @@
package org.hibernate.jpamodelgen.annotation; package org.hibernate.jpamodelgen.annotation;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import org.hibernate.jpamodelgen.model.MetaAttribute;
import org.hibernate.jpamodelgen.model.Metamodel; import org.hibernate.jpamodelgen.model.Metamodel;
import org.hibernate.jpamodelgen.util.Constants; import org.hibernate.jpamodelgen.util.Constants;
@ -16,16 +15,9 @@ import java.util.List;
/** /**
* @author Gavin King * @author Gavin King
*/ */
public class CriteriaFinderMethod implements MetaAttribute { public class CriteriaFinderMethod extends AbstractFinderMethod {
private final Metamodel annotationMetaEntity;
private final String methodName;
private final String entity;
private final @Nullable String containerType; private final @Nullable String containerType;
private final List<String> paramNames;
private final List<String> paramTypes;
private final boolean belongsToDao;
private final String sessionType;
private final List<String> fetchProfiles;
public CriteriaFinderMethod( public CriteriaFinderMethod(
Metamodel annotationMetaEntity, Metamodel annotationMetaEntity,
@ -35,79 +27,23 @@ public class CriteriaFinderMethod implements MetaAttribute {
boolean belongsToDao, boolean belongsToDao,
String sessionType, String sessionType,
List<String> fetchProfiles) { List<String> fetchProfiles) {
this.annotationMetaEntity = annotationMetaEntity; super( annotationMetaEntity, methodName, entity, belongsToDao, sessionType, fetchProfiles,
this.methodName = methodName; paramNames, paramTypes );
this.entity = entity;
this.containerType = containerType; this.containerType = containerType;
this.paramNames = paramNames;
this.paramTypes = paramTypes;
this.belongsToDao = belongsToDao;
this.sessionType = sessionType;
this.fetchProfiles = fetchProfiles;
}
@Override
public boolean hasTypedAttribute() {
return true;
}
@Override
public boolean hasStringAttribute() {
return false;
} }
@Override @Override
public String getAttributeDeclarationString() { public String getAttributeDeclarationString() {
final boolean usingEntityManager = Constants.ENTITY_MANAGER.equals(sessionType); final StringBuilder declaration = new StringBuilder();
comment( declaration );
StringBuilder declaration = new StringBuilder(); modifiers( declaration );
declaration declaration
.append("\n/**\n * @see ") .append(returnType())
.append(annotationMetaEntity.getQualifiedName())
.append("#")
.append(methodName)
.append("(")
.append(parameterList())
.append(")")
.append("\n **/\n");
if ( belongsToDao ) {
declaration
.append("@Override\npublic ");
}
else {
declaration
.append("public static ");
}
StringBuilder type = new StringBuilder();
if ( containerType != null ) {
type.append(annotationMetaEntity.importType(containerType)).append('<');
}
type.append(annotationMetaEntity.importType(entity));
if ( containerType != null ) {
type.append('>');
}
declaration
.append(type)
.append(" ") .append(" ")
.append(methodName) .append(methodName);
.append("("); parameters( declaration );
if ( !belongsToDao ) {
declaration declaration
.append(annotationMetaEntity.importType(Constants.ENTITY_MANAGER)) .append(" {")
.append(" entityManager");
}
for ( int i = 0; i < paramNames.size(); i ++ ) {
if ( !belongsToDao || i > 0 ) {
declaration
.append(", ");
}
declaration
.append(annotationMetaEntity.importType(paramTypes.get(i)))
.append(" ")
.append(paramNames.get(i));
}
declaration
.append(") {")
.append("\n\tvar builder = entityManager") .append("\n\tvar builder = entityManager")
.append(usingEntityManager .append(usingEntityManager
? ".getEntityManagerFactory()" ? ".getEntityManagerFactory()"
@ -125,22 +61,23 @@ public class CriteriaFinderMethod implements MetaAttribute {
declaration declaration
.append(", "); .append(", ");
} }
final String paramName = paramNames.get(i);
declaration declaration
.append("\n\t\t\tbuilder.equal(entity.get(") .append("\n\t\t\tbuilder.equal(entity.get(")
.append(annotationMetaEntity.importType(entity+'_')) .append(annotationMetaEntity.importType(entity + '_'))
.append('.') .append('.')
.append(paramNames.get(i)) .append(paramName)
.append("), ") .append("), ")
//TODO: only safe if we are binding literals as parameters!!! //TODO: only safe if we are binding literals as parameters!!!
.append(paramNames.get(i)) .append(paramName)
.append(")"); .append(")");
} }
declaration declaration
.append("\n\t);") .append("\n\t);")
.append("\n\treturn entityManager.createQuery(query)"); .append("\n\treturn entityManager.createQuery(query)");
boolean hasEnabledFetchProfiles = !fetchProfiles.isEmpty(); final boolean hasEnabledFetchProfiles = !fetchProfiles.isEmpty();
boolean hasNativeReturnType = containerType != null && containerType.startsWith("org.hibernate"); final boolean hasNativeReturnType = containerType != null && containerType.startsWith("org.hibernate");
boolean unwrap = final boolean unwrap =
( hasEnabledFetchProfiles || hasNativeReturnType ) ( hasEnabledFetchProfiles || hasNativeReturnType )
&& usingEntityManager; && usingEntityManager;
if ( unwrap ) { if ( unwrap ) {
@ -149,12 +86,7 @@ public class CriteriaFinderMethod implements MetaAttribute {
.append(annotationMetaEntity.importType(Constants.HIB_SELECTION_QUERY)) .append(annotationMetaEntity.importType(Constants.HIB_SELECTION_QUERY))
.append(".class)"); .append(".class)");
} }
for ( String profile : fetchProfiles ) { enableFetchProfile( declaration );
declaration
.append("\n\t\t\t.enableFetchProfile(")
.append(profile)
.append(")");
}
if ( containerType == null) { if ( containerType == null) {
if ( unwrap || hasEnabledFetchProfiles) { if ( unwrap || hasEnabledFetchProfiles) {
declaration.append("\n\t\t\t"); declaration.append("\n\t\t\t");
@ -174,42 +106,16 @@ public class CriteriaFinderMethod implements MetaAttribute {
return declaration.toString(); return declaration.toString();
} }
private String parameterList() { private StringBuilder returnType() {
return paramTypes.stream() StringBuilder type = new StringBuilder();
.map(this::strip) if ( containerType != null ) {
.map(annotationMetaEntity::importType) type.append(annotationMetaEntity.importType(containerType)).append('<');
.reduce((x, y) -> x + y) }
.orElse(""); type.append(annotationMetaEntity.importType(entity));
if ( containerType != null ) {
type.append('>');
}
return type;
} }
private String strip(String type) {
int index = type.indexOf("<");
String stripped = index > 0 ? type.substring(0, index) : type;
return type.endsWith("...") ? stripped + "..." : stripped;
}
@Override
public String getAttributeNameDeclarationString() {
throw new UnsupportedOperationException();
}
@Override
public String getMetaType() {
throw new UnsupportedOperationException();
}
@Override
public String getPropertyName() {
return methodName;
}
@Override
public String getTypeDeclaration() {
return entity;
}
@Override
public Metamodel getHostingEntity() {
return annotationMetaEntity;
}
} }

View File

@ -6,7 +6,6 @@
*/ */
package org.hibernate.jpamodelgen.annotation; package org.hibernate.jpamodelgen.annotation;
import org.hibernate.jpamodelgen.model.MetaAttribute;
import org.hibernate.jpamodelgen.model.Metamodel; import org.hibernate.jpamodelgen.model.Metamodel;
import org.hibernate.jpamodelgen.util.Constants; import org.hibernate.jpamodelgen.util.Constants;
@ -15,15 +14,9 @@ import java.util.List;
/** /**
* @author Gavin King * @author Gavin King
*/ */
public class IdFinderMethod implements MetaAttribute { public class IdFinderMethod extends AbstractFinderMethod {
private final Metamodel annotationMetaEntity;
private final String methodName;
private final String entity;
private final String paramName; private final String paramName;
private final String paramType;
private final boolean belongsToDao;
private final String sessionType;
private final List<String> fetchProfiles;
public IdFinderMethod( public IdFinderMethod(
Metamodel annotationMetaEntity, Metamodel annotationMetaEntity,
@ -32,68 +25,20 @@ public class IdFinderMethod implements MetaAttribute {
boolean belongsToDao, boolean belongsToDao,
String sessionType, String sessionType,
List<String> fetchProfiles) { List<String> fetchProfiles) {
this.annotationMetaEntity = annotationMetaEntity; super( annotationMetaEntity, methodName, entity, belongsToDao, sessionType, fetchProfiles,
this.methodName = methodName; List.of(paramName), List.of(paramType) );
this.entity = entity;
this.paramName = paramName; this.paramName = paramName;
this.paramType = paramType;
this.belongsToDao = belongsToDao;
this.sessionType = sessionType;
this.fetchProfiles = fetchProfiles;
}
@Override
public boolean hasTypedAttribute() {
return true;
}
@Override
public boolean hasStringAttribute() {
return false;
} }
@Override @Override
public String getAttributeDeclarationString() { public String getAttributeDeclarationString() {
final boolean usingEntityManager = Constants.ENTITY_MANAGER.equals(sessionType); final StringBuilder declaration = new StringBuilder();
comment( declaration );
StringBuilder declaration = new StringBuilder(); preamble( declaration );
final boolean usingStatelessSession = Constants.HIB_STATELESS_SESSION.equals(sessionType);
if ( usingStatelessSession || usingEntityManager && fetchProfiles.isEmpty() ) {
declaration declaration
.append("\n/**\n * @see ") .append(usingStatelessSession ? ".get(" : ".find(")
.append(annotationMetaEntity.getQualifiedName())
.append("#")
.append(methodName)
.append("(")
.append(annotationMetaEntity.importType(paramType))
.append(")")
.append("\n **/\n");
if ( belongsToDao ) {
declaration
.append("@Override\npublic ");
}
else {
declaration
.append("public static ");
}
declaration
.append(annotationMetaEntity.importType(entity));
declaration
.append(" ")
.append(methodName)
.append("(");
if ( !belongsToDao ) {
declaration
.append(annotationMetaEntity.importType(Constants.ENTITY_MANAGER))
.append(" entityManager, ");
}
declaration
.append(annotationMetaEntity.importType(paramType))
.append(" ")
.append(paramName)
.append(") {")
.append("\n\treturn entityManager");
if ( fetchProfiles.isEmpty() ) {
declaration
.append(Constants.HIB_STATELESS_SESSION.equals(sessionType) ? ".get(" : ".find(")
.append(annotationMetaEntity.importType(entity)) .append(annotationMetaEntity.importType(entity))
.append(".class, ") .append(".class, ")
.append(paramName) .append(paramName)
@ -101,22 +46,12 @@ public class IdFinderMethod implements MetaAttribute {
.append("\n}"); .append("\n}");
} }
else { else {
if ( usingEntityManager ) { unwrapSession( declaration );
declaration
.append(".unwrap(")
.append(annotationMetaEntity.importType(Constants.HIB_SESSION))
.append(".class)\n\t\t\t");
}
declaration declaration
.append(".byId(") .append(".byId(")
.append(annotationMetaEntity.importType(entity)) .append(annotationMetaEntity.importType(entity))
.append(".class)"); .append(".class)");
for ( String profile : fetchProfiles ) { enableFetchProfile( declaration );
declaration
.append("\n\t\t\t.enableFetchProfile(")
.append(profile)
.append(")");
}
declaration declaration
.append("\n\t\t\t.load(") .append("\n\t\t\t.load(")
.append(paramName) .append(paramName)
@ -125,29 +60,4 @@ public class IdFinderMethod implements MetaAttribute {
} }
return declaration.toString(); return declaration.toString();
} }
@Override
public String getAttributeNameDeclarationString() {
throw new UnsupportedOperationException();
}
@Override
public String getMetaType() {
throw new UnsupportedOperationException();
}
@Override
public String getPropertyName() {
return methodName;
}
@Override
public String getTypeDeclaration() {
return entity;
}
@Override
public Metamodel getHostingEntity() {
return annotationMetaEntity;
}
} }

View File

@ -6,24 +6,14 @@
*/ */
package org.hibernate.jpamodelgen.annotation; package org.hibernate.jpamodelgen.annotation;
import org.hibernate.jpamodelgen.model.MetaAttribute;
import org.hibernate.jpamodelgen.model.Metamodel; import org.hibernate.jpamodelgen.model.Metamodel;
import org.hibernate.jpamodelgen.util.Constants;
import java.util.List; import java.util.List;
/** /**
* @author Gavin King * @author Gavin King
*/ */
public class NaturalIdFinderMethod implements MetaAttribute { public class NaturalIdFinderMethod extends AbstractFinderMethod {
private final Metamodel annotationMetaEntity;
private final String methodName;
private final String entity;
private final List<String> paramNames;
private final List<String> paramTypes;
private final boolean belongsToDao;
private final String sessionType;
private final List<String> fetchProfiles;
public NaturalIdFinderMethod( public NaturalIdFinderMethod(
Metamodel annotationMetaEntity, Metamodel annotationMetaEntity,
@ -32,94 +22,30 @@ public class NaturalIdFinderMethod implements MetaAttribute {
boolean belongsToDao, boolean belongsToDao,
String sessionType, String sessionType,
List<String> fetchProfiles) { List<String> fetchProfiles) {
this.annotationMetaEntity = annotationMetaEntity; super( annotationMetaEntity, methodName, entity, belongsToDao, sessionType, fetchProfiles,
this.methodName = methodName; paramNames, paramTypes );
this.entity = entity;
this.paramNames = paramNames;
this.paramTypes = paramTypes;
this.belongsToDao = belongsToDao;
this.sessionType = sessionType;
this.fetchProfiles = fetchProfiles;
}
@Override
public boolean hasTypedAttribute() {
return true;
}
@Override
public boolean hasStringAttribute() {
return false;
} }
@Override @Override
public String getAttributeDeclarationString() { public String getAttributeDeclarationString() {
StringBuilder declaration = new StringBuilder(); final StringBuilder declaration = new StringBuilder();
declaration comment( declaration );
.append("\n/**\n * @see ") preamble( declaration );
.append(annotationMetaEntity.getQualifiedName()) unwrapSession( declaration );
.append("#")
.append(methodName)
.append("(")
.append(parameterList())
.append(")")
.append("\n **/\n");
if ( belongsToDao ) {
declaration
.append("@Override\npublic ");
}
else {
declaration
.append("public static ");
}
declaration
.append(annotationMetaEntity.importType(entity));
declaration
.append(" ")
.append(methodName)
.append("(");
if ( !belongsToDao ) {
declaration
.append(annotationMetaEntity.importType(Constants.ENTITY_MANAGER))
.append(" entityManager");
}
for ( int i = 0; i < paramNames.size(); i ++ ) {
if ( !belongsToDao || i > 0 ) {
declaration
.append(", ");
}
declaration
.append(annotationMetaEntity.importType(paramTypes.get(i)))
.append(" ")
.append(paramNames.get(i));
}
declaration
.append(") {")
.append("\n\treturn entityManager");
if ( Constants.ENTITY_MANAGER.equals(sessionType) ) {
declaration
.append(".unwrap(")
.append(annotationMetaEntity.importType(Constants.HIB_SESSION))
.append(".class)\n\t\t\t");
}
declaration declaration
.append(".byNaturalId(") .append(".byNaturalId(")
.append(annotationMetaEntity.importType(entity)) .append(annotationMetaEntity.importType(entity))
.append(".class)"); .append(".class)");
enableFetchProfile( declaration );
for ( int i = 0; i < paramNames.size(); i ++ ) { for ( int i = 0; i < paramNames.size(); i ++ ) {
final String paramName = paramNames.get(i);
declaration declaration
.append("\n\t\t\t.using(") .append("\n\t\t\t.using(")
.append(annotationMetaEntity.importType(entity+'_')) .append(annotationMetaEntity.importType(entity + '_'))
.append('.') .append('.')
.append(paramNames.get(i)) .append(paramName)
.append(", ") .append(", ")
.append(paramNames.get(i)) .append(paramName)
.append(")");
}
for ( String profile : fetchProfiles ) {
declaration
.append("\n\t\t\t.enableFetchProfile(")
.append(profile)
.append(")"); .append(")");
} }
declaration declaration
@ -127,42 +53,4 @@ public class NaturalIdFinderMethod implements MetaAttribute {
return declaration.toString(); return declaration.toString();
} }
private String parameterList() {
return paramTypes.stream()
.map(this::strip)
.map(annotationMetaEntity::importType)
.reduce((x, y) -> x + y)
.orElse("");
}
private String strip(String type) {
int index = type.indexOf("<");
String stripped = index > 0 ? type.substring(0, index) : type;
return type.endsWith("...") ? stripped + "..." : stripped;
}
@Override
public String getAttributeNameDeclarationString() {
throw new UnsupportedOperationException();
}
@Override
public String getMetaType() {
throw new UnsupportedOperationException();
}
@Override
public String getPropertyName() {
return methodName;
}
@Override
public String getTypeDeclaration() {
return entity;
}
@Override
public Metamodel getHostingEntity() {
return annotationMetaEntity;
}
} }

View File

@ -32,7 +32,7 @@ public class QueryMethod implements MetaAttribute {
private final List<String> paramTypes; private final List<String> paramTypes;
private final boolean isNative; private final boolean isNative;
private final boolean belongsToDao; private final boolean belongsToDao;
private final String sessionType; final boolean usingEntityManager;
public QueryMethod( public QueryMethod(
Metamodel annotationMetaEntity, Metamodel annotationMetaEntity,
@ -56,7 +56,7 @@ public class QueryMethod implements MetaAttribute {
this.paramTypes = paramTypes; this.paramTypes = paramTypes;
this.isNative = isNative; this.isNative = isNative;
this.belongsToDao = belongsToDao; this.belongsToDao = belongsToDao;
this.sessionType = sessionType; usingEntityManager = Constants.ENTITY_MANAGER.equals(sessionType);
} }
@Override @Override
@ -71,81 +71,17 @@ public class QueryMethod implements MetaAttribute {
@Override @Override
public String getAttributeDeclarationString() { public String getAttributeDeclarationString() {
final boolean usingEntityManager = Constants.ENTITY_MANAGER.equals(sessionType); final List<String> paramTypes = parameterTypes();
final StringBuilder returnType = returnType();
List<String> paramTypes = this.paramTypes.stream() final StringBuilder declaration = new StringBuilder();
.map(ptype -> isOrderParam(ptype) && ptype.endsWith("[]") comment( declaration );
? ptype.substring(0, ptype.length()-2) + "..." modifiers( paramTypes, declaration );
: ptype)
.collect(toList());
StringBuilder declaration = new StringBuilder();
declaration declaration
.append("\n/**\n * @see ") .append(returnType)
.append(annotationMetaEntity.getQualifiedName())
.append("#")
.append(methodName)
.append("(")
.append(parameterList())
.append(")")
.append("\n **/\n");
boolean hasVarargs = paramTypes.stream().anyMatch(ptype -> ptype.endsWith("..."));
if ( hasVarargs ) {
declaration
.append("@SafeVarargs\n");
}
if ( belongsToDao ) {
declaration
.append("@Override\npublic ");
if ( hasVarargs ) {
declaration
.append("final ");
}
}
else {
declaration
.append("public static ");
}
StringBuilder type = new StringBuilder();
if (containerTypeName != null) {
type.append(annotationMetaEntity.importType(containerTypeName));
if (returnTypeName != null) {
type.append("<")
.append(annotationMetaEntity.importType(returnTypeName)).append(">");
}
}
else if (returnTypeName != null) {
type.append(annotationMetaEntity.importType(returnTypeName));
}
declaration
.append(type)
.append(" ") .append(" ")
.append(methodName) .append(methodName);
.append("("); parameters( paramTypes, declaration );
if ( !belongsToDao ) {
declaration declaration
.append(annotationMetaEntity.importType(Constants.ENTITY_MANAGER))
.append(" entityManager");
}
for (int i = 0; i<paramNames.size(); i++ ) {
String ptype = paramTypes.get(i);
String param = paramNames.get(i);
String rptype = returnTypeName != null
? ptype.replace(returnTypeName, annotationMetaEntity.importType(returnTypeName))
: ptype;
if ( !belongsToDao || i>0 ) {
declaration
.append(", ");
}
declaration
.append(annotationMetaEntity.importType(rptype))
.append(" ")
.append(param);
}
declaration
.append(")")
.append(" {") .append(" {")
.append("\n\treturn "); .append("\n\treturn ");
if ( isNative && returnTypeName != null && containerTypeName == null if ( isNative && returnTypeName != null && containerTypeName == null
@ -153,7 +89,7 @@ public class QueryMethod implements MetaAttribute {
// EntityManager.createNativeQuery() does not return TypedQuery, // EntityManager.createNativeQuery() does not return TypedQuery,
// so we need to cast to the entity type // so we need to cast to the entity type
declaration.append("(") declaration.append("(")
.append(type) .append(returnType)
.append(") "); .append(") ");
} }
declaration declaration
@ -161,7 +97,7 @@ public class QueryMethod implements MetaAttribute {
.append(isNative ? "createNativeQuery" : "createQuery") .append(isNative ? "createNativeQuery" : "createQuery")
.append("(") .append("(")
.append(getConstantName()); .append(getConstantName());
if (returnTypeName != null) { if ( returnTypeName != null ) {
declaration declaration
.append(", ") .append(", ")
.append(annotationMetaEntity.importType(returnTypeName)) .append(annotationMetaEntity.importType(returnTypeName))
@ -170,47 +106,47 @@ public class QueryMethod implements MetaAttribute {
declaration.append(")"); declaration.append(")");
boolean unwrapped = !usingEntityManager; boolean unwrapped = !usingEntityManager;
for (int i = 1; i <= paramNames.size(); i++) { for (int i = 1; i <= paramNames.size(); i++) {
String param = paramNames.get(i-1); final String paramName = paramNames.get(i-1);
String ptype = paramTypes.get(i-1); final String paramType = paramTypes.get(i-1);
if (queryString.contains(":" + param)) { if ( queryString.contains(":" + paramName) ) {
declaration declaration
.append("\n\t\t\t.setParameter(\"") .append("\n\t\t\t.setParameter(\"")
.append(param) .append(paramName)
.append("\", ") .append("\", ")
.append(param) .append(paramName)
.append(")"); .append(")");
} }
else if (queryString.contains("?" + i)) { else if ( queryString.contains("?" + i) ) {
declaration declaration
.append("\n\t\t\t.setParameter(") .append("\n\t\t\t.setParameter(")
.append(i) .append(i)
.append(", ") .append(", ")
.append(param) .append(paramName)
.append(")"); .append(")");
} }
else if (isPageParam(ptype)) { else if ( isPageParam(paramType) ) {
unwrap( declaration, unwrapped ); unwrap( declaration, unwrapped );
unwrapped = true; unwrapped = true;
declaration declaration
.append("\n\t\t\t.setPage(") .append("\n\t\t\t.setPage(")
.append(param) .append(paramName)
.append(")"); .append(")");
} }
else if (isOrderParam(ptype)) { else if ( isOrderParam(paramType) ) {
unwrap( declaration, unwrapped ); unwrap( declaration, unwrapped );
unwrapped = true; unwrapped = true;
if (ptype.endsWith("...")) { if ( paramType.endsWith("...") ) {
declaration declaration
.append("\n\t\t\t.setOrder(") .append("\n\t\t\t.setOrder(")
.append(annotationMetaEntity.importType(List.class.getName())) .append(annotationMetaEntity.importType(List.class.getName()))
.append(".of(") .append(".of(")
.append(param) .append(paramName)
.append("))"); .append("))");
} }
else { else {
declaration declaration
.append("\n\t\t\t.setOrder(") .append("\n\t\t\t.setOrder(")
.append(param) .append(paramName)
.append(")"); .append(")");
} }
} }
@ -238,11 +174,95 @@ public class QueryMethod implements MetaAttribute {
return declaration.toString(); return declaration.toString();
} }
private void parameters(List<String> paramTypes, StringBuilder declaration) {
declaration.append("(");
if ( !belongsToDao ) {
declaration
.append(annotationMetaEntity.importType(Constants.ENTITY_MANAGER))
.append(" entityManager");
}
for (int i = 0; i<paramNames.size(); i++ ) {
String ptype = paramTypes.get(i);
String param = paramNames.get(i);
String rptype = returnTypeName != null
? ptype.replace(returnTypeName, annotationMetaEntity.importType(returnTypeName))
: ptype;
if ( !belongsToDao || i>0 ) {
declaration
.append(", ");
}
declaration
.append(annotationMetaEntity.importType(rptype))
.append(" ")
.append(param);
}
declaration
.append(")");
}
private StringBuilder returnType() {
StringBuilder type = new StringBuilder();
if ( containerTypeName != null ) {
type.append(annotationMetaEntity.importType(containerTypeName));
if ( returnTypeName != null ) {
type.append("<")
.append(annotationMetaEntity.importType(returnTypeName)).append(">");
}
}
else if ( returnTypeName != null ) {
type.append(annotationMetaEntity.importType(returnTypeName));
}
return type;
}
private List<String> parameterTypes() {
return paramTypes.stream()
.map(paramType -> isOrderParam(paramType) && paramType.endsWith("[]")
? paramType.substring(0, paramType.length() - 2) + "..."
: paramType)
.collect(toList());
}
private void comment(StringBuilder declaration) {
declaration
.append("\n/**\n * @see ")
.append(annotationMetaEntity.getQualifiedName())
.append("#")
.append(methodName)
.append("(")
.append(parameterList())
.append(")")
.append("\n **/\n");
}
private void modifiers(List<String> paramTypes, StringBuilder declaration) {
boolean hasVarargs = paramTypes.stream().anyMatch(ptype -> ptype.endsWith("..."));
if ( hasVarargs ) {
declaration
.append("@SafeVarargs\n");
}
if ( belongsToDao ) {
declaration
.append("@Override\npublic ");
if ( hasVarargs ) {
declaration
.append("final ");
}
}
else {
declaration
.append("public static ");
}
}
private String parameterList() { private String parameterList() {
return paramTypes.stream() return paramTypes.stream()
.map(this::strip) .map(this::strip)
.map(annotationMetaEntity::importType) .map(annotationMetaEntity::importType)
.reduce((x, y) -> x + y) .reduce((x, y) -> x + ',' + y)
.orElse(""); .orElse("");
} }
@ -273,7 +293,7 @@ public class QueryMethod implements MetaAttribute {
@Override @Override
public String getAttributeNameDeclarationString() { public String getAttributeNameDeclarationString() {
return new StringBuilder() return new StringBuilder()
.append("public static final String ") .append("static final String ")
.append(getConstantName()) .append(getConstantName())
.append(" = \"") .append(" = \"")
.append(queryString) .append(queryString)
@ -287,10 +307,12 @@ public class QueryMethod implements MetaAttribute {
return stem; return stem;
} }
else { else {
return stem + "_" + StringHelper.join("_", return stem + "_"
paramTypes.stream() + paramTypes.stream()
.filter(name -> !isPageParam(name) && !isOrderParam(name)) .filter(name -> !isPageParam(name) && !isOrderParam(name))
.map(StringHelper::unqualify).collect(toList())); .map(StringHelper::unqualify)
.reduce((x,y) -> x + '_' + y)
.orElse("");
} }
} }