HHH-16633 better Javadoc and @Nonnull annotations in generated source

This commit is contained in:
Gavin King 2023-07-10 13:13:45 +02:00
parent 02e395c96d
commit 24db891e84
9 changed files with 165 additions and 33 deletions

View File

@ -66,6 +66,7 @@ public final class Context {
*/ */
private Boolean fullyXmlConfigured; private Boolean fullyXmlConfigured;
private boolean addInjectAnnotation = false; private boolean addInjectAnnotation = false;
private boolean addNonnullAnnotation = false;
private boolean addGeneratedAnnotation = true; private boolean addGeneratedAnnotation = true;
private boolean addGenerationDate; private boolean addGenerationDate;
private boolean addSuppressWarningsAnnotation; private boolean addSuppressWarningsAnnotation;
@ -121,6 +122,14 @@ public final class Context {
this.addInjectAnnotation = addInjectAnnotation; this.addInjectAnnotation = addInjectAnnotation;
} }
public boolean addNonnullAnnotation() {
return addNonnullAnnotation;
}
public void setAddNonnullAnnotation(boolean addNonnullAnnotation) {
this.addNonnullAnnotation = addNonnullAnnotation;
}
public boolean addGeneratedAnnotation() { public boolean addGeneratedAnnotation() {
return addGeneratedAnnotation; return addGeneratedAnnotation;
} }

View File

@ -114,7 +114,13 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
final PackageElement jakartaInjectPackage = final PackageElement jakartaInjectPackage =
context.getProcessingEnvironment().getElementUtils() context.getProcessingEnvironment().getElementUtils()
.getPackageElement( "jakarta.inject" ); .getPackageElement( "jakarta.inject" );
final PackageElement jakartaAnnotationPackage =
context.getProcessingEnvironment().getElementUtils()
.getPackageElement( "jakarta.annotation" );
context.setAddInjectAnnotation( jakartaInjectPackage != null ); context.setAddInjectAnnotation( jakartaInjectPackage != null );
context.setAddNonnullAnnotation( jakartaAnnotationPackage != null );
context.setAddGeneratedAnnotation( jakartaAnnotationPackage != null );
final Map<String, String> options = environment.getOptions(); final Map<String, String> options = environment.getOptions();
@ -122,12 +128,6 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
if ( setting != null ) { if ( setting != null ) {
context.setAddGeneratedAnnotation( parseBoolean( setting ) ); context.setAddGeneratedAnnotation( parseBoolean( setting ) );
} }
else {
PackageElement jakartaAnnotationPackage =
context.getProcessingEnvironment().getElementUtils()
.getPackageElement( "jakarta.annotation" );
context.setAddGeneratedAnnotation( jakartaAnnotationPackage != null );
}
context.setAddGenerationDate( parseBoolean( options.get( ADD_GENERATION_DATE ) ) ); context.setAddGenerationDate( parseBoolean( options.get( ADD_GENERATION_DATE ) ) );

View File

