package er.neo4jadaptor.query.neo4j_eval.retrievers;
import java.util.Iterator;
import org.neo4j.graphdb.Direction;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.PropertyContainer;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.RelationshipType;
import com.webobjects.eoaccess.EOAttribute;
import com.webobjects.eoaccess.EORelationship;
import com.webobjects.foundation.NSArray;
import er.neo4jadaptor.ersatz.neo4j.Neo4JUtils;
import er.neo4jadaptor.query.neo4j_eval.Cost;
import er.neo4jadaptor.utils.EOUtilities;
import er.neo4jadaptor.utils.iteration.Iterators;
/**
* Simulates getting foreign key value. Actually we don't store foreign key values in Neo4J so instead
* we traverse relationship and return destination ID.
*
* @author Jedrzej Sobanski
*
*/
public class ForeignKeyValue implements Retriever<PropertyContainer, Number> {
private final RelationshipType relationshipType;
private final EOAttribute srcAttribute;
public ForeignKeyValue(EORelationship rel) {
relationshipType = Neo4JUtils.getRelationshipType(rel);
NSArray<EOAttribute> srcAtts = rel.sourceAttributes();
if (srcAtts.count() != 1) {
throw new IllegalArgumentException();
}
srcAttribute = srcAtts.get(0);
}
private Iterator<Number> retrieveFromProperties(PropertyContainer container) {
Number n = (Number) container.getProperty(srcAttribute.name(), null);
if (n != null) {
return Iterators.singleton(n);
} else {
return Iterators.empty();
}
}
private Iterator<Number> retrieveFromNodeRelationships(Node node) {
Relationship r = node.getSingleRelationship(relationshipType, Direction.OUTGOING);
if (r != null) {
Long id = r.getEndNode().getId();
Number ret = EOUtilities.convertToAttributeType(srcAttribute, id);
return Iterators.singleton(ret);
} else {
return Iterators.empty();
}
}
public Cost getCost() {
return Cost.RELATIONSHIPS;
}
public Iterator<Number> retrieve(PropertyContainer container) {
if (container instanceof Relationship) {
return retrieveFromProperties(container);
} else {
return retrieveFromNodeRelationships((Node) container);
}
}
@Override
public String toString() {
return srcAttribute.name();
}
}