Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ public final class Context {
private String[] includes = {"*"};
private String[] excludes = {};

private boolean indexing = true;

private final Map<String, String> entityNameMappings = new HashMap<>();
private final Map<String, Set<String>> enumTypesByValue = new HashMap<>();

Expand Down Expand Up @@ -551,4 +553,12 @@ private void addEnumValue(String qualifiedTypeName, String value) {
}
return null;
}

public void setIndexing(boolean index) {
this.indexing = index;
}

public boolean isIndexing() {
return indexing;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
import static org.hibernate.processor.HibernateProcessor.EXCLUDE;
import static org.hibernate.processor.HibernateProcessor.FULLY_ANNOTATION_CONFIGURED_OPTION;
import static org.hibernate.processor.HibernateProcessor.INCLUDE;
import static org.hibernate.processor.HibernateProcessor.INDEX;
import static org.hibernate.processor.HibernateProcessor.LAZY_XML_PARSING;
import static org.hibernate.processor.HibernateProcessor.ORM_XML_OPTION;
import static org.hibernate.processor.HibernateProcessor.PERSISTENCE_XML_OPTION;
Expand Down Expand Up @@ -120,7 +121,8 @@
ADD_GENERATED_ANNOTATION,
ADD_SUPPRESS_WARNINGS_ANNOTATION,
SUPPRESS_JAKARTA_DATA_METAMODEL,
INCLUDE, EXCLUDE
INCLUDE, EXCLUDE,
INDEX
})
public class HibernateProcessor extends AbstractProcessor {

Expand Down Expand Up @@ -190,6 +192,13 @@ public class HibernateProcessor extends AbstractProcessor {
*/
public static final String EXCLUDE = "exclude";

/**
* Option to suppress creation of a filesystem-based index of entity
* types and enums for use by the query validator. By default, and
* index is created.
*/
public static final String INDEX = "index";

private static final boolean ALLOW_OTHER_PROCESSORS_TO_CLAIM_ANNOTATIONS = false;

public static final String ENTITY_INDEX = "entity.index";
Expand Down Expand Up @@ -282,6 +291,8 @@ && packagePresent(quarkusOrmPanachePackage) ) {
context.setInclude( options.getOrDefault( INCLUDE, "*" ) );
context.setExclude( options.getOrDefault( EXCLUDE, "" ) );

context.setIndexing( parseBoolean( options.getOrDefault( INDEX, "true" ) ) );

return parseBoolean( options.get( FULLY_ANNOTATION_CONFIGURED_OPTION ) );
}

Expand Down Expand Up @@ -773,43 +784,45 @@ else if ( hasAnnotation( typeElement, EMBEDDABLE ) ) {
}

private void writeIndex() {
final ProcessingEnvironment processingEnvironment = context.getProcessingEnvironment();
final Elements elementUtils = processingEnvironment.getElementUtils();
context.getEntityNameMappings().forEach((entityName, className) -> {
try (Writer writer = processingEnvironment.getFiler()
.createResource(
StandardLocation.SOURCE_OUTPUT,
ENTITY_INDEX,
entityName,
elementUtils.getTypeElement( className )
)
.openWriter()) {
writer.append(className);
}
catch (IOException e) {
processingEnvironment.getMessager()
.printMessage(Diagnostic.Kind.WARNING,
"could not write entity index " + e.getMessage());
}
});
context.getEnumTypesByValue().forEach((valueName, enumTypeNames) -> {
try (Writer writer = processingEnvironment.getFiler()
.createResource(
StandardLocation.SOURCE_OUTPUT,
ENTITY_INDEX,
'.' + valueName,
elementUtils.getTypeElement( enumTypeNames.iterator().next() )
)
.openWriter()) {
for (String enumTypeName : enumTypeNames) {
writer.append(enumTypeName).append(" ");
if ( context.isIndexing() ) {
final ProcessingEnvironment processingEnvironment = context.getProcessingEnvironment();
final Elements elementUtils = processingEnvironment.getElementUtils();
context.getEntityNameMappings().forEach( (entityName, className) -> {
try (Writer writer = processingEnvironment.getFiler()
.createResource(
StandardLocation.SOURCE_OUTPUT,
ENTITY_INDEX,
entityName,
elementUtils.getTypeElement( className )
)
.openWriter()) {
writer.append( className );
}
}
catch (IOException e) {
processingEnvironment.getMessager()
.printMessage(Diagnostic.Kind.WARNING,
"could not write entity index " + e.getMessage());
}
});
catch (IOException e) {
processingEnvironment.getMessager()
.printMessage( Diagnostic.Kind.WARNING,
"could not write entity index " + e.getMessage() );
}
} );
context.getEnumTypesByValue().forEach( (valueName, enumTypeNames) -> {
try (Writer writer = processingEnvironment.getFiler()
.createResource(
StandardLocation.SOURCE_OUTPUT,
ENTITY_INDEX,
'.' + valueName,
elementUtils.getTypeElement( enumTypeNames.iterator().next() )
)
.openWriter()) {
for ( String enumTypeName : enumTypeNames ) {
writer.append( enumTypeName ).append( " " );
}
}
catch (IOException e) {
processingEnvironment.getMessager()
.printMessage( Diagnostic.Kind.WARNING,
"could not write entity index " + e.getMessage() );
}
} );
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ private void handleNamedQuery(AnnotationMirror mirror, boolean checkHql) {
new WarningErrorHandler( context, getElement(), mirror, value, hql,
reportErrors, checkHql ),
ProcessorSessionFactory.create( context.getProcessingEnvironment(),
context.getEntityNameMappings(), context.getEnumTypesByValue() )
context.getEntityNameMappings(), context.getEnumTypesByValue(),
context.isIndexing() )
);
if ( !isJakartaDataStyle()
&& statement instanceof SqmSelectStatement<?> selectStatement ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2451,7 +2451,7 @@ private void validateHql(
true,
new ErrorHandler( context, isLocal(method) ? method : element, mirror, value, hql ),
ProcessorSessionFactory.create( context.getProcessingEnvironment(),
context.getEntityNameMappings(), context.getEnumTypesByValue() )
context.getEntityNameMappings(), context.getEnumTypesByValue(), context.isIndexing() )
);
if ( statement != null ) {
if ( statement instanceof SqmSelectStatement ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,9 @@ public abstract class ProcessorSessionFactory extends MockSessionFactory {
public static MockSessionFactory create(
ProcessingEnvironment environment,
Map<String,String> entityNameMappings,
Map<String, Set<String>> enumTypesByValue) {
return instance.make(environment, entityNameMappings, enumTypesByValue);
Map<String, Set<String>> enumTypesByValue,
boolean indexing) {
return instance.make(environment, indexing, entityNameMappings, enumTypesByValue);
}

static final Mocker<ProcessorSessionFactory> instance = Mocker.variadic(ProcessorSessionFactory.class);
Expand All @@ -88,16 +89,19 @@ public static MockSessionFactory create(
private final Elements elementUtil;
private final Types typeUtil;
private final Filer filer;
private final boolean indexing;
private final Map<String, String> entityNameMappings;
private final Map<String, Set<String>> enumTypesByValue;

public ProcessorSessionFactory(
ProcessingEnvironment processingEnvironment,
boolean indexing,
Map<String,String> entityNameMappings,
Map<String, Set<String>> enumTypesByValue) {
elementUtil = processingEnvironment.getElementUtils();
typeUtil = processingEnvironment.getTypeUtils();
filer = processingEnvironment.getFiler();
this.indexing = indexing;
this.entityNameMappings = entityNameMappings;
this.enumTypesByValue = enumTypesByValue;
}
Expand Down Expand Up @@ -130,7 +134,6 @@ else if (isElementCollectionProperty(property)) {
}
}


@Override
Type propertyType(String typeName, String propertyPath) {
final TypeElement type = findClassByQualifiedName(typeName);
Expand Down Expand Up @@ -220,15 +223,27 @@ Set<String> getEnumTypesForValue(String value) {
if ( result != null ) {
return result;
}
try (Reader reader = filer.getResource(StandardLocation.SOURCE_OUTPUT, ENTITY_INDEX, value)
.openReader(true); BufferedReader buffered = new BufferedReader(reader) ) {
return Set.of(split(" ", buffered.readLine()));
if ( indexing ) {
final Set<String> indexed = getIndexedEnumTypesByValue(value);
if ( indexed != null ) {
enumTypesByValue.put(value, indexed);
return indexed;
}
}
//TODO: else do a full scan like in findEntityByUnqualifiedName()
return null;
}

private @Nullable Set<String> getIndexedEnumTypesByValue(String value) {
try (Reader reader = filer.getResource( StandardLocation.SOURCE_OUTPUT, ENTITY_INDEX, value )
.openReader( true ); BufferedReader buffered = new BufferedReader( reader )) {
return Set.of( split( " ", buffered.readLine() ) );
}
catch (IOException ignore) {
}
try (Reader reader = filer.getResource(StandardLocation.CLASS_PATH, ENTITY_INDEX, '.' + value)
.openReader(true); BufferedReader buffered = new BufferedReader(reader) ) {
return Set.of(split(" ", buffered.readLine()));
try (Reader reader = filer.getResource( StandardLocation.CLASS_PATH, ENTITY_INDEX, '.' + value )
.openReader( true ); BufferedReader buffered = new BufferedReader( reader )) {
return Set.of( split( " ", buffered.readLine() ) );
}
catch (IOException ignore) {
}
Expand Down Expand Up @@ -503,27 +518,13 @@ private TypeElement findEntityByUnqualifiedName(String entityName) {
if ( cached != null ) {
return cached;
}
final String qualifiedName = entityNameMappings.get(entityName);
if ( qualifiedName != null ) {
final TypeElement result = elementUtil.getTypeElement(qualifiedName);
entityCache.put(entityName, result);
return result;
}
try (Reader reader = filer.getResource( StandardLocation.SOURCE_OUTPUT, ENTITY_INDEX, entityName)
.openReader(true); BufferedReader buffered = new BufferedReader(reader) ) {
final TypeElement result = elementUtil.getTypeElement(buffered.readLine());
entityCache.put(entityName, result);
return result;
}
catch (IOException ignore) {
}
try (Reader reader = filer.getResource(StandardLocation.CLASS_PATH, ENTITY_INDEX, entityName)
.openReader(true); BufferedReader buffered = new BufferedReader(reader) ) {
final TypeElement result = elementUtil.getTypeElement(buffered.readLine());
entityCache.put(entityName, result);
return result;
}
catch (IOException ignore) {

if ( indexing ) {
final TypeElement indexedEntity = findIndexedEntityByQualifiedName( entityName );
if ( indexedEntity != null ) {
entityCache.put(entityName, indexedEntity);
return indexedEntity;
}
}

TypeElement symbol =
Expand All @@ -543,6 +544,26 @@ private TypeElement findEntityByUnqualifiedName(String entityName) {
return null;
}

private @Nullable TypeElement findIndexedEntityByQualifiedName(String entityName) {
final String qualifiedName = entityNameMappings.get(entityName);
if ( qualifiedName != null ) {
return elementUtil.getTypeElement(qualifiedName);
}
try (Reader reader = filer.getResource( StandardLocation.SOURCE_OUTPUT, ENTITY_INDEX, entityName)
.openReader(true); BufferedReader buffered = new BufferedReader(reader) ) {
return elementUtil.getTypeElement(buffered.readLine());
}
catch (IOException ignore) {
}
try (Reader reader = filer.getResource(StandardLocation.CLASS_PATH, ENTITY_INDEX, entityName)
.openReader(true); BufferedReader buffered = new BufferedReader(reader) ) {
return elementUtil.getTypeElement(buffered.readLine());
}
catch (IOException ignore) {
}
return null;
}

public static TypeElement findEntityByUnqualifiedName(String entityName, ModuleElement module) {
for (Element element: module.getEnclosedElements()) {
if (element.getKind() == ElementKind.PACKAGE) {
Expand Down
Loading