@ -26,6 +26,7 @@ public abstract class AbstractFinderMethod implements MetaAttribute {
final boolean belongsToDao; final boolean belongsToDao;
final String sessionType; final String sessionType;
final boolean usingEntityManager; final boolean usingEntityManager;
private final boolean addNonnullAnnotation;
final List<String> fetchProfiles; final List<String> fetchProfiles;
final List<String> paramNames; final List<String> paramNames;
@ -39,7 +40,8 @@ public abstract class AbstractFinderMethod implements MetaAttribute {
String sessionType, String sessionType,
List<String> fetchProfiles, List<String> fetchProfiles,
List<String> paramNames, List<String> paramNames,
List<String> paramTypes) { List<String> paramTypes,
boolean addNonnullAnnotation) {
this.annotationMetaEntity = annotationMetaEntity; this.annotationMetaEntity = annotationMetaEntity;
this.methodName = methodName; this.methodName = methodName;
this.entity = entity; this.entity = entity;
@ -48,7 +50,8 @@ public abstract class AbstractFinderMethod implements MetaAttribute {
this.fetchProfiles = fetchProfiles; this.fetchProfiles = fetchProfiles;
this.paramNames = paramNames; this.paramNames = paramNames;
this.paramTypes = paramTypes; this.paramTypes = paramTypes;
usingEntityManager = Constants.ENTITY_MANAGER.equals(sessionType); this.usingEntityManager = Constants.ENTITY_MANAGER.equals(sessionType);
this.addNonnullAnnotation = addNonnullAnnotation;
} }
@Override @Override
@ -81,6 +84,7 @@ public abstract class AbstractFinderMethod implements MetaAttribute {
return annotationMetaEntity; return annotationMetaEntity;
} }
abstract boolean isId();
@Override @Override
public String getAttributeNameDeclarationString() { public String getAttributeNameDeclarationString() {
@ -123,13 +127,53 @@ public abstract class AbstractFinderMethod implements MetaAttribute {
void comment(StringBuilder declaration) { void comment(StringBuilder declaration) {
declaration declaration
.append("\n/**\n * @see ") .append("\n/**")
.append("\n * Find ")
.append("{@link ")
.append(annotationMetaEntity.importType(entity))
.append("} by ");
int paramCount = paramNames.size();
for (int i = 0; i < paramCount; i++) {
String param = paramNames.get(i);
if ( i>0 ) {
if ( i + 1 == paramCount) {
declaration
.append(paramCount>2 ? ", and " : " and "); //Oxford comma
}
else {
declaration
.append(", ");
}
}
declaration
.append("{@link ")
.append(annotationMetaEntity.importType(entity))
.append('#')
.append(param)
.append(' ')
.append(param)
.append("}");
}
declaration
.append('.')
.append("\n *")
.append("\n * @see ")
.append(annotationMetaEntity.getQualifiedName()) .append(annotationMetaEntity.getQualifiedName())
.append("#") .append("#")
.append(methodName) .append(methodName)
.append("(") .append("(")
.append(parameterList()) .append(parameterList())
.append(")") .append(")");
// declaration
// .append("\n *");
// for (String param : paramNames) {
// declaration
// .append("\n * @see ")
// .append(annotationMetaEntity.importType(entity))
// .append('#')
// .append(param);
// }
declaration
.append("\n **/\n"); .append("\n **/\n");
} }
@ -180,6 +224,7 @@ public abstract class AbstractFinderMethod implements MetaAttribute {
declaration declaration
.append("("); .append("(");
if ( !belongsToDao ) { if ( !belongsToDao ) {
notNull( declaration );
declaration declaration
.append(annotationMetaEntity.importType(Constants.ENTITY_MANAGER)) .append(annotationMetaEntity.importType(Constants.ENTITY_MANAGER))
.append(" entityManager"); .append(" entityManager");
@ -189,6 +234,9 @@ public abstract class AbstractFinderMethod implements MetaAttribute {
declaration declaration
.append(", "); .append(", ");
} }
if ( isId() ) {
notNull( declaration );
}
declaration declaration
.append(annotationMetaEntity.importType(paramTypes.get(i))) .append(annotationMetaEntity.importType(paramTypes.get(i)))
.append(" ") .append(" ")
@ -197,4 +245,13 @@ public abstract class AbstractFinderMethod implements MetaAttribute {
declaration declaration
.append(')'); .append(')');
} }
private void notNull(StringBuilder declaration) {
if ( addNonnullAnnotation ) {
declaration
.append('@')
.append(annotationMetaEntity.importType("jakarta.annotation.Nonnull"))
.append(' ');
}
}
} }

View File

@ -287,7 +287,15 @@ public class AnnotationMetaEntity extends AnnotationMeta {
String typeName = element.getSimpleName().toString() + '_'; String typeName = element.getSimpleName().toString() + '_';
String sessionType = getterOrSetter.getReturnType().toString(); String sessionType = getterOrSetter.getReturnType().toString();
putMember( name, putMember( name,
new DaoConstructor(this, typeName, name, sessionType, context.addInjectAnnotation() ) ); new DaoConstructor(
this,
typeName,
name,
sessionType,
context.addInjectAnnotation(),
context.addNonnullAnnotation()
)
);
return sessionType; return sessionType;
} }
@ -502,7 +510,8 @@ public class AnnotationMetaEntity extends AnnotationMeta {
false, false,
dao, dao,
sessionType, sessionType,
enabledFetchProfiles( method ) enabledFetchProfiles( method ),
context.addNonnullAnnotation()
) )
); );
} }
@ -541,7 +550,8 @@ public class AnnotationMetaEntity extends AnnotationMeta {
paramTypes, paramTypes,
dao, dao,
sessionType, sessionType,
enabledFetchProfiles( method ) enabledFetchProfiles( method ),
context.addNonnullAnnotation()
) )
); );
} }
@ -557,7 +567,8 @@ public class AnnotationMetaEntity extends AnnotationMeta {
false, false,
dao, dao,
sessionType, sessionType,
enabledFetchProfiles( method ) enabledFetchProfiles( method ),
context.addNonnullAnnotation()
) )
); );
} }
@ -582,7 +593,8 @@ public class AnnotationMetaEntity extends AnnotationMeta {
parameter.asType().toString(), parameter.asType().toString(),
dao, dao,
sessionType, sessionType,
enabledFetchProfiles( method ) enabledFetchProfiles( method ),
context.addNonnullAnnotation()
) )
); );
break; break;
@ -598,7 +610,8 @@ public class AnnotationMetaEntity extends AnnotationMeta {
List.of( parameter.asType().toString() ), List.of( parameter.asType().toString() ),
dao, dao,
sessionType, sessionType,
enabledFetchProfiles( method ) enabledFetchProfiles( method ),
context.addNonnullAnnotation()
) )
); );
break; break;
@ -615,7 +628,8 @@ public class AnnotationMetaEntity extends AnnotationMeta {
fieldType == FieldType.ID, fieldType == FieldType.ID,
dao, dao,
sessionType, sessionType,
enabledFetchProfiles( method ) enabledFetchProfiles( method ),
context.addNonnullAnnotation()
) )
); );
break; break;
@ -703,7 +717,8 @@ public class AnnotationMetaEntity extends AnnotationMeta {
paramTypes, paramTypes,
isNative, isNative,
dao, dao,
sessionType sessionType,
context.addNonnullAnnotation()
); );
putMember( attribute.getPropertyName() + paramTypes, attribute ); putMember( attribute.getPropertyName() + paramTypes, attribute );

