Skip to content

Commit

Permalink
HHH-17460 - Ongoing JPA 32 work
Browse files Browse the repository at this point in the history
  • Loading branch information
sebersole committed Mar 28, 2024
1 parent dd004e8 commit 321bde9
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 129 deletions.
@@ -0,0 +1,177 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html.
*/
package org.hibernate.boot.models.xml.internal;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbNamedAttributeNodeImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbNamedEntityGraphImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbNamedSubgraphImpl;
import org.hibernate.boot.models.JpaAnnotations;
import org.hibernate.boot.models.xml.spi.XmlDocumentContext;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.models.spi.AnnotationUsage;
import org.hibernate.models.spi.ClassDetails;
import org.hibernate.models.spi.MutableAnnotationUsage;
import org.hibernate.models.spi.MutableClassDetails;
import org.hibernate.models.spi.SourceModelBuildingContext;

import jakarta.persistence.NamedAttributeNode;
import jakarta.persistence.NamedEntityGraph;
import jakarta.persistence.NamedEntityGraphs;
import jakarta.persistence.NamedSubgraph;

import static org.hibernate.boot.models.JpaAnnotations.NAMED_ATTRIBUTE_NODE;
import static org.hibernate.boot.models.internal.AnnotationUsageHelper.applyStringAttributeIfSpecified;
import static org.hibernate.boot.models.xml.internal.XmlProcessingHelper.applyAttributeIfSpecified;
import static org.hibernate.internal.util.collections.CollectionHelper.arrayList;

