package org.neo4j.rdf.store.representation.standard; import org.neo4j.graphdb.RelationshipType; import org.neo4j.meta.model.MetaModel; import org.neo4j.rdf.model.Literal; import org.neo4j.rdf.model.Statement; import org.neo4j.rdf.store.representation.AbstractNode; import org.neo4j.rdf.store.representation.AbstractRelationship; import org.neo4j.rdf.store.representation.AbstractRepresentation; import org.neo4j.rdf.store.representation.RepresentationExecutor; /** * * Each statement: * Subject to a middle node, to an object node (or literal node) * The middle node has relationships to which contexts that statement is in. * * (S) ---[P]--> ( ) ---[P]--> (O) * / \ * / \ * [C] [C] * / \ * v v * (C1) (C2) * */ public class VerboseQuadStrategy extends StandardAbstractRepresentationStrategy { public static final String EXECUTOR_INFO_NODE_TYPE = "nodetype"; public static final String EXECUTOR_INFO_PREDICATE = "predicate"; public static final String TYPE_SUBJECT = "subject"; public static final String TYPE_MIDDLE = "middle"; public static final String TYPE_LITERAL = "literal"; public static final String TYPE_OBJECT = "object"; public static final String TYPE_CONTEXT = "context"; public static final String KEY_OBJECT_URI_ON_MIDDLE_NODE = "object_uri"; public VerboseQuadStrategy( RepresentationExecutor executor, MetaModel meta ) { super( executor, meta ); } @Override public VerboseQuadExecutor getExecutor() { return ( VerboseQuadExecutor ) super.getExecutor(); } @Override public AbstractRepresentation getAbstractRepresentation( Statement statement, AbstractRepresentation representation ) { if ( super.getAbstractRepresentation( statement, representation ) != null ) { return representation; } if ( objectIsObjectType( statement ) ) { getObjectTypeRepresentation( statement, representation ); } else { getLiteralRepresentation( statement, representation ); } return representation; } private String formMiddleNodeKey( Statement statement ) { return "M" + formTripleNodeKey( statement ); } protected AbstractRepresentation getLiteralRepresentation( Statement statement, AbstractRepresentation representation ) { AbstractNode subjectNode = getOrCreateNode( representation, statement.getSubject() ); subjectNode.addExecutorInfo( EXECUTOR_INFO_NODE_TYPE, TYPE_SUBJECT ); AbstractNode middleNode = getOrCreateNode( representation, null, formMiddleNodeKey( statement ) ); middleNode.addExecutorInfo( EXECUTOR_INFO_NODE_TYPE, TYPE_MIDDLE ); AbstractNode literalNode = getOrCreateNode( representation, null, formTripleNodeKey( statement ) ); literalNode.addExecutorInfo( EXECUTOR_INFO_NODE_TYPE, TYPE_LITERAL ); String predicate = asUri( statement.getPredicate() ); String valueKey = getExecutor().getLiteralNodePropertyKey( predicate ); if ( statement.getObject().isWildcard() ) { literalNode.addProperty( valueKey, statement.getObject() ); } else { Literal literal = ( Literal ) statement.getObject(); literalNode.addProperty( valueKey, literal.getValue() ); literalNode.addExecutorInfo( EXECUTOR_INFO_PREDICATE, predicate ); if ( literal.getDatatype() != null ) { literalNode.addProperty( VerboseQuadExecutor.LITERAL_DATATYPE_KEY, literal.getDatatype().getUriAsString() ); } if ( literal.getLanguage() != null ) { literalNode.addProperty( VerboseQuadExecutor.LITERAL_LANGUAGE_KEY, literal.getLanguage() ); } } connectThreeNodes( representation, subjectNode, middleNode, literalNode, statement ); connectMiddleNodeWithContext( representation, middleNode, statement ); return representation; } protected void connectThreeNodes( AbstractRepresentation representation, AbstractNode subjectNode, AbstractNode middleNode, AbstractNode otherNode, Statement statement ) { String predicate = asUri( statement.getPredicate() ); AbstractRelationship subjectToMiddle = new AbstractRelationship( subjectNode, predicate, middleNode ); representation.addRelationship( subjectToMiddle ); AbstractRelationship middleToOther = new AbstractRelationship( middleNode, predicate, otherNode ); representation.addRelationship( middleToOther ); } protected void connectMiddleNodeWithContext( AbstractRepresentation representation, AbstractNode middleNode, Statement statement ) { if ( !statement.getContext().isWildcard() ) { AbstractNode contextNode = getOrCreateNode( representation, statement.getContext() ); AbstractRelationship middleToContext = new AbstractRelationship( middleNode, RelTypes.IN_CONTEXT.name(), contextNode ); middleToContext.addExecutorInfo( EXECUTOR_INFO_NODE_TYPE, TYPE_CONTEXT ); representation.addRelationship( middleToContext ); contextNode.addExecutorInfo( EXECUTOR_INFO_NODE_TYPE, TYPE_CONTEXT ); } } protected AbstractRepresentation getObjectTypeRepresentation( Statement statement, AbstractRepresentation representation ) { AbstractNode subjectNode = getOrCreateNode( representation, statement.getSubject() ); subjectNode.addExecutorInfo( EXECUTOR_INFO_NODE_TYPE, TYPE_SUBJECT ); AbstractNode middleNode = getOrCreateNode( representation, null, formMiddleNodeKey( statement ) ); middleNode.addExecutorInfo( EXECUTOR_INFO_NODE_TYPE, TYPE_MIDDLE ); AbstractNode objectNode = getOrCreateNode( representation, statement.getObject() ); objectNode.addExecutorInfo( EXECUTOR_INFO_NODE_TYPE, TYPE_OBJECT ); connectThreeNodes( representation, subjectNode, middleNode, objectNode, statement ); connectMiddleNodeWithContext( representation, middleNode, statement ); return representation; } public static enum RelTypes implements RelationshipType { IN_CONTEXT, } }