introduce include/exclude options for HibernateProcessor

and rename @Suppress -> @Exclude

Signed-off-by: Gavin King <gavin@hibernate.org>
This commit is contained in:
Gavin King 2024-04-14 19:13:55 +02:00
parent 4ae64eeb3f
commit ccaefc168a
5 changed files with 73 additions and 6 deletions

View File

@ -25,5 +25,5 @@ import static java.lang.annotation.RetentionPolicy.CLASS;
@Target({PACKAGE, TYPE}) @Target({PACKAGE, TYPE})
@Retention(CLASS) @Retention(CLASS)
@Incubating @Incubating
public @interface Suppress { public @interface Exclude {
} }

View File

@ -10,12 +10,12 @@ package org.hibernate.orm.test.annotations.onetoone;
import jakarta.persistence.Entity; import jakarta.persistence.Entity;
import jakarta.persistence.Id; import jakarta.persistence.Id;
import jakarta.persistence.OneToOne; import jakarta.persistence.OneToOne;
import org.hibernate.annotations.processing.Suppress; import org.hibernate.annotations.processing.Exclude;
/** /**
* @author Emmanuel Bernard * @author Emmanuel Bernard
*/ */
@Suppress @Exclude
@Entity @Entity
public class ShowDescription { public class ShowDescription {
@Id @Id

View File

@ -30,6 +30,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
import static java.lang.Boolean.parseBoolean; import static java.lang.Boolean.parseBoolean;
import static java.util.Collections.emptyList; import static java.util.Collections.emptyList;
import static org.hibernate.internal.util.collections.ArrayHelper.EMPTY_STRING_ARRAY;
/** /**
* @author Max Andersen * @author Max Andersen
@ -98,6 +99,9 @@ public final class Context {
private boolean usesQuarkusOrm = false; private boolean usesQuarkusOrm = false;
private boolean usesQuarkusReactive = false; private boolean usesQuarkusReactive = false;
private String[] includes = {"*"};
private String[] excludes = {};
public Context(ProcessingEnvironment processingEnvironment) { public Context(ProcessingEnvironment processingEnvironment) {
this.processingEnvironment = processingEnvironment; this.processingEnvironment = processingEnvironment;
@ -412,4 +416,36 @@ public final class Context {
public boolean usesQuarkusReactive() { public boolean usesQuarkusReactive() {
return usesQuarkusReactive; return usesQuarkusReactive;
} }
public void setInclude(String include) {
includes = include.split(",\\s*");
}
public void setExclude(String exclude) {
excludes = exclude.isBlank()
? EMPTY_STRING_ARRAY
: exclude.split(",\\s*");
}
public boolean isIncluded(String typeName) {
for (String include : includes) {
if ( matches(typeName, include) ) {
for (String exclude : excludes) {
if ( matches(typeName, exclude) ) {
return false;
}
}
return true;
}
}
return false;
}
private boolean matches(String name, String pattern) {
return "*".equals(pattern)
|| name.equals( pattern )
|| pattern.endsWith("*") && name.startsWith( pattern.substring(0, pattern.length()-1) )
|| pattern.startsWith("*") && name.endsWith( pattern.substring(1) )
|| pattern.startsWith("*") && pattern.endsWith("*") && name.contains( pattern.substring(1, pattern.length()-1) );
}
} }

View File

@ -10,6 +10,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
import org.hibernate.processor.annotation.AnnotationMetaEntity; import org.hibernate.processor.annotation.AnnotationMetaEntity;
import org.hibernate.processor.annotation.AnnotationMetaPackage; import org.hibernate.processor.annotation.AnnotationMetaPackage;
import org.hibernate.processor.model.Metamodel; import org.hibernate.processor.model.Metamodel;
import org.hibernate.processor.util.Constants;
import org.hibernate.processor.xml.JpaDescriptorParser; import org.hibernate.processor.xml.JpaDescriptorParser;
import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.AbstractProcessor;
@ -138,6 +139,22 @@ public class HibernateProcessor extends AbstractProcessor {
*/ */
public static final String SUPPRESS_JAKARTA_DATA_METAMODEL = "suppressJakartaDataMetamodel"; public static final String SUPPRESS_JAKARTA_DATA_METAMODEL = "suppressJakartaDataMetamodel";
/**
* Option to include only certain types, according to a list of patterns.
* The wildcard character is {@code *}, and patterns are comma-separated.
* For example: {@code *.entity.*,*Repository}. The default include is
* simply {@code *}, meaning that all types are included.
*/
public static final String INCLUDE = "include";
/**
* Option to exclude certain types, according to a list of patterns.
* The wildcard character is {@code *}, and patterns are comma-separated.
* For example: {@code *.framework.*,*$$}. The default exclude is
* empty.
*/
public static final String EXCLUDE = "exclude";
private static final boolean ALLOW_OTHER_PROCESSORS_TO_CLAIM_ANNOTATIONS = false; private static final boolean ALLOW_OTHER_PROCESSORS_TO_CLAIM_ANNOTATIONS = false;
private Context context; private Context context;
@ -228,6 +245,9 @@ public class HibernateProcessor extends AbstractProcessor {
} }
} }
context.setInclude( options.getOrDefault( INCLUDE, "*" ) );
context.setExclude( options.getOrDefault( EXCLUDE, "" ) );
return parseBoolean( options.get( FULLY_ANNOTATION_CONFIGURED_OPTION ) ); return parseBoolean( options.get( FULLY_ANNOTATION_CONFIGURED_OPTION ) );
} }
@ -276,6 +296,16 @@ public class HibernateProcessor extends AbstractProcessor {
return ALLOW_OTHER_PROCESSORS_TO_CLAIM_ANNOTATIONS; return ALLOW_OTHER_PROCESSORS_TO_CLAIM_ANNOTATIONS;
} }
private boolean included(Element element) {
if ( element instanceof TypeElement) {
final TypeElement typeElement = (TypeElement) element;
return context.isIncluded( typeElement.getQualifiedName().toString() );
}
else {
return false;
}
}
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 + "'" );
@ -293,8 +323,9 @@ public class HibernateProcessor extends AbstractProcessor {
for ( Element element : roundEnvironment.getRootElements() ) { for ( Element element : roundEnvironment.getRootElements() ) {
try { try {
if ( hasAnnotation( element, SUPPRESS) if ( !included( element )
|| hasAnnotation( context.getElementUtils().getPackageOf(element), SUPPRESS ) ) { || hasAnnotation( element, Constants.EXCLUDE )
|| hasAnnotation( context.getElementUtils().getPackageOf(element), Constants.EXCLUDE ) ) {
// skip it completely // skip it completely
} }
else if ( isEntityOrEmbeddable( element ) ) { else if ( isEntityOrEmbeddable( element ) ) {

View File

@ -62,7 +62,7 @@ public final class Constants {
public static final String SQL = "org.hibernate.annotations.processing.SQL"; public static final String SQL = "org.hibernate.annotations.processing.SQL";
public static final String FIND = "org.hibernate.annotations.processing.Find"; public static final String FIND = "org.hibernate.annotations.processing.Find";
public static final String PATTERN = "org.hibernate.annotations.processing.Pattern"; public static final String PATTERN = "org.hibernate.annotations.processing.Pattern";
public static final String SUPPRESS = "org.hibernate.annotations.processing.Suppress"; public static final String EXCLUDE = "org.hibernate.annotations.processing.Exclude";
public static final String JD_REPOSITORY = "jakarta.data.repository.Repository"; public static final String JD_REPOSITORY = "jakarta.data.repository.Repository";
public static final String JD_QUERY = "jakarta.data.repository.Query"; public static final String JD_QUERY = "jakarta.data.repository.Query";