/**
* Processing for JPA entity graphs from XML
*
* @author Steve Ebersole
*/
public class EntityGraphProcessing {
public static void applyEntityGraphs(
JaxbEntityImpl jaxbEntity,
MutableClassDetails classDetails,
XmlDocumentContext xmlDocumentContext) {
final List<JaxbNamedEntityGraphImpl> jaxbEntityGraphs = jaxbEntity.getNamedEntityGraphs();
if ( CollectionHelper.isEmpty( jaxbEntityGraphs ) ) {
return;
}

final SourceModelBuildingContext modelBuildingContext = xmlDocumentContext.getModelBuildingContext();
final MutableAnnotationUsage<NamedEntityGraphs> entityGraphsUsage = JpaAnnotations.NAMED_ENTITY_GRAPHS.createUsage(
classDetails,
modelBuildingContext
);
classDetails.addAnnotationUsage( entityGraphsUsage );

final ArrayList<Object> entityGraphList = arrayList( jaxbEntityGraphs.size() );
entityGraphsUsage.setAttributeValue( "value", entityGraphList );

for ( JaxbNamedEntityGraphImpl namedEntityGraph : jaxbEntityGraphs ) {
final AnnotationUsage<NamedEntityGraph> graphUsage = extractGraph( namedEntityGraph, classDetails, modelBuildingContext, xmlDocumentContext );
entityGraphList.add( graphUsage );
}
}

private static AnnotationUsage<NamedEntityGraph> extractGraph(
JaxbNamedEntityGraphImpl jaxbEntityGraph,
ClassDetails classDetails,
SourceModelBuildingContext modelBuildingContext,
XmlDocumentContext xmlDocumentContext) {
final MutableAnnotationUsage<NamedEntityGraph> graphUsage = JpaAnnotations.NAMED_ENTITY_GRAPH.createUsage(
classDetails,
modelBuildingContext
);

applyStringAttributeIfSpecified( "name", jaxbEntityGraph.getName(), graphUsage );
applyAttributeIfSpecified( "includeAllAttributes", jaxbEntityGraph.isIncludeAllAttributes(), graphUsage );

if ( CollectionHelper.isNotEmpty( jaxbEntityGraph.getNamedAttributeNode() ) ) {
final List<MutableAnnotationUsage<NamedAttributeNode>> attributeNodeList = extractAttributeNodes(
jaxbEntityGraph.getNamedAttributeNode(),
classDetails,
modelBuildingContext,
xmlDocumentContext
);
graphUsage.setAttributeValue( "attributeNodes", attributeNodeList );
}

if ( CollectionHelper.isNotEmpty( jaxbEntityGraph.getSubgraph() ) ) {
final List<MutableAnnotationUsage<NamedSubgraph>> subgraphList = extractSubgraphNodes(
jaxbEntityGraph.getSubgraph(),
classDetails,
modelBuildingContext,
xmlDocumentContext
);
graphUsage.setAttributeValue( "subgraphs", subgraphList );
}

if ( CollectionHelper.isNotEmpty( jaxbEntityGraph.getSubclassSubgraph() ) ) {
final List<MutableAnnotationUsage<NamedSubgraph>> subgraphList = extractSubgraphNodes(
jaxbEntityGraph.getSubclassSubgraph(),
classDetails,
modelBuildingContext,
xmlDocumentContext
);
graphUsage.setAttributeValue( "subclassSubgraphs", subgraphList );
}

return graphUsage;
}

private static List<MutableAnnotationUsage<NamedAttributeNode>> extractAttributeNodes(
List<JaxbNamedAttributeNodeImpl> jaxbAttributeNodes,
ClassDetails classDetails,
SourceModelBuildingContext modelBuildingContext,
XmlDocumentContext xmlDocumentContext) {
assert CollectionHelper.isNotEmpty( jaxbAttributeNodes );

final ArrayList<MutableAnnotationUsage<NamedAttributeNode>> attributeNodeList = arrayList( jaxbAttributeNodes.size() );
for ( JaxbNamedAttributeNodeImpl jaxbAttributeNode : jaxbAttributeNodes ) {
final MutableAnnotationUsage<NamedAttributeNode> namedAttributeNodeAnn = NAMED_ATTRIBUTE_NODE.createUsage(
classDetails,
modelBuildingContext
);
attributeNodeList.add( namedAttributeNodeAnn );

namedAttributeNodeAnn.setAttributeValue( "value", jaxbAttributeNode.getName() );
applyStringAttributeIfSpecified( "subgraph", jaxbAttributeNode.getSubgraph(), namedAttributeNodeAnn );
applyStringAttributeIfSpecified( "keySubgraph", jaxbAttributeNode.getKeySubgraph(), namedAttributeNodeAnn );
}

return attributeNodeList;
}

private static List<MutableAnnotationUsage<NamedSubgraph>> extractSubgraphNodes(
List<JaxbNamedSubgraphImpl> jaxbSubgraphs,
ClassDetails classDetails,
SourceModelBuildingContext modelBuildingContext,
XmlDocumentContext xmlDocumentContext) {
assert CollectionHelper.isNotEmpty( jaxbSubgraphs );

final List<MutableAnnotationUsage<NamedSubgraph>> subgraphAnnotations = arrayList( jaxbSubgraphs.size() );
for ( JaxbNamedSubgraphImpl jaxbSubgraph : jaxbSubgraphs ) {
final MutableAnnotationUsage<NamedSubgraph> namedSubGraphUsage = JpaAnnotations.NAMED_SUB_GRAPH.createUsage(
classDetails,
modelBuildingContext
);
subgraphAnnotations.add( namedSubGraphUsage );

namedSubGraphUsage.setAttributeValue( "name", jaxbSubgraph.getName() );

final ClassDetails typeDetails;
if ( jaxbSubgraph.getClazz() == null ) {
typeDetails = ClassDetails.VOID_CLASS_DETAILS;
}
else {
typeDetails = xmlDocumentContext.resolveJavaType( jaxbSubgraph.getClazz() );
}
namedSubGraphUsage.setAttributeValue( "type", typeDetails );

if ( CollectionHelper.isNotEmpty( jaxbSubgraph.getNamedAttributeNode() ) ) {
namedSubGraphUsage.setAttributeValue(
"attributeNodes",
extractAttributeNodes(
jaxbSubgraph.getNamedAttributeNode(),
classDetails,
modelBuildingContext,
xmlDocumentContext
)
);
}
}

return subgraphAnnotations;
}

}
Expand Up @@ -526,10 +526,7 @@ private static void processEntityMetadata(

applyTenantId( classDetails, jaxbEntity, classAccessType, xmlDocumentContext );

final List<JaxbNamedEntityGraphImpl> namedEntityGraphs = jaxbEntity.getNamedEntityGraphs();
for ( JaxbNamedEntityGraphImpl namedEntityGraph : namedEntityGraphs ) {
XmlAnnotationHelper.applyNamedEntityGraph( namedEntityGraph, classDetails, xmlDocumentContext );
}
EntityGraphProcessing.applyEntityGraphs( jaxbEntity, classDetails, xmlDocumentContext );

XmlAnnotationHelper.applyDiscriminatorValue(
jaxbEntity.getDiscriminatorValue(),
Expand All @@ -548,7 +545,6 @@ private static void processEntityMetadata(
classDetails,
xmlDocumentContext
);
// todo : secondary-tables
}

private static void applyAccessAnnotation(
Expand Down
Expand Up @@ -54,6 +54,8 @@
import static org.hibernate.internal.util.StringHelper.isNotEmpty;

/**
* Processing of queries from XML
*
* @author Steve Ebersole
*/
public class QueryProcessing {
Expand Down
Expand Up @@ -1491,130 +1491,6 @@ private static String prefixIfNotAlready(String value, String prefix) {
return value;
}

static void applyNamedEntityGraph(
JaxbNamedEntityGraphImpl namedEntityGraph,
MutableClassDetails target,
XmlDocumentContext xmlDocumentContext) {
if ( namedEntityGraph != null ) {
final MutableAnnotationUsage<NamedEntityGraph> namedEntityGraphAnn = XmlProcessingHelper.getOrMakeAnnotation(
NamedEntityGraph.class,
target,
xmlDocumentContext
);

final AnnotationDescriptor<NamedEntityGraph> namedEntityGraphAnnotationDescriptor = namedEntityGraphAnn.getAnnotationDescriptor();
XmlProcessingHelper.applyAttributeIfSpecified( "name", namedEntityGraph.getName(), namedEntityGraphAnn );
XmlProcessingHelper.applyAttributeIfSpecified( "includeAllAttributes", namedEntityGraph.isIncludeAllAttributes(), namedEntityGraphAnn );

namedEntityGraphAnn.setAttributeValue(
"attributeNodes",
makeNamedAttributeNodes( namedEntityGraph.getNamedAttributeNode(), target, xmlDocumentContext )
);

namedEntityGraphAnn.setAttributeValue(
"subgraphs",
makeNamedSubgraphs(
target,
xmlDocumentContext,
namedEntityGraph.getSubgraph()
)
);

namedEntityGraphAnn.setAttributeValue(
"subclassSubgraphs",
makeNamedSubgraphs(
target,
xmlDocumentContext,
namedEntityGraph.getSubclassSubgraph()
)
);

}

}

private static List<MutableAnnotationUsage<NamedSubgraph>> makeNamedSubgraphs(
MutableClassDetails target,
XmlDocumentContext xmlDocumentContext,
List<JaxbNamedSubgraphImpl> subclassSubgraphNodes) {
final List<MutableAnnotationUsage<NamedSubgraph>> subgraphAnnotations =
new ArrayList<>( subclassSubgraphNodes.size() );
for ( JaxbNamedSubgraphImpl subclassSubgraphNode : subclassSubgraphNodes ) {
final String subGraphsNodeName = subclassSubgraphNode.getName();
final MutableAnnotationUsage<NamedSubgraph> namedSubgraphNodeAnn = XmlProcessingHelper.getOrMakeNamedAnnotation(
NamedSubgraph.class,
subGraphsNodeName,
target,
xmlDocumentContext
);
XmlProcessingHelper.applyAttributeIfSpecified( "name", subGraphsNodeName, namedSubgraphNodeAnn );

final String clazz = subclassSubgraphNode.getClazz();
if ( clazz == null ) {
namedSubgraphNodeAnn.setAttributeValue(
"type",
resolveJavaType(
namedSubgraphNodeAnn.getAnnotationDescriptor()
.getAttribute( "type" )
.getAttributeMethod()
.getDefaultValue().toString(),
xmlDocumentContext
)
);
}
else {
namedSubgraphNodeAnn.setAttributeValue(
"type",
resolveJavaType( subclassSubgraphNode.getClazz(), xmlDocumentContext )

);
}
namedSubgraphNodeAnn.setAttributeValue(
"attributeNodes",
makeNamedAttributeNodes( subclassSubgraphNode.getNamedAttributeNode(), target, xmlDocumentContext )
);

subgraphAnnotations.add( namedSubgraphNodeAnn );
}
return subgraphAnnotations;
}

private static List<MutableAnnotationUsage<NamedAttributeNode>> makeNamedAttributeNodes(
List<JaxbNamedAttributeNodeImpl> namedAttributeNodes,
MutableClassDetails target,
XmlDocumentContext xmlDocumentContext) {
final List<MutableAnnotationUsage<NamedAttributeNode>> namedAttributeNodeAnnotations =
new ArrayList<>( namedAttributeNodes.size() );
for ( JaxbNamedAttributeNodeImpl namedAttributeNode : namedAttributeNodes ) {
final MutableAnnotationUsage<NamedAttributeNode> namedAttributeNodeAnn = NAMED_ATTRIBUTE_NODE.createUsage(
target,
xmlDocumentContext.getModelBuildingContext()
);
XmlProcessingHelper.applyAttributeIfSpecified( "value", namedAttributeNode.getName(), namedAttributeNodeAnn );
final AnnotationDescriptor<NamedAttributeNode> namedAttributeNodeDescriptor = xmlDocumentContext
.getModelBuildingContext()
.getAnnotationDescriptorRegistry()
.getDescriptor( NamedAttributeNode.class );
applyOr(
namedAttributeNode,
JaxbNamedAttributeNodeImpl::getSubgraph,
"subgraph",
namedAttributeNodeAnn,
namedAttributeNodeDescriptor
);
applyOr(
namedAttributeNode,
JaxbNamedAttributeNodeImpl::getKeySubgraph,
"keySubgraph",
namedAttributeNodeAnn,
namedAttributeNodeDescriptor
);
namedAttributeNodeAnnotations.add( namedAttributeNodeAnn );

}
return namedAttributeNodeAnnotations;
}

static void applyDiscriminatorValue(
String discriminatorValue,
MutableClassDetails target,
Expand Down

0 comments on commit 321bde9

Please sign in to comment.