HHH-18162 index creation in HibernateProcessor
This stores an index of entities and enum values in the entity.index directory. This approach has some downsides but works around some limitations of the processor API. Signed-off-by: Gavin King <gavin@hibernate.org>
This commit is contained in:
parent
ed2fdce0a6
commit
ebd8619f73
|
@ -13,6 +13,7 @@ import jakarta.persistence.metamodel.EntityType;
|
|||
import jakarta.persistence.metamodel.ManagedType;
|
||||
|
||||
import jakarta.persistence.metamodel.Metamodel;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.hibernate.Incubating;
|
||||
import org.hibernate.graph.spi.RootGraphImplementor;
|
||||
import org.hibernate.jpa.spi.JpaCompliance;
|
||||
|
@ -89,7 +90,8 @@ public interface JpaMetamodel extends Metamodel {
|
|||
|
||||
String qualifyImportableName(String queryName);
|
||||
|
||||
Set<String> getAllowedEnumLiteralTexts(String enumValue);
|
||||
@Nullable
|
||||
Set<String> getEnumTypesForValue(String enumValue);
|
||||
|
||||
EnumJavaType<?> getEnumType(String prefix);
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ import java.util.TreeMap;
|
|||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.hibernate.boot.model.NamedEntityGraphDefinition;
|
||||
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
||||
|
@ -281,8 +282,8 @@ public class JpaMetamodelImpl implements JpaMetamodelImplementor, Serializable {
|
|||
.collect( Collectors.toSet() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getAllowedEnumLiteralTexts(String enumValue) {
|
||||
@Override @Nullable
|
||||
public Set<String> getEnumTypesForValue(String enumValue) {
|
||||
return allowedEnumLiteralTexts.get(enumValue);
|
||||
}
|
||||
|
||||
|
|
|
@ -530,8 +530,8 @@ public class MappingMetamodelImpl extends QueryParameterBindingTypeResolverImpl
|
|||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getAllowedEnumLiteralTexts(String enumValue) {
|
||||
return jpaMetamodel.getAllowedEnumLiteralTexts(enumValue);
|
||||
public Set<String> getEnumTypesForValue(String enumValue) {
|
||||
return jpaMetamodel.getEnumTypesForValue(enumValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -2603,7 +2603,7 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
|||
ctx = ctx.getChild( 0 );
|
||||
|
||||
if ( ctx instanceof HqlParser.SimplePathContext ) {
|
||||
return creationContext.getJpaMetamodel().getAllowedEnumLiteralTexts( ctx.getText() );
|
||||
return creationContext.getJpaMetamodel().getEnumTypesForValue( ctx.getText() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,6 +106,9 @@ public final class Context {
|
|||
private String[] includes = {"*"};
|
||||
private String[] excludes = {};
|
||||
|
||||
private final Map<String, String> entityNameMappings = new HashMap<>();
|
||||
private final Map<String, Set<String>> enumTypesByValue = new HashMap<>();
|
||||
|
||||
public Context(ProcessingEnvironment processingEnvironment) {
|
||||
this.processingEnvironment = processingEnvironment;
|
||||
|
||||
|
@ -483,4 +486,24 @@ public final class Context {
|
|||
|| elements.stream().noneMatch(member -> member instanceof ExecutableElement
|
||||
&& getElementUtils().overrides((ExecutableElement) member, (ExecutableElement) inherited, type));
|
||||
}
|
||||
|
||||
public Map<String, String> getEntityNameMappings() {
|
||||
return entityNameMappings;
|
||||
}
|
||||
|
||||
public void addEntityNameMapping(String entityName, String qualifiedName) {
|
||||
entityNameMappings.put( entityName, qualifiedName );
|
||||
}
|
||||
|
||||
public @Nullable String qualifiedNameForEntityName(String entityName) {
|
||||
return entityNameMappings.get(entityName);
|
||||
}
|
||||
|
||||
public Map<String,Set<String>> getEnumTypesByValue() {
|
||||
return enumTypesByValue;
|
||||
}
|
||||
|
||||
public void addEnumValue(String type, String value) {
|
||||
enumTypesByValue.computeIfAbsent( value, s -> new HashSet<>() ).add( type );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,13 +22,19 @@ import javax.lang.model.SourceVersion;
|
|||
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.PackageElement;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.type.DeclaredType;
|
||||
import javax.lang.model.type.TypeKind;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
import javax.tools.Diagnostic;
|
||||
import javax.tools.StandardLocation;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
@ -42,12 +48,36 @@ import static org.hibernate.processor.HibernateProcessor.ADD_GENERATED_ANNOTATIO
|
|||
import static org.hibernate.processor.HibernateProcessor.ADD_GENERATION_DATE;
|
||||
import static org.hibernate.processor.HibernateProcessor.ADD_SUPPRESS_WARNINGS_ANNOTATION;
|
||||
import static org.hibernate.processor.HibernateProcessor.DEBUG_OPTION;
|
||||
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.LAZY_XML_PARSING;
|
||||
import static org.hibernate.processor.HibernateProcessor.ORM_XML_OPTION;
|
||||
import static org.hibernate.processor.HibernateProcessor.PERSISTENCE_XML_OPTION;
|
||||
import static org.hibernate.processor.HibernateProcessor.SUPPRESS_JAKARTA_DATA_METAMODEL;
|
||||
import static org.hibernate.processor.util.Constants.*;
|
||||
import static org.hibernate.processor.util.Constants.EMBEDDABLE;
|
||||
import static org.hibernate.processor.util.Constants.ENTITY;
|
||||
import static org.hibernate.processor.util.Constants.FIND;
|
||||
import static org.hibernate.processor.util.Constants.HIB_FETCH_PROFILE;
|
||||
import static org.hibernate.processor.util.Constants.HIB_FETCH_PROFILES;
|
||||
import static org.hibernate.processor.util.Constants.HIB_FILTER_DEF;
|
||||
import static org.hibernate.processor.util.Constants.HIB_FILTER_DEFS;
|
||||
import static org.hibernate.processor.util.Constants.HIB_NAMED_NATIVE_QUERIES;
|
||||
import static org.hibernate.processor.util.Constants.HIB_NAMED_NATIVE_QUERY;
|
||||
import static org.hibernate.processor.util.Constants.HIB_NAMED_QUERIES;
|
||||
import static org.hibernate.processor.util.Constants.HIB_NAMED_QUERY;
|
||||
import static org.hibernate.processor.util.Constants.HQL;
|
||||
import static org.hibernate.processor.util.Constants.JD_REPOSITORY;
|
||||
import static org.hibernate.processor.util.Constants.MAPPED_SUPERCLASS;
|
||||
import static org.hibernate.processor.util.Constants.NAMED_ENTITY_GRAPH;
|
||||
import static org.hibernate.processor.util.Constants.NAMED_ENTITY_GRAPHS;
|
||||
import static org.hibernate.processor.util.Constants.NAMED_NATIVE_QUERIES;
|
||||
import static org.hibernate.processor.util.Constants.NAMED_NATIVE_QUERY;
|
||||
import static org.hibernate.processor.util.Constants.NAMED_QUERIES;
|
||||
import static org.hibernate.processor.util.Constants.NAMED_QUERY;
|
||||
import static org.hibernate.processor.util.Constants.SQL;
|
||||
import static org.hibernate.processor.util.Constants.SQL_RESULT_SET_MAPPING;
|
||||
import static org.hibernate.processor.util.Constants.SQL_RESULT_SET_MAPPINGS;
|
||||
import static org.hibernate.processor.util.TypeUtils.containsAnnotation;
|
||||
import static org.hibernate.processor.util.TypeUtils.getAnnotationMirror;
|
||||
import static org.hibernate.processor.util.TypeUtils.getAnnotationValue;
|
||||
|
@ -85,7 +115,8 @@ import static org.hibernate.processor.util.TypeUtils.isClassOrRecordType;
|
|||
ADD_GENERATION_DATE,
|
||||
ADD_GENERATED_ANNOTATION,
|
||||
ADD_SUPPRESS_WARNINGS_ANNOTATION,
|
||||
SUPPRESS_JAKARTA_DATA_METAMODEL
|
||||
SUPPRESS_JAKARTA_DATA_METAMODEL,
|
||||
INCLUDE, EXCLUDE
|
||||
})
|
||||
public class HibernateProcessor extends AbstractProcessor {
|
||||
|
||||
|
@ -157,6 +188,8 @@ public class HibernateProcessor extends AbstractProcessor {
|
|||
|
||||
private static final boolean ALLOW_OTHER_PROCESSORS_TO_CLAIM_ANNOTATIONS = false;
|
||||
|
||||
public static final String ENTITY_INDEX = "entity.index";
|
||||
|
||||
private Context context;
|
||||
|
||||
@Override
|
||||
|
@ -168,7 +201,7 @@ public class HibernateProcessor extends AbstractProcessor {
|
|||
"Hibernate compile-time tooling " + Version.getVersionString()
|
||||
);
|
||||
|
||||
boolean fullyAnnotationConfigured = handleSettings( processingEnvironment );
|
||||
final boolean fullyAnnotationConfigured = handleSettings( processingEnvironment );
|
||||
if ( !fullyAnnotationConfigured ) {
|
||||
new JpaDescriptorParser( context ).parseXml();
|
||||
if ( context.isFullyXmlConfigured() ) {
|
||||
|
@ -275,6 +308,7 @@ public class HibernateProcessor extends AbstractProcessor {
|
|||
if ( !elementsToRedo.isEmpty() ) {
|
||||
context.logMessage( Diagnostic.Kind.ERROR, "Failed to generate code for " + elementsToRedo );
|
||||
}
|
||||
writeIndex();
|
||||
}
|
||||
else if ( context.isFullyXmlConfigured() ) {
|
||||
context.logMessage(
|
||||
|
@ -518,6 +552,9 @@ public class HibernateProcessor extends AbstractProcessor {
|
|||
if ( isClassOrRecordType( element ) ) {
|
||||
if ( hasAnnotation( element, ENTITY, MAPPED_SUPERCLASS, EMBEDDABLE ) ) {
|
||||
final TypeElement typeElement = (TypeElement) element;
|
||||
indexEntityName( typeElement );
|
||||
indexEnumFields( typeElement );
|
||||
|
||||
final String qualifiedName = typeElement.getQualifiedName().toString();
|
||||
final Metamodel alreadyExistingMetaEntity =
|
||||
tryGettingExistingEntityFromContext( typeElement, qualifiedName );
|
||||
|
@ -565,6 +602,54 @@ public class HibernateProcessor extends AbstractProcessor {
|
|||
}
|
||||
}
|
||||
|
||||
private void indexEntityName(TypeElement typeElement) {
|
||||
final AnnotationMirror mirror = getAnnotationMirror( typeElement, ENTITY );
|
||||
if ( mirror != null ) {
|
||||
context.addEntityNameMapping( entityName( typeElement, mirror ),
|
||||
typeElement.getQualifiedName().toString() );
|
||||
}
|
||||
}
|
||||
|
||||
private static String entityName(TypeElement entityType, AnnotationMirror mirror) {
|
||||
final String className = entityType.getSimpleName().toString();
|
||||
final AnnotationValue name = getAnnotationValue(mirror, "name" );
|
||||
if (name != null) {
|
||||
final String explicitName = name.getValue().toString();
|
||||
if ( !explicitName.isEmpty() ) {
|
||||
return explicitName;
|
||||
}
|
||||
}
|
||||
return className;
|
||||
}
|
||||
|
||||
private void indexEnumFields(TypeElement typeElement) {
|
||||
for ( Element member : context.getAllMembers(typeElement) ) {
|
||||
switch ( member.getKind() ) {
|
||||
case FIELD:
|
||||
indexEnumValues( member.asType() );
|
||||
break;
|
||||
case METHOD:
|
||||
indexEnumValues( ((ExecutableElement) member).getReturnType() );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void indexEnumValues(TypeMirror type) {
|
||||
if ( type.getKind() == TypeKind.DECLARED ) {
|
||||
final DeclaredType declaredType = (DeclaredType) type;
|
||||
final TypeElement fieldType = (TypeElement) declaredType.asElement();
|
||||
if ( fieldType.getKind() == ElementKind.ENUM ) {
|
||||
for (Element enumMember : fieldType.getEnclosedElements() ) {
|
||||
if ( enumMember.getKind() == ElementKind.ENUM_CONSTANT) {
|
||||
context.addEnumValue( fieldType.getQualifiedName().toString(),
|
||||
enumMember.getSimpleName().toString() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleRootElementAuxiliaryAnnotationMirrors(final Element element) {
|
||||
if ( element instanceof TypeElement ) {
|
||||
final AnnotationMetaEntity metaEntity =
|
||||
|
@ -615,4 +700,33 @@ public class HibernateProcessor extends AbstractProcessor {
|
|||
}
|
||||
}
|
||||
|
||||
private void writeIndex() {
|
||||
final ProcessingEnvironment processingEnvironment = context.getProcessingEnvironment();
|
||||
context.getEntityNameMappings().forEach((entityName, className) -> {
|
||||
try (Writer writer = processingEnvironment.getFiler()
|
||||
.createResource(StandardLocation.SOURCE_OUTPUT, ENTITY_INDEX, entityName)
|
||||
.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)
|
||||
.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());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,7 +84,8 @@ public abstract class AnnotationMeta implements Metamodel {
|
|||
final AnnotationValue nameValue = getAnnotationValue( mirror, "name" );
|
||||
if ( nameValue != null ) {
|
||||
final String name = nameValue.getValue().toString();
|
||||
final boolean reportErrors = getContext().checkNamedQuery( name );
|
||||
final Context context = getContext();
|
||||
final boolean reportErrors = context.checkNamedQuery( name );
|
||||
final AnnotationValue value = getAnnotationValue( mirror, "query" );
|
||||
if ( value != null ) {
|
||||
final Object query = value.getValue();
|
||||
|
@ -98,9 +99,10 @@ public abstract class AnnotationMeta implements Metamodel {
|
|||
// If we are in the scope of @CheckHQL, semantic errors in the
|
||||
// query result in compilation errors. Otherwise, they only
|
||||
// result in warnings, so we don't break working code.
|
||||
new WarningErrorHandler( getContext(), getElement(), mirror, value, hql,
|
||||
new WarningErrorHandler( context, getElement(), mirror, value, hql,
|
||||
reportErrors, checkHql ),
|
||||
ProcessorSessionFactory.create( getContext().getProcessingEnvironment() )
|
||||
ProcessorSessionFactory.create( context.getProcessingEnvironment(),
|
||||
context.getEntityNameMappings(), context.getEnumTypesByValue() )
|
||||
);
|
||||
if ( statement instanceof SqmSelectStatement
|
||||
&& isQueryMethodName( name ) ) {
|
||||
|
@ -112,7 +114,7 @@ public abstract class AnnotationMeta implements Metamodel {
|
|||
isRepository(),
|
||||
getSessionType(),
|
||||
getSessionVariableName(),
|
||||
getContext().addNonnullAnnotation()
|
||||
context.addNonnullAnnotation()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -2469,7 +2469,8 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
returnType,
|
||||
true,
|
||||
new ErrorHandler( context, isLocal(method) ? method : element, mirror, value, hql ),
|
||||
ProcessorSessionFactory.create( context.getProcessingEnvironment() )
|
||||
ProcessorSessionFactory.create( context.getProcessingEnvironment(),
|
||||
context.getEntityNameMappings(), context.getEnumTypesByValue() )
|
||||
);
|
||||
if ( statement != null ) {
|
||||
if ( statement instanceof SqmSelectStatement ) {
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
package org.hibernate.processor.annotation;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.hibernate.processor.Context;
|
||||
import org.hibernate.processor.model.MetaAttribute;
|
||||
import org.hibernate.processor.model.Metamodel;
|
||||
import org.hibernate.processor.util.Constants;
|
||||
|
@ -18,6 +19,7 @@ import org.hibernate.type.descriptor.java.JavaType;
|
|||
|
||||
import javax.lang.model.element.ModuleElement;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.util.Elements;
|
||||
import java.util.List;
|
||||
import java.util.TreeSet;
|
||||
|
||||
|
@ -194,13 +196,19 @@ class NamedQueryMethod implements MetaAttribute {
|
|||
}
|
||||
|
||||
private @Nullable TypeElement entityType(String entityName) {
|
||||
final Context context = annotationMeta.getContext();
|
||||
final Elements elementUtils = context.getElementUtils();
|
||||
final String qualifiedName = context.qualifiedNameForEntityName(entityName);
|
||||
if ( qualifiedName != null ) {
|
||||
return elementUtils.getTypeElement(qualifiedName);
|
||||
}
|
||||
TypeElement symbol =
|
||||
findEntityByUnqualifiedName( entityName,
|
||||
annotationMeta.getContext().getElementUtils().getModuleElement("") );
|
||||
elementUtils.getModuleElement("") );
|
||||
if ( symbol != null ) {
|
||||
return symbol;
|
||||
}
|
||||
for ( ModuleElement module : annotationMeta.getContext().getElementUtils().getAllModuleElements() ) {
|
||||
for ( ModuleElement module : elementUtils.getAllModuleElements() ) {
|
||||
symbol = findEntityByUnqualifiedName( entityName, module );
|
||||
if ( symbol != null ) {
|
||||
return symbol;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
package org.hibernate.processor.validation;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.hibernate.CustomEntityDirtinessStrategy;
|
||||
import org.hibernate.EntityNameResolver;
|
||||
import org.hibernate.MappingException;
|
||||
|
@ -58,7 +59,6 @@ import org.hibernate.metamodel.internal.MetadataContext;
|
|||
import org.hibernate.metamodel.internal.RuntimeMetamodelsImpl;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.model.domain.DomainType;
|
||||
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
|
||||
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
||||
import org.hibernate.metamodel.model.domain.ManagedDomainType;
|
||||
import org.hibernate.metamodel.model.domain.PersistentAttribute;
|
||||
|
@ -729,6 +729,11 @@ public abstract class MockSessionFactory
|
|||
public EntityPersister findEntityDescriptor(String entityName) {
|
||||
return createEntityPersister(entityName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getEnumTypesForValue(String enumValue) {
|
||||
return MockSessionFactory.this.getEnumTypesForValue(enumValue);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -868,9 +873,9 @@ public abstract class MockSessionFactory
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getAllowedEnumLiteralTexts(String enumValue) {
|
||||
return MockSessionFactory.this.getAllowedEnumLiteralTexts().get(enumValue);
|
||||
@Override @Nullable
|
||||
public Set<String> getEnumTypesForValue(String enumValue) {
|
||||
return MockSessionFactory.this.getEnumTypesForValue(enumValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -879,8 +884,9 @@ public abstract class MockSessionFactory
|
|||
}
|
||||
}
|
||||
|
||||
Map<String, Set<String>> getAllowedEnumLiteralTexts() {
|
||||
return emptyMap();
|
||||
@Nullable
|
||||
Set<String> getEnumTypesForValue(String value) {
|
||||
return emptySet();
|
||||
}
|
||||
|
||||
class MockMappedDomainType<X> extends MappedSuperclassTypeImpl<X>{
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
package org.hibernate.processor.validation;
|
||||
|
||||
import jakarta.persistence.AccessType;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.hibernate.PropertyNotFoundException;
|
||||
import org.hibernate.engine.spi.Mapping;
|
||||
import org.hibernate.type.BasicType;
|
||||
|
@ -21,6 +22,7 @@ import org.hibernate.type.descriptor.jdbc.JdbcType;
|
|||
import org.hibernate.type.descriptor.jdbc.VarcharJdbcType;
|
||||
import org.hibernate.type.internal.BasicTypeImpl;
|
||||
|
||||
import javax.annotation.processing.Filer;
|
||||
import javax.annotation.processing.ProcessingEnvironment;
|
||||
import javax.lang.model.element.AnnotationMirror;
|
||||
import javax.lang.model.element.AnnotationValue;
|
||||
|
@ -40,10 +42,13 @@ import javax.lang.model.type.TypeMirror;
|
|||
import javax.lang.model.type.TypeVariable;
|
||||
import javax.lang.model.util.Elements;
|
||||
import javax.lang.model.util.Types;
|
||||
import javax.tools.StandardLocation;
|
||||
import java.beans.Introspector;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
@ -65,8 +70,11 @@ import static org.hibernate.processor.util.Constants.JAVA_OBJECT;
|
|||
@SuppressWarnings("nullness")
|
||||
public abstract class ProcessorSessionFactory extends MockSessionFactory {
|
||||
|
||||
public static MockSessionFactory create(ProcessingEnvironment environment) {
|
||||
return instance.make(environment);
|
||||
public static MockSessionFactory create(
|
||||
ProcessingEnvironment environment,
|
||||
Map<String,String> entityNameMappings,
|
||||
Map<String, Set<String>> enumTypesByValue) {
|
||||
return instance.make(environment, entityNameMappings, enumTypesByValue);
|
||||
}
|
||||
|
||||
static final Mocker<ProcessorSessionFactory> instance = Mocker.variadic(ProcessorSessionFactory.class);
|
||||
|
@ -80,10 +88,19 @@ public abstract class ProcessorSessionFactory extends MockSessionFactory {
|
|||
|
||||
private final Elements elementUtil;
|
||||
private final Types typeUtil;
|
||||
private final Filer filer;
|
||||
private final Map<String, String> entityNameMappings;
|
||||
private final Map<String, Set<String>> enumTypesByValue;
|
||||
|
||||
public ProcessorSessionFactory(ProcessingEnvironment processingEnv) {
|
||||
elementUtil = processingEnv.getElementUtils();
|
||||
typeUtil = processingEnv.getTypeUtils();
|
||||
public ProcessorSessionFactory(
|
||||
ProcessingEnvironment processingEnvironment,
|
||||
Map<String,String> entityNameMappings,
|
||||
Map<String, Set<String>> enumTypesByValue) {
|
||||
elementUtil = processingEnvironment.getElementUtils();
|
||||
typeUtil = processingEnvironment.getTypeUtils();
|
||||
filer = processingEnvironment.getFiler();
|
||||
this.entityNameMappings = entityNameMappings;
|
||||
this.enumTypesByValue = enumTypesByValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -196,29 +213,28 @@ public abstract class ProcessorSessionFactory extends MockSessionFactory {
|
|||
: IntegerJdbcType.INSTANCE;
|
||||
}
|
||||
|
||||
final Map<String, Set<String>> result = new HashMap<>();
|
||||
public static final String ENTITY_INDEX = "entity.index";
|
||||
|
||||
@Override
|
||||
Map<String, Set<String>> getAllowedEnumLiteralTexts() {
|
||||
//TODO: elementUtil.getAllModuleElements();
|
||||
if ( result.isEmpty() ) {
|
||||
for (Element mod : elementUtil.getModuleElement("").getEnclosedElements()) {
|
||||
for (Element element : mod.getEnclosedElements()) {
|
||||
if (element.getKind() == ElementKind.ENUM) {
|
||||
TypeElement typeElement = (TypeElement) element;
|
||||
for (Element member : element.getEnclosedElements()) {
|
||||
if (member.getKind() == ElementKind.ENUM_CONSTANT) {
|
||||
String name = member.getSimpleName().toString();
|
||||
result.computeIfAbsent( name, s -> new HashSet<>() )
|
||||
.add( typeElement.getQualifiedName().toString() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override @Nullable
|
||||
Set<String> getEnumTypesForValue(String value) {
|
||||
Set<String> result = enumTypesByValue.get(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(buffered.readLine().split(" "));
|
||||
}
|
||||
catch (IOException e) {
|
||||
}
|
||||
try (Reader reader = filer.getResource(StandardLocation.CLASS_PATH, ENTITY_INDEX, '.' + value)
|
||||
.openReader(true); BufferedReader buffered = new BufferedReader(reader) ) {
|
||||
return Set.of(buffered.readLine().split(" "));
|
||||
}
|
||||
catch (IOException e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Type elementCollectionElementType(TypeElement elementType,
|
||||
String role, String path,
|
||||
|
@ -430,6 +446,30 @@ public abstract class ProcessorSessionFactory extends MockSessionFactory {
|
|||
if ( cached != null ) {
|
||||
return cached;
|
||||
}
|
||||
String qualifiedName = entityNameMappings.get(entityName);
|
||||
if ( qualifiedName != null ) {
|
||||
TypeElement result = elementUtil.getTypeElement(qualifiedName);
|
||||
entityCache.put(entityName, result);
|
||||
return result;
|
||||
}
|
||||
StandardLocation location = StandardLocation.SOURCE_OUTPUT;
|
||||
try (Reader reader = filer.getResource(location, ENTITY_INDEX, entityName)
|
||||
.openReader(true); BufferedReader buffered = new BufferedReader(reader) ) {
|
||||
TypeElement result = elementUtil.getTypeElement(buffered.readLine());
|
||||
entityCache.put(entityName, result);
|
||||
return result;
|
||||
}
|
||||
catch (IOException e) {
|
||||
}
|
||||
try (Reader reader = filer.getResource(StandardLocation.CLASS_PATH, ENTITY_INDEX, entityName)
|
||||
.openReader(true); BufferedReader buffered = new BufferedReader(reader) ) {
|
||||
TypeElement result = elementUtil.getTypeElement(buffered.readLine());
|
||||
entityCache.put(entityName, result);
|
||||
return result;
|
||||
}
|
||||
catch (IOException e) {
|
||||
}
|
||||
|
||||
TypeElement symbol =
|
||||
findEntityByUnqualifiedName(entityName,
|
||||
elementUtil.getModuleElement(""));
|
||||
|
|
Loading…
Reference in New Issue