View File

@ -29,13 +29,19 @@ public class CriteriaFinderMethod extends AbstractFinderMethod {
boolean isId, boolean isId,
boolean belongsToDao, boolean belongsToDao,
String sessionType, String sessionType,
List<String> fetchProfiles) { List<String> fetchProfiles,
boolean addNonnullAnnotation) {
super( annotationMetaEntity, methodName, entity, belongsToDao, sessionType, fetchProfiles, super( annotationMetaEntity, methodName, entity, belongsToDao, sessionType, fetchProfiles,
paramNames, paramTypes ); paramNames, paramTypes, addNonnullAnnotation );
this.containerType = containerType; this.containerType = containerType;
this.isId = isId; this.isId = isId;
} }
@Override
public boolean isId() {
return isId;
}
@Override @Override
public String getAttributeDeclarationString() { public String getAttributeDeclarationString() {
final StringBuilder declaration = new StringBuilder(); final StringBuilder declaration = new StringBuilder();

View File

@ -19,18 +19,21 @@ public class DaoConstructor implements MetaAttribute {
private final String methodName; private final String methodName;
private final String returnTypeName; private final String returnTypeName;
private final boolean inject; private final boolean inject;
private final boolean addNonnullAnnotation;
public DaoConstructor( public DaoConstructor(
Metamodel annotationMetaEntity, Metamodel annotationMetaEntity,
String constructorName, String constructorName,
String methodName, String methodName,
String returnTypeName, String returnTypeName,
boolean inject) { boolean inject,
boolean addNonnullAnnotation) {
this.annotationMetaEntity = annotationMetaEntity; this.annotationMetaEntity = annotationMetaEntity;
this.constructorName = constructorName; this.constructorName = constructorName;
this.methodName = methodName; this.methodName = methodName;
this.returnTypeName = returnTypeName; this.returnTypeName = returnTypeName;
this.inject = inject; this.inject = inject;
this.addNonnullAnnotation = addNonnullAnnotation;
} }
@Override @Override
@ -45,28 +48,44 @@ public class DaoConstructor implements MetaAttribute {
@Override @Override
public String getAttributeDeclarationString() { public String getAttributeDeclarationString() {
return new StringBuilder() StringBuilder declaration = new StringBuilder();
.append("\nprivate final ") declaration
.append("\nprivate final ");
notNull( declaration );
declaration
.append(annotationMetaEntity.importType(returnTypeName)) .append(annotationMetaEntity.importType(returnTypeName))
.append(" entityManager;") .append(" entityManager;")
.append("\n") .append("\n")
.append(inject ? "\n@" + annotationMetaEntity.importType("jakarta.inject.Inject") : "") .append(inject ? "\n@" + annotationMetaEntity.importType("jakarta.inject.Inject") : "")
.append("\npublic ") .append("\npublic ")
.append(constructorName) .append(constructorName)
.append("(") .append("(");
notNull( declaration );
declaration
.append(annotationMetaEntity.importType(returnTypeName)) .append(annotationMetaEntity.importType(returnTypeName))
.append(" entityManager) {") .append(" entityManager) {")
.append("\n\tthis.entityManager = entityManager;") .append("\n\tthis.entityManager = entityManager;")
.append("\n}") .append("\n}")
.append("\n\n") .append("\n\n")
.append("public ") .append("public ");
notNull( declaration );
declaration
.append(annotationMetaEntity.importType(returnTypeName)) .append(annotationMetaEntity.importType(returnTypeName))
.append(" ") .append(" ")
.append(methodName) .append(methodName)
.append("() {") .append("() {")
.append("\n\treturn entityManager;") .append("\n\treturn entityManager;")
.append("\n}") .append("\n}");
.toString(); return declaration.toString();
}
private void notNull(StringBuilder declaration) {
if ( addNonnullAnnotation ) {
declaration
.append('@')
.append(annotationMetaEntity.importType("jakarta.annotation.Nonnull"))
.append(' ');
}
} }
@Override @Override

View File

@ -25,13 +25,19 @@ public class IdFinderMethod extends AbstractFinderMethod {
String paramName, String paramType, String paramName, String paramType,
boolean belongsToDao, boolean belongsToDao,
String sessionType, String sessionType,
List<String> fetchProfiles) { List<String> fetchProfiles,
boolean addNonnullAnnotation) {
super( annotationMetaEntity, methodName, entity, belongsToDao, sessionType, fetchProfiles, super( annotationMetaEntity, methodName, entity, belongsToDao, sessionType, fetchProfiles,
List.of(paramName), List.of(paramType) ); List.of(paramName), List.of(paramType), addNonnullAnnotation );
this.paramName = paramName; this.paramName = paramName;
usingStatelessSession = Constants.HIB_STATELESS_SESSION.equals(sessionType); usingStatelessSession = Constants.HIB_STATELESS_SESSION.equals(sessionType);
} }
@Override
boolean isId() {
return true;
}
@Override @Override
public String getAttributeDeclarationString() { public String getAttributeDeclarationString() {
final StringBuilder declaration = new StringBuilder(); final StringBuilder declaration = new StringBuilder();

View File

@ -21,9 +21,16 @@ public class NaturalIdFinderMethod extends AbstractFinderMethod {
List<String> paramNames, List<String> paramTypes, List<String> paramNames, List<String> paramTypes,
boolean belongsToDao, boolean belongsToDao,
String sessionType, String sessionType,
List<String> fetchProfiles) { List<String> fetchProfiles,
boolean addNonnullAnnotation) {
super( annotationMetaEntity, methodName, entity, belongsToDao, sessionType, fetchProfiles, super( annotationMetaEntity, methodName, entity, belongsToDao, sessionType, fetchProfiles,
paramNames, paramTypes ); paramNames, paramTypes, addNonnullAnnotation );
}
@Override
boolean isId() {
// natural ids can be null
return false;
} }
@Override @Override

View File

@ -33,6 +33,7 @@ public class QueryMethod implements MetaAttribute {
private final boolean isNative; private final boolean isNative;
private final boolean belongsToDao; private final boolean belongsToDao;
final boolean usingEntityManager; final boolean usingEntityManager;
private final boolean addNonnullAnnotation;
public QueryMethod( public QueryMethod(
Metamodel annotationMetaEntity, Metamodel annotationMetaEntity,
@ -46,7 +47,8 @@ public class QueryMethod implements MetaAttribute {
List<String> paramTypes, List<String> paramTypes,
boolean isNative, boolean isNative,
boolean belongsToDao, boolean belongsToDao,
String sessionType) { String sessionType,
boolean addNonnullAnnotation) {
this.annotationMetaEntity = annotationMetaEntity; this.annotationMetaEntity = annotationMetaEntity;
this.methodName = methodName; this.methodName = methodName;
this.queryString = queryString; this.queryString = queryString;
@ -56,7 +58,8 @@ public class QueryMethod implements MetaAttribute {
this.paramTypes = paramTypes; this.paramTypes = paramTypes;
this.isNative = isNative; this.isNative = isNative;
this.belongsToDao = belongsToDao; this.belongsToDao = belongsToDao;
usingEntityManager = Constants.ENTITY_MANAGER.equals(sessionType); this.usingEntityManager = Constants.ENTITY_MANAGER.equals(sessionType);
this.addNonnullAnnotation = addNonnullAnnotation;
} }
@Override @Override
@ -177,6 +180,7 @@ public class QueryMethod implements MetaAttribute {
private void parameters(List<String> paramTypes, StringBuilder declaration) { private void parameters(List<String> paramTypes, StringBuilder declaration) {
declaration.append("("); declaration.append("(");
if ( !belongsToDao ) { if ( !belongsToDao ) {
notNull( declaration );
declaration declaration
.append(annotationMetaEntity.importType(Constants.ENTITY_MANAGER)) .append(annotationMetaEntity.importType(Constants.ENTITY_MANAGER))
.append(" entityManager"); .append(" entityManager");
@ -316,6 +320,15 @@ public class QueryMethod implements MetaAttribute {
} }
} }
private void notNull(StringBuilder declaration) {
if ( addNonnullAnnotation ) {
declaration
.append('@')
.append(annotationMetaEntity.importType("jakarta.annotation.Nonnull"))
.append(' ');
}
}
@Override @Override
public String getMetaType() { public String getMetaType() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();