fix up warnings in BasicDotIdentifierConsumer + genericize FullyQualifiedReflectivePathTerminal

This commit is contained in:
Gavin King 2024-09-10 08:08:47 +02:00
parent 0dedc62270
commit 4a974fe976
5 changed files with 62 additions and 51 deletions

View File

@ -30,18 +30,17 @@ import org.hibernate.type.descriptor.java.EnumJavaType;
import org.hibernate.type.descriptor.java.JavaType; import org.hibernate.type.descriptor.java.JavaType;
/** /**
* @asciidoc * A {@link DotIdentifierConsumer} used to interpret paths outside any
* * specific context. This is the handler used at the root of the handler
* DotIdentifierHandler used to interpret paths outside of any specific * stack.
* context. This is the handler used at the root of the handler stack. * <p>
* * It can recognize any number of types of paths:
* It can recognize any number of types of paths - * <ul>
* * <li>fully-qualified class names (entity or otherwise)
* * fully-qualified class names (entity or otherwise) * <li>static field references, e.g. {@code MyClass.SOME_FIELD}
* * static field references, e.g. `MyClass.SOME_FIELD` * <li>enum value references, e.g. {@code Sex.MALE}
* * enum value references, e.g. `Sex.MALE` * <li>navigable-path
* * navigable-path * </ul>
* * others?
* *
* @author Steve Ebersole * @author Steve Ebersole
*/ */
@ -189,11 +188,11 @@ public class BasicDotIdentifierConsumer implements DotIdentifierConsumer {
final NodeBuilder nodeBuilder = creationContext.getNodeBuilder(); final NodeBuilder nodeBuilder = creationContext.getNodeBuilder();
if ( importableName != null ) { if ( importableName != null ) {
final ManagedDomainType<?> managedType = jpaMetamodel.managedType( importableName ); final ManagedDomainType<?> managedType = jpaMetamodel.managedType( importableName );
if ( managedType instanceof EntityDomainType<?> ) { if ( managedType instanceof EntityDomainType<?> entityDomainType ) {
return new SqmLiteralEntityType<>( (EntityDomainType<?>) managedType, nodeBuilder ); return new SqmLiteralEntityType<>( entityDomainType, nodeBuilder );
} }
else if ( managedType instanceof EmbeddableDomainType<?> ) { else if ( managedType instanceof EmbeddableDomainType<?> embeddableDomainType ) {
return new SqmLiteralEmbeddableType<>( (EmbeddableDomainType<?>) managedType, nodeBuilder ); return new SqmLiteralEmbeddableType<>( embeddableDomainType, nodeBuilder );
} }
} }
@ -217,35 +216,49 @@ public class BasicDotIdentifierConsumer implements DotIdentifierConsumer {
try { try {
final EnumJavaType<?> enumType = jpaMetamodel.getEnumType( prefix ); final EnumJavaType<?> enumType = jpaMetamodel.getEnumType( prefix );
if ( enumType != null ) { if ( enumType != null ) {
return new SqmEnumLiteral( return sqmEnumLiteral( jpaMetamodel, enumType, terminal, nodeBuilder );
jpaMetamodel.enumValue( enumType, terminal ),
enumType,
terminal,
nodeBuilder
);
} }
final JavaType<?> fieldJtdTest = jpaMetamodel.getJavaConstantType( prefix, terminal ); final JavaType<?> fieldJtdTest = jpaMetamodel.getJavaConstantType( prefix, terminal );
if ( fieldJtdTest != null ) { if ( fieldJtdTest != null ) {
final Object constantValue = jpaMetamodel.getJavaConstant( prefix, terminal ); return sqmFieldLiteral( jpaMetamodel, prefix, terminal, fieldJtdTest, nodeBuilder );
return new SqmFieldLiteral( constantValue, fieldJtdTest, terminal, nodeBuilder );
} }
} }
catch (Exception ignore) { catch (Exception ignore) {
} }
} }
throw new SemanticException( throw new SemanticException( "Could not interpret path expression '" + path + "'" );
String.format( }
"Could not interpret path expression '%s'",
path private static <E> SqmFieldLiteral<E> sqmFieldLiteral(
) JpaMetamodelImplementor jpaMetamodel,
String prefix,
String terminal,
JavaType<E> fieldJtdTest,
NodeBuilder nodeBuilder) {
return new SqmFieldLiteral<>(
jpaMetamodel.getJavaConstant( prefix, terminal ),
fieldJtdTest,
terminal,
nodeBuilder
);
}
private static <E extends Enum<E>> SqmEnumLiteral<E> sqmEnumLiteral(
JpaMetamodelImplementor jpaMetamodel,
EnumJavaType<E> enumType,
String terminal,
NodeBuilder nodeBuilder) {
return new SqmEnumLiteral<>(
jpaMetamodel.enumValue( enumType, terminal ),
enumType,
terminal,
nodeBuilder
); );
} }
protected void validateAsRoot(SqmFrom<?, ?> pathRoot) { protected void validateAsRoot(SqmFrom<?, ?> pathRoot) {
} }
@Override @Override

