Skip to content

Commit 4c06810

Browse files
committed
some refactoring and cleanups in the graph package
1 parent 7f34241 commit 4c06810

File tree

6 files changed

+102
-137
lines changed

6 files changed

+102
-137
lines changed

hibernate-core/src/main/java/org/hibernate/annotations/NamedEntityGraph.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
* Entity graph names must be unique within the persistence unit.
4646
* <p/>
4747
* When applied to a root entity class, the name is optional and
48-
* defaults to the entity-name of that entity.
48+
* defaults to the JPA entity name of that entity.
4949
*/
5050
String name() default "";
5151

hibernate-core/src/main/java/org/hibernate/boot/model/internal/NamedGraphCreatorParsed.java

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,11 @@
44
*/
55
package org.hibernate.boot.model.internal;
66

7-
import org.antlr.v4.runtime.CharStreams;
8-
import org.antlr.v4.runtime.CommonTokenStream;
97
import org.checkerframework.checker.nullness.qual.NonNull;
108
import org.checkerframework.checker.nullness.qual.Nullable;
119
import org.hibernate.UnknownEntityTypeException;
1210
import org.hibernate.annotations.NamedEntityGraph;
1311
import org.hibernate.boot.model.NamedGraphCreator;
14-
import org.hibernate.grammars.graph.GraphLanguageLexer;
1512
import org.hibernate.grammars.graph.GraphLanguageParser;
1613
import org.hibernate.graph.InvalidGraphException;
1714
import org.hibernate.graph.spi.GraphParserEntityClassResolver;
@@ -20,6 +17,7 @@
2017
import org.hibernate.graph.spi.RootGraphImplementor;
2118
import org.hibernate.metamodel.model.domain.EntityDomainType;
2219

20+
import static org.hibernate.graph.internal.parse.GraphParsing.parseText;
2321
import static org.hibernate.internal.util.StringHelper.nullIfEmpty;
2422

