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.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.Name;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
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.AnnotationMetaPackage;
import org.hibernate.jpamodelgen.annotation.ProcessLaterException;
import org.hibernate.jpamodelgen.model.Metamodel;
import org.hibernate.jpamodelgen.util.Constants;
import org.hibernate.jpamodelgen.util.StringUtil;
@ -179,7 +177,7 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
private void processClasses(RoundEnvironment roundEnvironment) {
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 );
try {
final AnnotationMetaEntity metaEntity =
@ -193,35 +191,37 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
}
for ( Element element : roundEnvironment.getRootElements() ) {
try {
if ( isJPAEntity( element ) ) {
context.logMessage( Diagnostic.Kind.OTHER, "Processing annotated class " + element );
context.logMessage( Diagnostic.Kind.OTHER, "Processing annotated entity class '" + element + "'" );
handleRootElementAnnotationMirrors( 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 );
}
else if ( element instanceof TypeElement ) {
final TypeElement typeElement = (TypeElement) element;
try {
for ( Element member : typeElement.getEnclosedElements() ) {
if ( containsAnnotation( member, HQL, SQL, FIND ) ) {
context.logMessage( Diagnostic.Kind.OTHER, "Processing annotated class '" + element + "'" );
final AnnotationMetaEntity metaEntity =
AnnotationMetaEntity.create( typeElement, context, false );
context.addMetaAuxiliary( metaEntity.getQualifiedName(), metaEntity );
break;
}
}
}
catch (ProcessLaterException processLaterException) {
final Name qualifiedName = typeElement.getQualifiedName();
context.logMessage(
Diagnostic.Kind.OTHER,
"Could not process: " + qualifiedName + " (will redo in next round)"
);
context.addElementToRedo( qualifiedName );
}
}
}
catch ( ProcessLaterException processLaterException ) {
if ( element instanceof TypeElement ) {
context.logMessage(
Diagnostic.Kind.OTHER,
"Could not process '" + element + "' (will redo in next round)"
);
context.addElementToRedo( ( (TypeElement) element).getQualifiedName() );
}
}
}
}
@ -231,7 +231,7 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
if ( context.isAlreadyGenerated( aux.getQualifiedName() ) ) {
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 );
context.markGenerated( aux.getQualifiedName() );
}
@ -240,7 +240,7 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
if ( context.isAlreadyGenerated( entity.getQualifiedName() ) ) {
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 );
context.markGenerated( entity.getQualifiedName() );
}
@ -261,7 +261,8 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
continue;
}
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 );
context.markGenerated( entity.getQualifiedName() );
@ -270,7 +271,8 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
toProcessEntities.removeAll( processedEntities );
if ( toProcessEntities.size() >= toProcessCountBeforeLoop ) {
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) {
for ( AnnotationMirror mirror : element.getAnnotationMirrors() ) {
if ( element.getKind() == ElementKind.CLASS ) {
final String fqn = ( (TypeElement) element ).getQualifiedName().toString();
final Metamodel alreadyExistingMetaEntity = tryGettingExistingEntityFromContext( mirror, fqn );
final String qualifiedName = ( (TypeElement) element ).getQualifiedName().toString();
final Metamodel alreadyExistingMetaEntity = tryGettingExistingEntityFromContext( mirror, qualifiedName );
if ( alreadyExistingMetaEntity != null && alreadyExistingMetaEntity.isMetaComplete() ) {
String msg = "Skipping processing of annotations for " + fqn + " since xml configuration is metadata complete.";
context.logMessage( Diagnostic.Kind.OTHER, msg );
context.logMessage(
Diagnostic.Kind.OTHER,
"Skipping processing of annotations for '" + qualifiedName
+ "' since xml configuration is metadata complete.");
}
else {
boolean requiresLazyMemberInitialization = false;
AnnotationMetaEntity metaEntity;
if ( containsAnnotation( element, Constants.EMBEDDABLE ) ||
containsAnnotation( element, Constants.MAPPED_SUPERCLASS ) ) {
requiresLazyMemberInitialization = true;
}
metaEntity = AnnotationMetaEntity.create( (TypeElement) element, context, requiresLazyMemberInitialization );
final AnnotationMetaEntity metaEntity =
AnnotationMetaEntity.create( (TypeElement) element, context, requiresLazyMemberInitialization );
if ( alreadyExistingMetaEntity != null ) {
metaEntity.mergeInMembers( alreadyExistingMetaEntity );
}
@ -378,14 +380,14 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
//TODO: handle PackageElement
}
private @Nullable Metamodel tryGettingExistingEntityFromContext(AnnotationMirror mirror, String fqn) {
private @Nullable Metamodel tryGettingExistingEntityFromContext(AnnotationMirror mirror, String qualifiedName) {
Metamodel alreadyExistingMetaEntity = null;
if ( isAnnotationMirrorOfType( mirror, Constants.ENTITY )
|| isAnnotationMirrorOfType( mirror, Constants.MAPPED_SUPERCLASS ) ) {
alreadyExistingMetaEntity = context.getMetaEntity( fqn );
alreadyExistingMetaEntity = context.getMetaEntity( qualifiedName );
}
else if ( isAnnotationMirrorOfType( mirror, Constants.EMBEDDABLE ) ) {
alreadyExistingMetaEntity = context.getMetaEmbeddable( fqn );
alreadyExistingMetaEntity = context.getMetaEmbeddable( qualifiedName );
}
return alreadyExistingMetaEntity;
}

View File

@ -4,7 +4,7 @@
* 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;
package org.hibernate.jpamodelgen;
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.Metamodel;
import org.hibernate.jpamodelgen.util.StringUtil;
import static org.hibernate.jpamodelgen.util.StringUtil.getUpperUnderscoreCaseFromLowerCamelCase;
/**
* Captures all information about an annotated persistent attribute.
@ -70,7 +71,7 @@ public abstract class AnnotationMetaAttribute implements MetaAttribute {
.append("public static final ")
.append(parent.importType(String.class.getName()))
.append(" ")
.append(StringUtil.getUpperUnderscoreCaseFromLowerCamelCase(getPropertyName()))
.append(getUpperUnderscoreCaseFromLowerCamelCase(getPropertyName()))
.append(" = ")
.append("\"")
.append(getPropertyName())

View File

@ -11,15 +11,7 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.lang.model.element.AnnotationMirror;
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.element.*;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.ExecutableType;
import javax.lang.model.type.TypeKind;
@ -32,6 +24,7 @@ import org.hibernate.Session;
import org.hibernate.StatelessSession;
import org.hibernate.jpamodelgen.Context;
import org.hibernate.jpamodelgen.ImportContextImpl;
import org.hibernate.jpamodelgen.ProcessLaterException;
import org.hibernate.jpamodelgen.model.ImportContext;
import org.hibernate.jpamodelgen.model.MetaAttribute;
import org.hibernate.jpamodelgen.model.Metamodel;
@ -712,32 +705,4 @@ public class AnnotationMetaEntity extends AnnotationMeta {
&& !isPageParam(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;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.hibernate.jpamodelgen.model.MetaAttribute;
import org.hibernate.jpamodelgen.model.Metamodel;
import org.hibernate.jpamodelgen.util.Constants;
@ -16,16 +15,9 @@ import java.util.List;
/**
* @author Gavin King
*/
public class CriteriaFinderMethod implements MetaAttribute {
private final Metamodel annotationMetaEntity;
private final String methodName;
private final String entity;
public class CriteriaFinderMethod extends AbstractFinderMethod {
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(
Metamodel annotationMetaEntity,
@ -35,79 +27,23 @@ public class CriteriaFinderMethod implements MetaAttribute {
boolean belongsToDao,
String sessionType,
List<String> fetchProfiles) {
this.annotationMetaEntity = annotationMetaEntity;
this.methodName = methodName;
this.entity = entity;
super( annotationMetaEntity, methodName, entity, belongsToDao, sessionType, fetchProfiles,
paramNames, paramTypes );
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
public String getAttributeDeclarationString() {
final boolean usingEntityManager = Constants.ENTITY_MANAGER.equals(sessionType);
StringBuilder declaration = new StringBuilder();
final StringBuilder declaration = new StringBuilder();
comment( declaration );
modifiers( declaration );
declaration
.append("\n/**\n * @see ")
.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(returnType())
.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));
}
.append(methodName);
parameters( declaration );
declaration
.append(") {")
.append(" {")
.append("\n\tvar builder = entityManager")
.append(usingEntityManager
? ".getEntityManagerFactory()"
@ -125,22 +61,23 @@ public class CriteriaFinderMethod implements MetaAttribute {
declaration
.append(", ");
}
final String paramName = paramNames.get(i);
declaration
.append("\n\t\t\tbuilder.equal(entity.get(")
.append(annotationMetaEntity.importType(entity+'_'))
.append(annotationMetaEntity.importType(entity + '_'))
.append('.')
.append(paramNames.get(i))
.append(paramName)
.append("), ")
//TODO: only safe if we are binding literals as parameters!!!
.append(paramNames.get(i))
.append(paramName)
.append(")");
}
declaration
.append("\n\t);")
.append("\n\treturn entityManager.createQuery(query)");
boolean hasEnabledFetchProfiles = !fetchProfiles.isEmpty();
boolean hasNativeReturnType = containerType != null && containerType.startsWith("org.hibernate");
boolean unwrap =
final boolean hasEnabledFetchProfiles = !fetchProfiles.isEmpty();
final boolean hasNativeReturnType = containerType != null && containerType.startsWith("org.hibernate");
final boolean unwrap =
( hasEnabledFetchProfiles || hasNativeReturnType )
&& usingEntityManager;
if ( unwrap ) {
@ -149,12 +86,7 @@ public class CriteriaFinderMethod implements MetaAttribute {
.append(annotationMetaEntity.importType(Constants.HIB_SELECTION_QUERY))
.append(".class)");
}
for ( String profile : fetchProfiles ) {
declaration
.append("\n\t\t\t.enableFetchProfile(")
.append(profile)
.append(")");
}
enableFetchProfile( declaration );
if ( containerType == null) {
if ( unwrap || hasEnabledFetchProfiles) {
declaration.append("\n\t\t\t");
@ -174,42 +106,16 @@ public class CriteriaFinderMethod implements MetaAttribute {
return declaration.toString();
}
private String parameterList() {
return paramTypes.stream()
.map(this::strip)
.map(annotationMetaEntity::importType)
.reduce((x, y) -> x + y)
.orElse("");
private StringBuilder returnType() {
StringBuilder type = new StringBuilder();
if ( containerType != null ) {
type.append(annotationMetaEntity.importType(containerType)).append('<');
}
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;
import org.hibernate.jpamodelgen.model.MetaAttribute;
import org.hibernate.jpamodelgen.model.Metamodel;
import org.hibernate.jpamodelgen.util.Constants;
@ -15,15 +14,9 @@ import java.util.List;
/**
* @author Gavin King
*/
public class IdFinderMethod implements MetaAttribute {
private final Metamodel annotationMetaEntity;
private final String methodName;
private final String entity;
public class IdFinderMethod extends AbstractFinderMethod {
private final String paramName;
private final String paramType;
private final boolean belongsToDao;
private final String sessionType;
private final List<String> fetchProfiles;
public IdFinderMethod(
Metamodel annotationMetaEntity,
@ -32,68 +25,20 @@ public class IdFinderMethod implements MetaAttribute {
boolean belongsToDao,
String sessionType,
List<String> fetchProfiles) {
this.annotationMetaEntity = annotationMetaEntity;
this.methodName = methodName;
this.entity = entity;
super( annotationMetaEntity, methodName, entity, belongsToDao, sessionType, fetchProfiles,
List.of(paramName), List.of(paramType) );
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
public String getAttributeDeclarationString() {
final boolean usingEntityManager = Constants.ENTITY_MANAGER.equals(sessionType);
StringBuilder declaration = new StringBuilder();
declaration
.append("\n/**\n * @see ")
.append(annotationMetaEntity.getQualifiedName())
.append("#")
.append(methodName)
.append("(")
.append(annotationMetaEntity.importType(paramType))
.append(")")
.append("\n **/\n");
if ( belongsToDao ) {
final StringBuilder declaration = new StringBuilder();
comment( declaration );
preamble( declaration );
final boolean usingStatelessSession = Constants.HIB_STATELESS_SESSION.equals(sessionType);
if ( usingStatelessSession || usingEntityManager && fetchProfiles.isEmpty() ) {
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(usingStatelessSession ? ".get(" : ".find(")
.append(annotationMetaEntity.importType(entity))
.append(".class, ")
.append(paramName)
@ -101,22 +46,12 @@ public class IdFinderMethod implements MetaAttribute {
.append("\n}");
}
else {
if ( usingEntityManager ) {
declaration
.append(".unwrap(")
.append(annotationMetaEntity.importType(Constants.HIB_SESSION))
.append(".class)\n\t\t\t");
}
unwrapSession( declaration );
declaration
.append(".byId(")
.append(annotationMetaEntity.importType(entity))
.append(".class)");
for ( String profile : fetchProfiles ) {
declaration
.append("\n\t\t\t.enableFetchProfile(")
.append(profile)
.append(")");
}
enableFetchProfile( declaration );
declaration
.append("\n\t\t\t.load(")
.append(paramName)
@ -125,29 +60,4 @@ public class IdFinderMethod implements MetaAttribute {
}
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;
import org.hibernate.jpamodelgen.model.MetaAttribute;
import org.hibernate.jpamodelgen.model.Metamodel;
import org.hibernate.jpamodelgen.util.Constants;
import java.util.List;
/**
* @author Gavin King
*/
public class NaturalIdFinderMethod implements MetaAttribute {
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 class NaturalIdFinderMethod extends AbstractFinderMethod {
public NaturalIdFinderMethod(
Metamodel annotationMetaEntity,
@ -32,94 +22,30 @@ public class NaturalIdFinderMethod implements MetaAttribute {
boolean belongsToDao,
String sessionType,
List<String> fetchProfiles) {
this.annotationMetaEntity = annotationMetaEntity;
this.methodName = methodName;
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;
super( annotationMetaEntity, methodName, entity, belongsToDao, sessionType, fetchProfiles,
paramNames, paramTypes );
}
@Override
public String getAttributeDeclarationString() {
StringBuilder declaration = new StringBuilder();
declaration
.append("\n/**\n * @see ")
.append(annotationMetaEntity.getQualifiedName())
.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");
}
final StringBuilder declaration = new StringBuilder();
comment( declaration );
preamble( declaration );
unwrapSession( declaration );
declaration
.append(".byNaturalId(")
.append(annotationMetaEntity.importType(entity))
.append(".class)");
enableFetchProfile( declaration );
for ( int i = 0; i < paramNames.size(); i ++ ) {
final String paramName = paramNames.get(i);
declaration
.append("\n\t\t\t.using(")
.append(annotationMetaEntity.importType(entity+'_'))
.append(annotationMetaEntity.importType(entity + '_'))
.append('.')
.append(paramNames.get(i))
.append(paramName)
.append(", ")
.append(paramNames.get(i))
.append(")");
}
for ( String profile : fetchProfiles ) {
declaration
.append("\n\t\t\t.enableFetchProfile(")
.append(profile)
.append(paramName)
.append(")");
}
declaration
@ -127,42 +53,4 @@ public class NaturalIdFinderMethod implements MetaAttribute {
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 boolean isNative;
private final boolean belongsToDao;
private final String sessionType;
final boolean usingEntityManager;
public QueryMethod(
Metamodel annotationMetaEntity,
@ -56,7 +56,7 @@ public class QueryMethod implements MetaAttribute {
this.paramTypes = paramTypes;
this.isNative = isNative;
this.belongsToDao = belongsToDao;
this.sessionType = sessionType;
usingEntityManager = Constants.ENTITY_MANAGER.equals(sessionType);
}
@Override
@ -71,81 +71,17 @@ public class QueryMethod implements MetaAttribute {
@Override
public String getAttributeDeclarationString() {
final boolean usingEntityManager = Constants.ENTITY_MANAGER.equals(sessionType);
List<String> paramTypes = this.paramTypes.stream()
.map(ptype -> isOrderParam(ptype) && ptype.endsWith("[]")
? ptype.substring(0, ptype.length()-2) + "..."
: ptype)
.collect(toList());
StringBuilder declaration = new StringBuilder();
final List<String> paramTypes = parameterTypes();
final StringBuilder returnType = returnType();
final StringBuilder declaration = new StringBuilder();
comment( declaration );
modifiers( paramTypes, declaration );
declaration
.append("\n/**\n * @see ")
.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(returnType)
.append(" ")
.append(methodName)
.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);
}
.append(methodName);
parameters( paramTypes, declaration );
declaration
.append(")")
.append(" {")
.append("\n\treturn ");
if ( isNative && returnTypeName != null && containerTypeName == null
@ -153,7 +89,7 @@ public class QueryMethod implements MetaAttribute {
// EntityManager.createNativeQuery() does not return TypedQuery,
// so we need to cast to the entity type
declaration.append("(")
.append(type)
.append(returnType)
.append(") ");
}
declaration
@ -161,7 +97,7 @@ public class QueryMethod implements MetaAttribute {
.append(isNative ? "createNativeQuery" : "createQuery")
.append("(")
.append(getConstantName());
if (returnTypeName != null) {
if ( returnTypeName != null ) {
declaration
.append(", ")
.append(annotationMetaEntity.importType(returnTypeName))
@ -170,47 +106,47 @@ public class QueryMethod implements MetaAttribute {
declaration.append(")");
boolean unwrapped = !usingEntityManager;
for (int i = 1; i <= paramNames.size(); i++) {
String param = paramNames.get(i-1);
String ptype = paramTypes.get(i-1);
if (queryString.contains(":" + param)) {
final String paramName = paramNames.get(i-1);
final String paramType = paramTypes.get(i-1);
if ( queryString.contains(":" + paramName) ) {
declaration
.append("\n\t\t\t.setParameter(\"")
.append(param)
.append(paramName)
.append("\", ")
.append(param)
.append(paramName)
.append(")");
}
else if (queryString.contains("?" + i)) {
else if ( queryString.contains("?" + i) ) {
declaration
.append("\n\t\t\t.setParameter(")
.append(i)
.append(", ")
.append(param)
.append(paramName)
.append(")");
}
else if (isPageParam(ptype)) {
else if ( isPageParam(paramType) ) {
unwrap( declaration, unwrapped );
unwrapped = true;
declaration
.append("\n\t\t\t.setPage(")
.append(param)
.append(paramName)
.append(")");
}
else if (isOrderParam(ptype)) {
else if ( isOrderParam(paramType) ) {
unwrap( declaration, unwrapped );
unwrapped = true;
if (ptype.endsWith("...")) {
if ( paramType.endsWith("...") ) {
declaration
.append("\n\t\t\t.setOrder(")
.append(annotationMetaEntity.importType(List.class.getName()))
.append(".of(")
.append(param)
.append(paramName)
.append("))");
}
else {
declaration
.append("\n\t\t\t.setOrder(")
.append(param)
.append(paramName)
.append(")");
}
}
@ -238,11 +174,95 @@ public class QueryMethod implements MetaAttribute {
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() {
return paramTypes.stream()
.map(this::strip)
.map(annotationMetaEntity::importType)
.reduce((x, y) -> x + y)
.reduce((x, y) -> x + ',' + y)
.orElse("");
}
@ -273,7 +293,7 @@ public class QueryMethod implements MetaAttribute {
@Override
public String getAttributeNameDeclarationString() {
return new StringBuilder()
.append("public static final String ")
.append("static final String ")
.append(getConstantName())
.append(" = \"")
.append(queryString)
@ -287,10 +307,12 @@ public class QueryMethod implements MetaAttribute {
return stem;
}
else {
return stem + "_" + StringHelper.join("_",
paramTypes.stream()
return stem + "_"
+ paramTypes.stream()
.filter(name -> !isPageParam(name) && !isOrderParam(name))
.map(StringHelper::unqualify).collect(toList()));
.map(StringHelper::unqualify)
.reduce((x,y) -> x + '_' + y)
.orElse("");
}
}