View File

@ -31,7 +31,7 @@ public class FullyQualifiedReflectivePath implements SemanticPathPart, FullyQual
boolean isTerminal, boolean isTerminal,
SqmCreationState creationState) { SqmCreationState creationState) {
if ( isTerminal ) { if ( isTerminal ) {
return new FullyQualifiedReflectivePathTerminal( this, name, creationState ); return new FullyQualifiedReflectivePathTerminal<>( this, name, creationState );
} }
else { else {
return new FullyQualifiedReflectivePath( this, name ); return new FullyQualifiedReflectivePath( this, name );

View File

@ -35,17 +35,15 @@ import org.hibernate.type.descriptor.java.JavaType;
import jakarta.persistence.criteria.Expression; import jakarta.persistence.criteria.Expression;
import jakarta.persistence.criteria.Predicate; import jakarta.persistence.criteria.Predicate;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.hibernate.type.descriptor.java.spi.JavaTypeRegistry; import org.hibernate.type.descriptor.java.spi.JavaTypeRegistry;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class FullyQualifiedReflectivePathTerminal public class FullyQualifiedReflectivePathTerminal<E>
extends FullyQualifiedReflectivePath extends FullyQualifiedReflectivePath
implements SqmExpression { implements SqmExpression<E> {
private final @Nullable SqmExpressible<?> expressibleType; private final @Nullable SqmExpressible<E> expressibleType;
private final SqmCreationState creationState; private final SqmCreationState creationState;
private final Function<SemanticQueryWalker<?>,?> handler; private final Function<SemanticQueryWalker<?>,?> handler;
@ -64,7 +62,7 @@ public class FullyQualifiedReflectivePathTerminal
} }
@Override @Override
public FullyQualifiedReflectivePathTerminal copy(SqmCopyContext context) { public FullyQualifiedReflectivePathTerminal<E> copy(SqmCopyContext context) {
return this; return this;
} }
@ -139,23 +137,23 @@ public class FullyQualifiedReflectivePathTerminal
} }
@Override @Override
public @Nullable SqmExpressible<?> getNodeType() { public @Nullable SqmExpressible<E> getNodeType() {
return expressibleType; return expressibleType;
} }
@Override @Override
public Object accept(SemanticQueryWalker walker) { public <X> X accept(SemanticQueryWalker<X> walker) {
return handler.apply( walker ); return (X) handler.apply( walker );
} }
@Override @Override
public JavaType<?> getJavaTypeDescriptor() { public JavaType<E> getJavaTypeDescriptor() {
return expressibleType == null ? null : expressibleType.getExpressibleJavaType(); return expressibleType == null ? null : expressibleType.getExpressibleJavaType();
} }
@Override @Override
public void applyInferableType(@Nullable SqmExpressible type) { public void applyInferableType(@Nullable SqmExpressible<?> type) {
} }
@Override @Override
@ -201,7 +199,7 @@ public class FullyQualifiedReflectivePathTerminal
} }
@Override @Override
public SqmExpression<?> as(Class type) { public <X> SqmExpression<X> as(Class<X> type) {
return null; return null;
} }
@ -236,7 +234,7 @@ public class FullyQualifiedReflectivePathTerminal
} }
@Override @Override
public SqmExpression cast(Class type) { public <X> SqmExpression<X> cast(Class<X> type) {
return null; return null;
} }
@ -266,7 +264,7 @@ public class FullyQualifiedReflectivePathTerminal
} }
@Override @Override
public JpaSelection<?> alias(String name) { public JpaSelection<E> alias(String name) {
return null; return null;
} }