2523
/**
@@ -44,36 +42,33 @@ class NamedGraphCreatorParsed implements NamedGraphCreator {
4442
public RootGraphImplementor<?> createEntityGraph(
4543
GraphParserEntityClassResolver entityDomainClassResolver,
4644
GraphParserEntityNameResolver entityDomainNameResolver) {
47-
final var lexer = new GraphLanguageLexer( CharStreams.fromString( annotation.graph() ) );
48-
final var parser = new GraphLanguageParser( new CommonTokenStream( lexer ) );
49-
final var graphContext = parser.graph();
50-
45+
final var graphContext = parseText( annotation.graph() );
5146
final var typeIndicator = graphContext.typeIndicator();
47+
final EntityDomainType<?> entityDomainType;
48+
final String jpaEntityName;
5249
if ( entityType == null ) {
5350
if ( typeIndicator == null ) {
54-
throw new InvalidGraphException( "Expecting graph text to include an entity name : " + annotation.graph() );
51+
throw new InvalidGraphException( "Expecting graph text to include an entity name: " + annotation.graph() );
5552
}
56-
final String jpaEntityName = typeIndicator.TYPE_NAME().toString();
57-
final var entityDomainType = entityDomainNameResolver.resolveEntityName( jpaEntityName );
58-
final String name = this.name == null ? jpaEntityName : this.name;
59-
return parse( entityDomainNameResolver, name, entityDomainType, graphContext );
53+
jpaEntityName = typeIndicator.TYPE_NAME().toString();
54+
entityDomainType = entityDomainNameResolver.resolveEntityName( jpaEntityName );
6055
}
6156
else {
6257
if ( typeIndicator != null ) {
63-
throw new InvalidGraphException( "Expecting graph text to not include an entity name : " + annotation.graph() );
58+
throw new InvalidGraphException( "Expecting graph text to not include an entity name: " + annotation.graph() );
6459
}
65-
final var entityDomainType = entityDomainClassResolver.resolveEntityClass( entityType );
66-
final String name = this.name == null ? entityDomainType.getName() : this.name;
67-
return parse( entityDomainNameResolver, name, entityDomainType, graphContext );
60+
entityDomainType = entityDomainClassResolver.resolveEntityClass( entityType );
61+
jpaEntityName = entityDomainType.getName();
6862
}
63+
return visit( name == null ? jpaEntityName : name,
64+
entityDomainType, entityDomainNameResolver, graphContext );
6965
}
7066

71-
private static @NonNull RootGraphImplementor<?> parse(
72-
GraphParserEntityNameResolver entityDomainNameResolver,
67+
private static @NonNull RootGraphImplementor<?> visit(
7368
String name,
74-
EntityDomainType<?> entityDomainType,
69+
EntityDomainType<?> entityDomainType, GraphParserEntityNameResolver entityDomainNameResolver,
7570
GraphLanguageParser.GraphContext graphContext) {
76-
return GraphParsing.parse( name, entityDomainType, graphContext.attributeList(),
71+
return GraphParsing.visit( name, entityDomainType, graphContext.attributeList(),
7772
entityName -> resolve( entityName, entityDomainNameResolver ) );
7873
}
7974

hibernate-core/src/main/java/org/hibernate/graph/EntityGraphs.java

Lines changed: 40 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import java.util.Arrays;
88
import java.util.List;
99
import java.util.Map;
10-
import java.util.Set;
1110
import java.util.stream.Stream;
1211

1312
import jakarta.persistence.AttributeNode;
@@ -310,31 +309,10 @@ public static <T> boolean areEqual(EntityGraph<T> a, EntityGraph<T> b) {
310309
if ( a == b ) {
311310
return true;
312311
}
313-
if ( ( a == null ) || ( b == null ) ) {
314-
return false;
315-
}
316-
317-
final List<AttributeNode<?>> aNodes = a.getAttributeNodes();
318-
final List<AttributeNode<?>> bNodes = b.getAttributeNodes();
319-
320-
if ( aNodes.size() != bNodes.size() ) {
321-
return false;
322-
}
323-
for ( AttributeNode<?> aNode : aNodes ) {
324-
final String attributeName = aNode.getAttributeName();
325-
AttributeNode<?> bNode = null;
326-
for ( AttributeNode<?> bCandidate : bNodes ) {
327-
if ( attributeName.equals( bCandidate.getAttributeName() ) ) {
328-
bNode = bCandidate;
329-
break;
330-
}
331-
}
332-
if ( !areEqual( aNode, bNode ) ) {
333-
return false;
334-
}
312+
else {
313+
return a != null && b != null
314+
&& haveSameNodes( a, b );
335315
}
336-
337-
return true;
338316
}
339317

340318
/**
@@ -345,10 +323,10 @@ public static boolean areEqual(AttributeNode<?> a, AttributeNode<?> b) {
345323
if ( a == b ) {
346324
return true;
347325
}
348-
if ( ( a == null ) || ( b == null ) ) {
326+
else if ( a == null || b == null ) {
349327
return false;
350328
}
351-
if ( a.getAttributeName().equals( b.getAttributeName() ) ) {
329+
else if ( a.getAttributeName().equals( b.getAttributeName() ) ) {
352330
return areEqual( a.getSubgraphs(), b.getSubgraphs() )
353331
&& areEqual( a.getKeySubgraphs(), b.getKeySubgraphs() );
354332
}
@@ -367,71 +345,62 @@ public static boolean areEqual(
367345
if ( a == b ) {
368346
return true;
369347
}
370-
if ( ( a == null ) || ( b == null ) ) {
348+
else if ( a == null || b == null ) {
371349
return false;
372350
}
373-
374-
@SuppressWarnings("rawtypes")
375-
final Set<Class> aKeys = a.keySet();
376-
@SuppressWarnings("rawtypes")
377-
final Set<Class> bKeys = b.keySet();
378-
379-
if ( aKeys.equals( bKeys ) ) {
380-
for ( Class<?> clazz : aKeys ) {
381-
if ( !bKeys.contains( clazz ) ) {
382-
return false;
383-
}
384-
if ( !areEqual( a.get( clazz ), b.get( clazz ) ) ) {
385-
return false;
351+
else {
352+
final var aKeys = a.keySet();
353+
final var bKeys = b.keySet();
354+
if ( aKeys.equals( bKeys ) ) {
355+
for ( var key : aKeys ) {
356+
if ( !areEqual( a.get( key ), b.get( key ) ) ) {
357+
return false;
358+
}
386359
}
360+
return true;
361+
}
362+
else {
363+
return false;
387364
}
388-
return true;
389-
}
390-
else {
391-
return false;
392365
}
393366
}
394367

395368
/**
396369
* Compares two entity subgraphs and returns {@code true} if they are equal,
397370
* ignoring attribute order.
398371
*/
399-
public static boolean areEqual(
400-
@SuppressWarnings("rawtypes") Subgraph a,
401-
@SuppressWarnings("rawtypes") Subgraph b) {
372+
public static boolean areEqual(Subgraph<?> a, Subgraph<?> b) {
402373
if ( a == b ) {
403374
return true;
404375
}
405-
if ( ( a == null ) || ( b == null ) ) {
406-
return false;
407-
}
408-
if ( a.getClassType() != b.getClassType() ) {
409-
return false;
376+
else {
377+
return a != null && b != null
378+
&& a.getClassType() == b.getClassType()
379+
&& haveSameNodes( a, b );
410380
}
381+
}
411382

412-
@SuppressWarnings("unchecked")
413-
final List<AttributeNode<?>> aNodes = a.getAttributeNodes();
414-
@SuppressWarnings("unchecked")
415-
final List<AttributeNode<?>> bNodes = b.getAttributeNodes();
416-
383+
private static boolean haveSameNodes(Graph<?> a, Graph<?> b) {
384+
final var aNodes = a.getAttributeNodes();
385+
final var bNodes = b.getAttributeNodes();
417386
if ( aNodes.size() != bNodes.size() ) {
418387
return false;
419388
}
420-
421-
for ( AttributeNode<?> aNode : aNodes ) {
422-
final String attributeName = aNode.getAttributeName();
423-
AttributeNode<?> bNode = null;
424-
for ( AttributeNode<?> bCandidate : bNodes ) {
425-
if ( attributeName.equals( bCandidate.getAttributeName() ) ) {
426-
bNode = bCandidate;
427-
break;
389+
else {
390+
for ( var aNode : aNodes ) {
391+
final String attributeName = aNode.getAttributeName();
392+
AttributeNode<?> bNode = null;
393+
for ( var bCandidate : bNodes ) {
394+
if ( attributeName.equals( bCandidate.getAttributeName() ) ) {
395+
bNode = bCandidate;
396+
break;
397+
}
398+
}
399+
if ( !areEqual( aNode, bNode ) ) {
400+
return false;
428401
}
429402
}
430-
if ( !areEqual( aNode, bNode ) ) {
431-
return false;
432-
}
403+
return true;
433404
}
434-
435-
return true;
436405
}
437406
}

hibernate-core/src/main/java/org/hibernate/graph/GraphParser.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,15 @@
2828
* The {@link #parse} methods all create a root {@link jakarta.persistence.EntityGraph}
2929
* based on the passed entity class and parse the graph string into that root graph.
3030
* <p>
31-
* The {@link #parseInto} methods parse the graph string into a passed graph, which may be a subgraph
31+
* The {@link #parseInto} methods parse the graph string into a passed graph, which may
32+
* be a subgraph.
3233
* <p>
3334
* Multiple graphs for the same entity type can be
3435
* {@linkplain EntityGraphs#merge(EntityManager, Class, jakarta.persistence.Graph...)
3536
* merged}.
3637
*
3738
* @author asusnjar
3839
*/
39-
@SuppressWarnings("unused")
4040
public final class GraphParser {
4141

4242
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -135,8 +135,8 @@ public static <T> RootGraph<T> parse(
135135
}
136136

137137
/**
138-
* Creates a root graph based on the passed `rootType` and parses `graphText` into
139-
* the generated root graph
138+
* Creates a root graph based on the passed {@code rootType} and parses {@code graphText}
139+
* into the generated root graph.
140140
*
141141
* @apiNote The passed EntityManager is expected to be a Hibernate implementation.
142142
* Attempting to pass another provider's EntityManager implementation will fail.

hibernate-core/src/main/java/org/hibernate/graph/internal/parse/GraphParser.java

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@
1313
import org.hibernate.graph.spi.GraphParserEntityNameResolver;
1414
import org.hibernate.graph.spi.GraphImplementor;
1515
import org.hibernate.graph.spi.SubGraphImplementor;
16-
import org.hibernate.internal.util.StringHelper;
1716
import org.hibernate.internal.util.collections.Stack;
1817
import org.hibernate.internal.util.collections.StandardStack;
1918

2019
import static org.hibernate.graph.internal.GraphParserLogging.PARSING_LOGGER;
20+
import static org.hibernate.internal.util.StringHelper.repeat;
2121

2222
/**
2323
* Unified access to the Antlr parser for Hibernate's "graph language"
@@ -51,36 +51,12 @@ public Stack<GraphImplementor<?>> getGraphStack() {
5151

5252
@Override
5353
public AttributeNodeImplementor<?,?,?> visitAttributeNode(GraphLanguageParser.AttributeNodeContext attributeNodeContext) {
54-
final String attributeName = attributeNodeContext.attributePath().ATTR_NAME().getText();
54+
final var attributePathContext = attributeNodeContext.attributePath();
55+
final var attributeQualifierContext = attributePathContext.attributeQualifier();
5556

56-
final SubGraphGenerator subGraphCreator;
57+
final String attributeName = attributePathContext.ATTR_NAME().getText();
5758

58-
if ( attributeNodeContext.attributePath().attributeQualifier() == null ) {
59-
if ( PARSING_LOGGER.isTraceEnabled() ) {
60-
PARSING_LOGGER.tracef(
61-
"%s Start attribute : %s",
62-
StringHelper.repeat( ">>", attributeNodeStack.depth() + 1 ),
63-
attributeName
64-
);
65-
}
66-
67-
subGraphCreator = PathQualifierType.VALUE.getSubGraphCreator();
68-
}
69-
else {
70-
final String qualifierName = attributeNodeContext.attributePath().attributeQualifier().ATTR_NAME().getText();
71-
72-
if ( PARSING_LOGGER.isTraceEnabled() ) {
73-
PARSING_LOGGER.tracef(
74-
"%s Start qualified attribute : %s.%s",
75-
StringHelper.repeat( ">>", attributeNodeStack.depth() + 1 ),
76-
attributeName,
77-
qualifierName
78-
);
79-
}
80-
81-
final PathQualifierType pathQualifierType = resolvePathQualifier( qualifierName );
82-
subGraphCreator = pathQualifierType.getSubGraphCreator();
83-
}
59+
final var subGraphCreator = subGraphCreator( attributeQualifierContext, attributeName );
8460

8561
final var attributeNode = resolveAttributeNode( attributeName );
8662

@@ -101,14 +77,39 @@ public AttributeNodeImplementor<?,?,?> visitAttributeNode(GraphLanguageParser.At
10177
if ( PARSING_LOGGER.isTraceEnabled() ) {
10278
PARSING_LOGGER.tracef(
10379
"%s Finished attribute : %s",
104-
StringHelper.repeat( "<<", attributeNodeStack.depth() + 1 ),
80+
repeat( "<<", attributeNodeStack.depth() + 1 ),
10581
attributeName
10682
);
10783
}
10884

10985
return attributeNode;
11086
}
11187

88+
private SubGraphGenerator subGraphCreator(GraphLanguageParser.AttributeQualifierContext attributeQualifierContext, String attributeName) {
89+
if ( attributeQualifierContext == null ) {
90+
if ( PARSING_LOGGER.isTraceEnabled() ) {
91+
PARSING_LOGGER.tracef(
92+
"%s Start attribute : %s",
93+
repeat( ">>", attributeNodeStack.depth() + 1 ),
94+
attributeName
95+
);
96+
}
97+
return PathQualifierType.VALUE.getSubGraphCreator();
98+
}
99+
else {
100+
final String qualifierName = attributeQualifierContext.ATTR_NAME().getText();
101+
if ( PARSING_LOGGER.isTraceEnabled() ) {
102+
PARSING_LOGGER.tracef(
103+
"%s Start qualified attribute : %s.%s",
104+
repeat( ">>", attributeNodeStack.depth() + 1 ),
105+
attributeName,
106+
qualifierName
107+
);
108+
}
109+
return resolvePathQualifier( qualifierName ).getSubGraphCreator();
110+
}
111+
}
112+
112113
private AttributeNodeImplementor<?,?,?> resolveAttributeNode(String attributeName) {
113114
final var currentGraph = graphStack.getCurrent();
114115
assert currentGraph != null;
@@ -140,15 +141,15 @@ public SubGraphImplementor<?> visitSubGraph(GraphLanguageParser.SubGraphContext
140141
if ( PARSING_LOGGER.isTraceEnabled() ) {
141142
PARSING_LOGGER.tracef(
142143
"%s Starting graph: %s",
143-
StringHelper.repeat( ">>", attributeNodeStack.depth() + 2 ),
144+
repeat( ">>", attributeNodeStack.depth() + 2 ),
144145
subTypeName
145146
);
146147
}
147148

148149
final var attributeNode = attributeNodeStack.getCurrent();
149150
final var subGraphCreator = graphSourceStack.getCurrent();
150151

151-
final SubGraphImplementor<?> subGraph = subGraphCreator.createSubGraph(
152+
final var subGraph = subGraphCreator.createSubGraph(
152153
attributeNode,
153154
subTypeName,
154155
entityNameResolver
@@ -166,7 +167,7 @@ public SubGraphImplementor<?> visitSubGraph(GraphLanguageParser.SubGraphContext
166167
if ( PARSING_LOGGER.isTraceEnabled() ) {
167168
PARSING_LOGGER.tracef(
168169
"%s Finished graph : %s",
169-
StringHelper.repeat( "<<", attributeNodeStack.depth() + 2 ),
170+
repeat( "<<", attributeNodeStack.depth() + 2 ),
170171
subGraph.getGraphedType().getTypeName()
171172
);
172173
}

0 commit comments

Comments
 (0)