package com.tinkerpop.blueprints.impls.neo4j;
import com.tinkerpop.blueprints.Edge;
import com.tinkerpop.blueprints.Element;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.util.ElementHelper;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.PropertyContainer;
import org.neo4j.graphdb.Relationship;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/**
* @author Marko A. Rodriguez (http://markorodriguez.com)
*/
abstract class Neo4jElement implements Element {
protected final Neo4jGraph graph;
protected PropertyContainer rawElement;
public Neo4jElement(final Neo4jGraph graph) {
this.graph = graph;
}
public <T> T getProperty(final String key) {
if (this.rawElement.hasProperty(key))
return (T) tryConvertCollectionToArrayList(this.rawElement.getProperty(key));
else
return null;
}
public void setProperty(final String key, final Object value) {
ElementHelper.validateProperty(this, key, value);
this.graph.autoStartTransaction();
// attempts to take a collection and convert it to an array so that Neo4j can consume it
this.rawElement.setProperty(key, tryConvertCollectionToArray(value));
}
public <T> T removeProperty(final String key) {
if (!this.rawElement.hasProperty(key))
return null;
else {
this.graph.autoStartTransaction();
return (T) this.rawElement.removeProperty(key);
}
}
public Set<String> getPropertyKeys() {
final Set<String> keys = new HashSet<String>();
for (final String key : this.rawElement.getPropertyKeys()) {
keys.add(key);
}
return keys;
}
public int hashCode() {
return this.getId().hashCode();
}
public PropertyContainer getRawElement() {
return this.rawElement;
}
public Object getId() {
if (this.rawElement instanceof Node) {
return ((Node) this.rawElement).getId();
} else {
return ((Relationship) this.rawElement).getId();
}
}
public void remove() {
if (this instanceof Vertex)
this.graph.removeVertex((Vertex) this);
else
this.graph.removeEdge((Edge) this);
}
public boolean equals(final Object object) {
return ElementHelper.areEqual(this, object);
}
private Object tryConvertCollectionToArray(final Object value) {
if (value instanceof Collection<?>) {
// convert this collection to an array. the collection must
// be all of the same type.
try {
final Collection<?> collection = (Collection<?>) value;
Object[] array = null;
final Iterator<?> objects = collection.iterator();
for (int i = 0; objects.hasNext(); i++) {
Object object = objects.next();
if (array == null) {
array = (Object[]) Array.newInstance(object.getClass(), collection.size());
}
array[i] = object;
}
return array;
} catch (final ArrayStoreException ase) {
// this fires off if the collection is not all of the same type
return value;
}
} else {
return value;
}
}
private Object tryConvertCollectionToArrayList(final Object value) {
if (value.getClass().isArray()) {
// convert primitive array to an ArrayList.
try {
ArrayList<Object> list = new ArrayList<Object>();
int arrlength = Array.getLength(value);
for (int i = 0; i < arrlength; i++) {
Object object = Array.get(value, i);
list.add(object);
}
return list;
} catch (final Exception e) {
// this fires off if the collection is not an array
return value;
}
} else {
return value;
}
}
}