View File

@ -337,7 +337,7 @@ public class QualifiedJoinPathConsumer implements DotIdentifierConsumer {
@Override @Override
public void consumeIdentifier(String identifier, boolean isTerminal, boolean allowReuse) { public void consumeIdentifier(String identifier, boolean isTerminal, boolean allowReuse) {
if ( path.length() != 0 ) { if ( !path.isEmpty() ) {
path.append( '.' ); path.append( '.' );
} }
path.append( identifier ); path.append( identifier );

View File

@ -53,8 +53,8 @@ public class QualifiedJoinPredicatePathConsumer extends BasicDotIdentifierConsum
final SqmCreationProcessingState processingState = getCreationState().getCurrentProcessingState(); final SqmCreationProcessingState processingState = getCreationState().getCurrentProcessingState();
// First, we need to find out if the current join is part of current processing query // First, we need to find out if the current join is part of current processing query
final SqmQuery<?> currentProcessingQuery = processingState.getProcessingQuery(); final SqmQuery<?> currentProcessingQuery = processingState.getProcessingQuery();
if ( currentProcessingQuery instanceof SqmSelectQuery<?> ) { if ( currentProcessingQuery instanceof SqmSelectQuery<?> selectQuery ) {
final SqmQuerySpec<?> querySpec = ( (SqmSelectQuery<?>) currentProcessingQuery ).getQuerySpec(); final SqmQuerySpec<?> querySpec = selectQuery.getQuerySpec();
final SqmFromClause fromClause = querySpec.getFromClause(); final SqmFromClause fromClause = querySpec.getFromClause();
// If the current processing query contains the root of the current join, // If the current processing query contains the root of the current join,
// then the root of the processing path must be a root of one of the parent queries // then the root of the processing path must be a root of one of the parent queries
@ -96,8 +96,8 @@ public class QualifiedJoinPredicatePathConsumer extends BasicDotIdentifierConsum
SqmCreationProcessingState processingState) { SqmCreationProcessingState processingState) {
while ( processingState != null ) { while ( processingState != null ) {
final SqmQuery<?> processingQuery = processingState.getProcessingQuery(); final SqmQuery<?> processingQuery = processingState.getProcessingQuery();
if ( processingQuery instanceof SqmSelectQuery<?> ) { if ( processingQuery instanceof SqmSelectQuery<?> selectQuery ) {
final SqmQuerySpec<?> querySpec = ( (SqmSelectQuery<?>) processingQuery ).getQuerySpec(); final SqmQuerySpec<?> querySpec = selectQuery.getQuerySpec();
final SqmFromClause fromClause = querySpec.getFromClause(); final SqmFromClause fromClause = querySpec.getFromClause();
// If we are in a subquery, the "foreign" from element could be one of the subquery roots, // If we are in a subquery, the "foreign" from element could be one of the subquery roots,
// which is totally fine. The aim of this check is to prevent uses of different "spaces" // which is totally fine. The aim of this check is to prevent uses of different "spaces"