org.hibernate.graph.internal.AttributeNodeImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of hibernate-core Show documentation
Show all versions of hibernate-core Show documentation
JPMS Module-Info's for a few of the Jakarta Libraries just until they add them in themselves
/*
* 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.graph.internal;
import java.util.Collections;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.graph.CannotContainSubGraphException;
import org.hibernate.graph.SubGraph;
import org.hibernate.graph.spi.AttributeNodeImplementor;
import org.hibernate.graph.spi.SubGraphImplementor;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.metamodel.model.domain.spi.PersistentAttributeDescriptor;
import org.hibernate.metamodel.model.domain.spi.ManagedTypeDescriptor;
import org.hibernate.metamodel.model.domain.spi.SimpleTypeDescriptor;
import org.jboss.logging.Logger;
/**
* Hibernate implementation of the JPA AttributeNode contract
*
* @author Steve Ebersole
*/
public class AttributeNodeImpl
extends AbstractGraphNode
implements AttributeNodeImplementor {
private final PersistentAttributeDescriptor, J> attribute;
private Map, SubGraphImplementor extends J>> subGraphMap;
private Map, SubGraphImplementor extends J>> keySubGraphMap;
@SuppressWarnings("WeakerAccess")
public AttributeNodeImpl(
boolean mutable,
PersistentAttributeDescriptor attribute,
SessionFactoryImplementor sessionFactory) {
this( mutable, attribute, null, null, sessionFactory );
}
/**
* Intended only for use from making a copy
*/
private AttributeNodeImpl(
boolean mutable,
PersistentAttributeDescriptor, J> attribute,
Map, SubGraphImplementor extends J>> subGraphMap,
Map, SubGraphImplementor extends J>> keySubGraphMap,
SessionFactoryImplementor sessionFactory) {
super( mutable, sessionFactory );
this.attribute = attribute;
this.subGraphMap = subGraphMap;
this.keySubGraphMap = keySubGraphMap;
}
@Override
public String getAttributeName() {
return getAttributeDescriptor().getName();
}
@Override
public PersistentAttributeDescriptor, J> getAttributeDescriptor() {
return attribute;
}
@Override
@SuppressWarnings("unchecked")
public Map, SubGraphImplementor extends J>> getSubGraphMap() {
if ( subGraphMap == null ) {
return Collections.emptyMap();
}
else {
return (Map) subGraphMap;
}
}
@Override
@SuppressWarnings("unchecked")
public Map, SubGraphImplementor extends J>> getKeySubGraphMap() {
if ( keySubGraphMap == null ) {
return Collections.emptyMap();
}
else {
return keySubGraphMap;
}
}
@Override
public SubGraphImplementor makeSubGraph() {
return internalMakeSubgraph( (Class) null );
}
@Override
public SubGraphImplementor makeSubGraph(Class subtype) {
return internalMakeSubgraph( subtype );
}
@Override
public SubGraphImplementor makeSubGraph(ManagedTypeDescriptor subtype) {
return internalMakeSubgraph( subtype );
}
private SubGraphImplementor internalMakeSubgraph(ManagedTypeDescriptor type) {
assert type != null;
log.debugf( "Making sub-graph : ( (%s) %s )", type.getName(), getAttributeName() );
final SubGraphImplementor subGraph = type.makeSubGraph();
internalAddSubGraph( type.getJavaType(), subGraph );
return subGraph;
}
@SuppressWarnings("unchecked")
private ManagedTypeDescriptor valueGraphTypeAsManaged() {
final SimpleTypeDescriptor valueGraphType = (SimpleTypeDescriptor) getAttributeDescriptor().getValueGraphType();
if ( valueGraphType instanceof ManagedTypeDescriptor ) {
return (ManagedTypeDescriptor) valueGraphType;
}
throw new CannotContainSubGraphException(
String.format(
Locale.ROOT,
"Attribute [%s] (%s) cannot contain value sub-graphs",
getAttributeName(),
getAttributeDescriptor().getPersistentAttributeType().name()
)
);
}
private static final Logger log = Logger.getLogger( AttributeNodeImpl.class );
@SuppressWarnings("unchecked")
private SubGraphImplementor internalMakeSubgraph(Class subType) {
verifyMutability();
final ManagedTypeDescriptor managedType = valueGraphTypeAsManaged();
if ( subType == null ) {
subType = managedType.getJavaType();
}
return internalMakeSubgraph( managedType.findSubType( subType ) );
}
@SuppressWarnings({"WeakerAccess", "unchecked"})
protected void internalAddSubGraph(Class subType, SubGraphImplementor subGraph) {
log.tracef( "Adding sub-graph : ( (%s) %s )", subGraph.getGraphedType().getName(), getAttributeName() );
if ( subGraphMap == null ) {
subGraphMap = new HashMap<>();
}
final SubGraphImplementor extends J> previous = subGraphMap.put( subType, (SubGraphImplementor) subGraph );
if ( previous != null ) {
log.debugf( "Adding sub-graph [%s] over-wrote existing [%s]", subGraph, previous );
}
}
@Override
@SuppressWarnings("unchecked")
public void addSubGraph(Class subType, SubGraph subGraph) {
verifyMutability();
internalAddSubGraph( subType, (SubGraphImplementor) subGraph );
}
@Override
public SubGraphImplementor makeKeySubGraph() {
return internalMakeKeySubgraph( (Class) null );
}
@Override
public SubGraphImplementor makeKeySubGraph(Class subtype) {
return internalMakeKeySubgraph( subtype );
}
@Override
public SubGraphImplementor makeKeySubGraph(ManagedTypeDescriptor subtype) {
return internalMakeKeySubgraph( subtype );
}
private SubGraphImplementor internalMakeKeySubgraph(ManagedTypeDescriptor type) {
log.debugf( "Making key sub-graph : ( (%s) %s )", type.getName(), getAttributeName() );
final SubGraphImplementor subGraph = type.makeSubGraph();
internalAddKeySubGraph( type.getJavaType(), subGraph );
return subGraph;
}
@SuppressWarnings("unchecked")
private SubGraphImplementor internalMakeKeySubgraph(Class type) {
verifyMutability();
final ManagedTypeDescriptor managedType = keyGraphTypeAsManaged();
final ManagedTypeDescriptor subType;
if ( type == null ) {
subType = managedType;
}
else {
subType = managedType.findSubType( type );
}
subType.getJavaType();
return internalMakeKeySubgraph( subType );
}
@SuppressWarnings({"WeakerAccess", "unchecked"})
protected void internalAddKeySubGraph(Class subType, SubGraph subGraph) {
log.tracef( "Adding key sub-graph : ( (%s) %s )", subType.getName(), getAttributeName() );
if ( keySubGraphMap == null ) {
keySubGraphMap = new HashMap<>();
}
final SubGraphImplementor extends J> previous = keySubGraphMap.put( subType, (SubGraphImplementor) subGraph );
if ( previous != null ) {
log.debugf( "Adding key sub-graph [%s] over-wrote existing [%]", subGraph, previous );
}
}
@SuppressWarnings("unchecked")
private ManagedTypeDescriptor keyGraphTypeAsManaged() {
final SimpleTypeDescriptor keyGraphType = (SimpleTypeDescriptor) getAttributeDescriptor().getKeyGraphType();
if ( keyGraphType instanceof ManagedTypeDescriptor ) {
return (ManagedTypeDescriptor) keyGraphType;
}
throw new CannotContainSubGraphException(
String.format(
Locale.ROOT,
"Attribute [%s#%s] (%s) cannot contain key sub-graphs - %s",
getAttributeDescriptor().getDeclaringType().getName(),
getAttributeName(),
getAttributeDescriptor().getPersistentAttributeType().name(),
keyGraphType
)
);
}
@Override
@SuppressWarnings("unchecked")
public void addKeySubGraph(Class subType, SubGraph subGraph) {
internalAddKeySubGraph( subType, subGraph );
}
@Override
@SuppressWarnings("unchecked")
public AttributeNodeImplementor makeCopy(boolean mutable) {
return new AttributeNodeImpl<>(
mutable,
this.attribute,
makeMapCopy( mutable, (Map) subGraphMap ),
makeMapCopy( mutable, (Map) keySubGraphMap ),
sessionFactory()
);
}
private Map, SubGraphImplementor> makeMapCopy(
boolean mutable,
Map, SubGraphImplementor> nodeMap) {
if ( nodeMap == null ) {
return null;
}
return CollectionHelper.makeCopy(
nodeMap,
type -> type,
subGraph -> subGraph.makeCopy( mutable )
);
}
@Override
@SuppressWarnings("unchecked")
public void merge(AttributeNodeImplementor> attributeNode) {
attributeNode.visitSubGraphs(
(incomingSubType, incomingGraph) -> {
SubGraphImplementor existing = null;
if ( subGraphMap == null ) {
subGraphMap = new HashMap<>();
}
else {
existing = subGraphMap.get( incomingSubType );
}
if ( existing != null ) {
existing.merge( incomingGraph );
}
else {
internalAddSubGraph( (Class) incomingSubType, (SubGraphImplementor) incomingGraph.makeCopy( true ) );
}
}
);
attributeNode.visitKeySubGraphs(
(incomingSubType, incomingGraph) -> {
SubGraphImplementor existing = null;
if ( keySubGraphMap == null ) {
keySubGraphMap = new HashMap<>();
}
else {
existing = keySubGraphMap.get( incomingSubType );
}
if ( existing != null ) {
existing.merge( incomingGraph );
}
else {
internalAddKeySubGraph( (Class) incomingSubType, (SubGraphImplementor) incomingGraph.makeCopy( true ) );
}
}
);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy