/*
* Hibernate OGM, Domain model persistence for NoSQL datastores
*
* 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.ogm.datastore.neo4j.remote.bolt.dialect.impl;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.hibernate.ogm.datastore.neo4j.BaseNeo4jDialect;
import org.hibernate.ogm.dialect.spi.TupleTypeContext;
import org.hibernate.ogm.model.key.spi.AssociatedEntityKeyMetadata;
import org.hibernate.ogm.model.key.spi.EntityKeyMetadata;
import org.hibernate.ogm.model.spi.TupleSnapshot;
import org.neo4j.driver.v1.types.Node;
/**
* Represents the Tuple snapshot as loaded by the Neo4j datastore.
* <p>
* The columns of the tuple are mapped as properties of the node.
*
* @author Davide D'Alto
*/
public final class BoltNeo4jTupleSnapshot implements TupleSnapshot {
private final Node node;
private final Map<String, AssociatedEntityKeyMetadata> associatedEntityKeyMetadata;
private final EntityKeyMetadata entityKeyMetadata;
private final Map<String, Node> toOneEntities;
private final Map<String, Collection<Node>> embeddedNodes;
private final Map<String, String> rolesByColumn;
public BoltNeo4jTupleSnapshot(
NodeWithEmbeddedNodes node,
EntityKeyMetadata entityKeyMetadata) {
this( node, entityKeyMetadata, Collections.<String, Node>emptyMap(), null );
}
public BoltNeo4jTupleSnapshot(
NodeWithEmbeddedNodes node,
EntityKeyMetadata metadata,
Map<String, Node> toOneEntities,
TupleTypeContext tupleTypeContext
) {
this.node = node.getOwner();
this.embeddedNodes = node.getEmbeddedNodes();
this.entityKeyMetadata = metadata;
this.toOneEntities = toOneEntities;
this.associatedEntityKeyMetadata = tupleTypeContext.getAllAssociatedEntityKeyMetadata();
this.rolesByColumn = tupleTypeContext.getAllRoles();
}
@Override
public Object get(String column) {
if ( associatedEntityKeyMetadata.containsKey( column ) ) {
return readPropertyOnOtherNode( column );
}
else if ( BaseNeo4jDialect.isPartOfRegularEmbedded( entityKeyMetadata.getColumnNames(), column ) ) {
return readEmbeddedProperty( column );
}
else {
return readProperty( node, column );
}
}
private Object readPropertyOnOtherNode(String column) {
String associationrole = rolesByColumn.get( column );
Node associatedEntity = toOneEntities.get( associationrole );
if ( associatedEntity == null ) {
return null;
}
return readProperty( associatedEntity, associatedEntityKeyMetadata.get( column ).getCorrespondingEntityKeyColumn( column ) );
}
private Object readEmbeddedProperty(String column) {
String embeddedPath = column.substring( 0, column.lastIndexOf( "." ) );
String property = column.substring( embeddedPath.length() + 1 );
if ( embeddedNodes.containsKey( embeddedPath ) ) {
Node embeddedNode = embeddedNodes.get( embeddedPath ).iterator().next();
return readProperty( embeddedNode, property );
}
return null;
}
private Object readProperty(Node node, String targetColumnName) {
if ( node.containsKey( targetColumnName ) ) {
return node.get( targetColumnName ).asObject();
}
return null;
}
@Override
public boolean isEmpty() {
return node.asMap().isEmpty();
}
@Override
public Set<String> getColumnNames() {
Set<String> names = new HashSet<String>();
for ( String string : node.keys() ) {
names.add( string );
}
return names;
}
public Node getNode() {
return node;
}
}