/*
* 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.test.dsl;
import static org.hibernate.ogm.datastore.neo4j.query.parsing.cypherdsl.impl.CypherDSL.escapeIdentifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* A DSL to define a chain of relationships like the following:
* <p>
* <pre>
* () -> [r1:type1 {property: {r1}.property}] -> () -[r2:type2]-> ()
* </pre>
*
* @author Davide D'Alto
*/
public class RelationshipsChainForGraphAssertions {
private final NodeForGraphAssertions start;
private final List<NextRelationship> stream = new ArrayList<NextRelationship>();
private final Map<String, Object> params = new HashMap<String, Object>();
public RelationshipsChainForGraphAssertions(NodeForGraphAssertions start, NodeForGraphAssertions end, String relationshipType) {
this.start = start;
this.params.put( start.getAlias(), start.getProperties() );
addToStream( end, relationshipType );
}
private void addToStream(NodeForGraphAssertions end, String relationshipType) {
stream.add( new NextRelationship( end, relationshipType, "r" + stream.size() ) );
params.put( end.getAlias(), end.getProperties() );
}
public RelationshipsChainForGraphAssertions relationshipTo(NodeForGraphAssertions next, String relationshipType) {
addToStream( next, relationshipType );
return this;
}
/**
* Get the starting node of the current chain of relationships.
*/
public NodeForGraphAssertions getStart() {
return start;
}
/**
* The map with the values for the parameters in the cypher representation of the current chain.
*/
public Map<String, Object> getParams() {
return params;
}
/**
* The number of relationships in the chain.
*/
public int getSize() {
return stream.size();
}
/**
* Define a property on the last relationship of the chain.
*/
public RelationshipsChainForGraphAssertions property(String name, Object value) {
NextRelationship relationship = stream.get( stream.size() - 1 );
@SuppressWarnings("unchecked")
Map<String, Object> properties = (Map<String, Object>) params.get( relationship.getAlias() );
if ( properties == null ) {
params.put( relationship.getAlias(), relationship.getProperties() );
}
relationship.addProperty( name, value );
return this;
}
/**
* Returns the cypher representation of the chain of relationships,
* <p>
* Example:
* <pre>
* (n1:ENTITY {id: {n1}.id}) -[r0:type0 {property: {r0}.property}]-> (n2:EMBEDDED {property: {n2}.property}) -[r1:type1]-> (n3:EMBEDDED)
* <pre>
*/
public String toCypher() {
StringBuilder builder = new StringBuilder();
builder.append( start.toCypher() );
for ( NextRelationship relationship : stream ) {
builder.append( " -[" );
if ( !relationship.getProperties().isEmpty() ) {
builder.append( relationship.getAlias() );
}
builder.append( ":" );
builder.append( relationship.getRelationshipType() );
if ( !relationship.getProperties().isEmpty() ) {
builder.append( " {" );
boolean first = true;
for ( String property : relationship.getProperties().keySet() ) {
if ( first ) {
first = false;
}
else {
builder.append( ", " );
}
escapeIdentifier( builder, property );
builder.append( ": {" );
builder.append( relationship.getAlias() );
builder.append( "}." );
escapeIdentifier( builder, property );
}
builder.append( " }" );
}
builder.append( "]-> " );
builder.append( relationship.getEnd().toCypher() );
}
return builder.toString();
}
private static class NextRelationship {
private final NodeForGraphAssertions end;
private final String relationshipType;
private final Map<String, Object> properties = new HashMap<String, Object>();
private final String alias;
public NextRelationship(NodeForGraphAssertions to, String relationshipType, String alias) {
this.end = to;
this.relationshipType = relationshipType;
this.alias = alias;
}
public String getAlias() {
return alias;
}
public Map<String, Object> getProperties() {
return properties;
}
public NodeForGraphAssertions getEnd() {
return end;
}
public String getRelationshipType() {
return relationshipType;
}
public void addProperty( String name, Object value ) {
properties.put( name, value );
}
}
}