diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/processing/Suppress.java b/hibernate-core/src/main/java/org/hibernate/annotations/processing/Exclude.java similarity index 96% rename from hibernate-core/src/main/java/org/hibernate/annotations/processing/Suppress.java rename to hibernate-core/src/main/java/org/hibernate/annotations/processing/Exclude.java index cc0bcf3170..d295c47c5f 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/processing/Suppress.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/processing/Exclude.java @@ -25,5 +25,5 @@ import static java.lang.annotation.RetentionPolicy.CLASS; @Target({PACKAGE, TYPE}) @Retention(CLASS) @Incubating -public @interface Suppress { +public @interface Exclude { } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/onetoone/ShowDescription.java b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/onetoone/ShowDescription.java index 4bfac9848d..f471acf3c3 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/onetoone/ShowDescription.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/onetoone/ShowDescription.java @@ -10,12 +10,12 @@ package org.hibernate.orm.test.annotations.onetoone; import jakarta.persistence.Entity; import jakarta.persistence.Id; import jakarta.persistence.OneToOne; -import org.hibernate.annotations.processing.Suppress; +import org.hibernate.annotations.processing.Exclude; /** * @author Emmanuel Bernard */ -@Suppress +@Exclude @Entity public class ShowDescription { @Id diff --git a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/Context.java b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/Context.java index a796c5274e..a9d3d3018e 100644 --- a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/Context.java +++ b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/Context.java @@ -30,6 +30,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; import static java.lang.Boolean.parseBoolean; import static java.util.Collections.emptyList; +import static org.hibernate.internal.util.collections.ArrayHelper.EMPTY_STRING_ARRAY; /** * @author Max Andersen @@ -98,6 +99,9 @@ public final class Context { private boolean usesQuarkusOrm = false; private boolean usesQuarkusReactive = false; + private String[] includes = {"*"}; + private String[] excludes = {}; + public Context(ProcessingEnvironment processingEnvironment) { this.processingEnvironment = processingEnvironment; @@ -412,4 +416,36 @@ public final class Context { public boolean 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) ); + } } diff --git a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/HibernateProcessor.java b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/HibernateProcessor.java index a7f26dd2ea..7392384376 100644 --- a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/HibernateProcessor.java +++ b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/HibernateProcessor.java @@ -10,6 +10,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.processor.annotation.AnnotationMetaEntity; import org.hibernate.processor.annotation.AnnotationMetaPackage; import org.hibernate.processor.model.Metamodel; +import org.hibernate.processor.util.Constants; import org.hibernate.processor.xml.JpaDescriptorParser; import javax.annotation.processing.AbstractProcessor; @@ -138,6 +139,22 @@ public class HibernateProcessor extends AbstractProcessor { */ 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 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 ) ); } @@ -276,6 +296,16 @@ public class HibernateProcessor extends AbstractProcessor { 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) { for ( CharSequence elementName : new HashSet<>( context.getElementsToRedo() ) ) { context.logMessage( Diagnostic.Kind.OTHER, "Redoing element '" + elementName + "'" ); @@ -293,8 +323,9 @@ public class HibernateProcessor extends AbstractProcessor { for ( Element element : roundEnvironment.getRootElements() ) { try { - if ( hasAnnotation( element, SUPPRESS) - || hasAnnotation( context.getElementUtils().getPackageOf(element), SUPPRESS ) ) { + if ( !included( element ) + || hasAnnotation( element, Constants.EXCLUDE ) + || hasAnnotation( context.getElementUtils().getPackageOf(element), Constants.EXCLUDE ) ) { // skip it completely } else if ( isEntityOrEmbeddable( element ) ) { diff --git a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/util/Constants.java b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/util/Constants.java index 48b4e5e8bd..d38892d2d3 100644 --- a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/util/Constants.java +++ b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/util/Constants.java @@ -62,7 +62,7 @@ public final class Constants { public static final String SQL = "org.hibernate.annotations.processing.SQL"; public static final String FIND = "org.hibernate.annotations.processing.Find"; 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_QUERY = "jakarta.data.repository.Query";