/* * 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.common.dialect.impl; import static org.hibernate.ogm.util.impl.EmbeddedHelper.isPartOfEmbedded; import java.util.HashMap; import java.util.Map; import java.util.Set; import org.hibernate.ogm.model.key.spi.AssociatedEntityKeyMetadata; import org.hibernate.ogm.model.key.spi.AssociationKey; import org.hibernate.ogm.model.spi.TupleSnapshot; /** * A {@link TupleSnapshot} of the row in an association for remote Neo4j dialects. * * @author Davide D'Alto */ public class RemoteNeo4jTupleAssociationSnapshot implements TupleSnapshot { private final Map<String, Object> properties; public RemoteNeo4jTupleAssociationSnapshot(RemoteNeo4jAssociationPropertiesRow row, AssociationKey associationKey, AssociatedEntityKeyMetadata associatedEntityKeyMetadata) { this.properties = collectProperties( row, associationKey, associatedEntityKeyMetadata ); } @Override public Object get(String column) { return properties.get( column ); } @Override public boolean isEmpty() { return properties.isEmpty(); } @Override public Set<String> getColumnNames() { return properties.keySet(); } private static Map<String, Object> collectProperties(RemoteNeo4jAssociationPropertiesRow row, AssociationKey associationKey, AssociatedEntityKeyMetadata associatedEntityKeyMetadata) { Map<String, Object> properties = new HashMap<String, Object>(); String[] rowKeyColumnNames = associationKey.getMetadata().getRowKeyColumnNames(); Map<String, Object> relationship = row.getRelationship(); Map<String, Object> ownerNode = row.getOwnerNode(); Map<String, Object> targetNode = row.getTargetNode(); // Index columns for ( int i = 0; i < rowKeyColumnNames.length; i++ ) { if ( relationship.containsKey( rowKeyColumnNames[i] ) ) { properties.put( rowKeyColumnNames[i], relationship.get( rowKeyColumnNames[i] ) ); } } // Properties stored in the target side of the association for ( String associationColumn : associatedEntityKeyMetadata.getAssociationKeyColumns() ) { String targetColumnName = associatedEntityKeyMetadata.getCorrespondingEntityKeyColumn( associationColumn ); if ( isPartOfEmbedded( targetColumnName ) ) { fetchEmbeddedProperties( associationKey, properties, targetNode, associationColumn, targetColumnName ); } else { if ( targetNode.containsKey( targetColumnName ) ) { properties.put( associationColumn, targetNode.get( targetColumnName ) ); } } } // Property stored in the owner side of the association for ( int i = 0; i < associationKey.getColumnNames().length; i++ ) { String key = associationKey.getEntityKey().getColumnNames()[i]; if ( ownerNode.containsKey( key ) ) { properties.put( associationKey.getColumnNames()[i], ownerNode.get( key ) ); } } return properties; } private static void fetchEmbeddedProperties(AssociationKey associationKey, Map<String, Object> properties, Map<String, Object> targetNode, String associationColumn, String targetColumnName) { // Embedded column String collectionRole = associationKey.getMetadata().getCollectionRole(); if ( targetColumnName.equals( collectionRole ) ) { // Ex: @ElementCollection List<String> examples targetColumnName = targetColumnName.substring( targetColumnName.lastIndexOf( "." ) + 1 ); if ( targetNode.containsKey( targetColumnName ) ) { properties.put( associationColumn, targetNode.get( targetColumnName ) ); } } if ( targetColumnName.startsWith( collectionRole ) ) { // Ex: @ElementCollection Map<String, Embedded> examples targetColumnName = targetColumnName.substring( collectionRole.length() + 1 ); if ( targetNode.containsKey( targetColumnName ) ) { properties.put( associationColumn, targetNode.get( targetColumnName ) ); } } else if ( targetNode.containsKey( targetColumnName ) ) { // Embedded id properties.put( associationColumn, targetNode.get( targetColumnName ) ); } else { // Ex: @ElementCollection List<Embedded> examples if ( targetNode.containsKey( targetColumnName ) ) { properties.put( associationColumn, targetNode.get( targetColumnName ) ); } } } }