Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package com.tinkerpop.blueprints.impls.neo4j2;
  
 
 import java.util.*;
A Blueprints implementation of the graph database Neo4j (http://neo4j.org)

Author(s):
Marko A. Rodriguez (http://markorodriguez.com)
 
     private static final Logger logger = Logger.getLogger(Neo4j2Graph.class.getName());
 
     private GraphDatabaseService rawGraph;
     private static final String INDEXED_KEYS_POSTFIX = ":indexed_keys";
 
     protected final ThreadLocal<Transactiontx = new ThreadLocal<Transaction>() {
         protected Transaction initialValue() {
             return null;
         }
     };
 
     protected final ThreadLocal<BooleancheckElementsInTransaction = new ThreadLocal<Boolean>() {
         protected Boolean initialValue() {
             return false;
         }
     };
 
     private static final Features FEATURES = new Features();
 
     static {
 
         . = false;
         . = true;
         . = true;
         . = true;
         . = true;
         . = true;
         . = true;
         . = false;
         . = true;
         . = false;
         . = true;
 
         . = true;
         . = true;
         . = true;
         . = false;
         . = true;
         . = true;
         . = true;
         . = true;
         . = true;
         . = true;
         . = true;
         . = true;
         . = true;
         . = true;
         . = true;
        . = true;
        . = true;
        . = false;
    }
    private final TransactionManager transactionManager;
    private final ExecutionEngine cypher;
    protected boolean checkElementsInTransaction() {
        if (this..get() == null) {
            return false;
        } else {
            return this..get();
        }
    }

    
Neo4j's transactions are not consistent between the graph and the graph indices. Moreover, global graph operations are not consistent. For example, if a vertex is removed and then an index is queried in the same transaction, the removed vertex can be returned. This method allows the developer to turn on/off a Neo4j2Graph 'hack' that ensures transactional consistency. The default behavior for Neo4j2Graph is to use Neo4j's native behavior which ensures speed at the expensive of consistency. Note that this boolean switch is local to the current thread (i.e. a ThreadLocal variable).

Parameters:
checkElementsInTransaction check whether an element is in the transaction between returning it
    public void setCheckElementsInTransaction(final boolean checkElementsInTransaction) {
        this..set(checkElementsInTransaction);
    }
    public Neo4j2Graph(final String directory) {
        this(directorynull);
    }
    public Neo4j2Graph(final GraphDatabaseService rawGraph) {
        this. = rawGraph;
         = new ExecutionEngine(rawGraph);
        init();
    }
    public Neo4j2Graph(final String directoryfinal Map<StringStringconfiguration) {
        try {
            GraphDatabaseBuilder builder = new GraphDatabaseFactory().newEmbeddedDatabaseBuilder(directory);
            if (null != configuration)
                this. = builder.setConfig(configuration).newGraphDatabase();
            else
                this. = builder.newGraphDatabase();
             = new ExecutionEngine();
            init();
        } catch (Exception e) {
            if (this. != null)
                this..shutdown();
            throw new RuntimeException(e.getMessage(), e);
        }
    }
    protected void init() {
        this.loadKeyIndices();
    }
    public Neo4j2Graph(final Configuration configuration) {
        this(configuration.getString("blueprints.neo4j.directory"null),
                ConfigurationConverter.getMap(configuration.subset("blueprints.neo4j.conf")));
    }
    private void loadKeyIndices() {
        this.autoStartTransaction(true);
        for (final String key : this.getInternalIndexKeys(Vertex.class)) {
            this.createKeyIndex(keyVertex.class);
        }
        for (final String key : this.getInternalIndexKeys(Edge.class)) {
            this.createKeyIndex(keyEdge.class);
        }
        this.commit();
    }
    private <T extends Elementvoid createInternalIndexKey(final String keyfinal Class<T> elementClass) {
        final String propertyName = elementClass.getSimpleName() + ;
        if ( instanceof GraphDatabaseAPI) {
            final PropertyContainer pc = getGraphProperties();
            try {
                final String[] keys = (String[]) pc.getProperty(propertyName);
                final Set<Stringtemp = new HashSet<String>(Arrays.asList(keys));
                temp.add(key);
                pc.setProperty(propertyNametemp.toArray(new String[temp.size()]));
            } catch (Exception e) {
                // no indexed_keys kernel data property
                pc.setProperty(propertyNamenew String[]{key});
            }
        } else {
            throw new UnsupportedOperationException(
                    "Unable to create an index on a non-GraphDatabaseAPI graph");
        }
    }
    private <T extends Elementvoid dropInternalIndexKey(final String keyfinal Class<T> elementClass) {
        final String propertyName = elementClass.getSimpleName() + ;
        if ( instanceof GraphDatabaseAPI) {
            final PropertyContainer pc = getGraphProperties();
            try {
                final String[] keys = (String[]) pc.getProperty(propertyName);
                final Set<Stringtemp = new HashSet<String>(Arrays.asList(keys));
                temp.remove(key);
                pc.setProperty(propertyNametemp.toArray(new String[temp.size()]));
            } catch (Exception e) {
                // no indexed_keys kernel data property
            }
        } else {
            logNotGraphDatabaseAPI();
        }
    }
    public <T extends ElementSet<StringgetInternalIndexKeys(final Class<T> elementClass) {
        final String propertyName = elementClass.getSimpleName() + ;
        if ( instanceof GraphDatabaseAPI) {
            final PropertyContainer pc = getGraphProperties();
            try {
                final String[] keys = (String[]) pc.getProperty(propertyName);
                return new HashSet<String>(Arrays.asList(keys));
            } catch (Exception e) {
                // no indexed_keys kernel data property
            }
        } else {
            logNotGraphDatabaseAPI();
        }
        return Collections.emptySet();
    }
    }
    private void logNotGraphDatabaseAPI() {
        if (.isLoggable(.)) {
            .log(."Indices are not available on non-GraphDatabaseAPI instances" +
                    " Current graph class is " + .getClass().getName());
        }
    }
    public synchronized <T extends ElementIndex<T> createIndex(final String indexNamefinal Class<T> indexClassfinal Parameter... indexParameters) {
        this.autoStartTransaction(true);
        if (this..index().existsForNodes(indexName) || this..index().existsForRelationships(indexName)) {
            throw ExceptionFactory.indexAlreadyExists(indexName);
        }
        return new Neo4j2Index(indexNameindexClassthisindexParameters);
    }
    public <T extends ElementIndex<T> getIndex(final String indexNamefinal Class<T> indexClass) {
        this.autoStartTransaction(false);
        if (Vertex.class.isAssignableFrom(indexClass)) {
            if (this..index().existsForNodes(indexName)) {
                return new Neo4j2Index(indexNameindexClassthis);
            } else if (this..index().existsForRelationships(indexName)) {
                throw ExceptionFactory.indexDoesNotSupportClass(indexNameindexClass);
            } else {
                return null;
            }
        } else if (Edge.class.isAssignableFrom(indexClass)) {
            if (this..index().existsForRelationships(indexName)) {
                return new Neo4j2Index(indexNameindexClassthis);
            } else if (this..index().existsForNodes(indexName)) {
                throw ExceptionFactory.indexDoesNotSupportClass(indexNameindexClass);
            } else {
                return null;
            }
        } else {
            return null;
        }
    }

    

Note that this method will force a successful closing of the current thread's transaction. As such, once the index is dropped, the operation is committed.

Parameters:
indexName the name of the index to drop
    public synchronized void dropIndex(final String indexName) {
        this.autoStartTransaction(true);
        if (this..index().existsForNodes(indexName)) {
            org.neo4j.graphdb.index.Index<NodenodeIndex = this..index().forNodes(indexName);
            if (nodeIndex.isWriteable()) {
                nodeIndex.delete();
            }
        } else if (this..index().existsForRelationships(indexName)) {
            RelationshipIndex relationshipIndex = this..index().forRelationships(indexName);
            if (relationshipIndex.isWriteable()) {
                relationshipIndex.delete();
            }
        }
        this.commit();
    }
    public Iterable<Index<? extends Element>> getIndices() {
        this.autoStartTransaction(false);
        final List<Index<? extends Element>> indices = new ArrayList<Index<? extends Element>>();
        for (final String name : this..index().nodeIndexNames()) {
            if (!name.equals(.))
                indices.add(new Neo4j2Index(nameVertex.classthis));
        }
        for (final String name : this..index().relationshipIndexNames()) {
            if (!name.equals(.))
                indices.add(new Neo4j2Index(nameEdge.classthis));
        }
        return indices;
    }
    public Neo4j2Vertex addVertex(final Object id) {
        this.autoStartTransaction(true);
        return new Neo4j2Vertex(this..createNode(), this);
    }
    public Neo4j2Vertex getVertex(final Object id) {
        this.autoStartTransaction(false);
        if (null == id)
            throw ExceptionFactory.vertexIdCanNotBeNull();
        try {
            final Long longId;
            if (id instanceof Long)
                longId = (Longid;
            else if (id instanceof Number)
                longId = ((Numberid).longValue();
            else
                longId = Double.valueOf(id.toString()).longValue();
            return new Neo4j2Vertex(this..getNodeById(longId), this);
        } catch (NotFoundException e) {
            return null;
        } catch (NumberFormatException e) {
            return null;
        }
    }

    

The underlying Neo4j graph does not natively support this method within a transaction. If the graph is not currently in a transaction, then the operation runs efficiently and correctly. If the graph is currently in a transaction, please use setCheckElementsInTransaction() if it is necessary to ensure proper transactional semantics. Note that it is costly to check if an element is in the transaction.

Returns:
all the vertices in the graph
    public Iterable<VertexgetVertices() {
        this.autoStartTransaction(false);
        return new Neo4j2VertexIterable(GlobalGraphOperations.at().getAllNodes(), thisthis.checkElementsInTransaction());
    }
    public Iterable<VertexgetVertices(final String keyfinal Object value) {
        this.autoStartTransaction(false);
        final AutoIndexer indexer = this..index().getNodeAutoIndexer();
        if (indexer.isEnabled() && indexer.getAutoIndexedProperties().contains(key))
            return new Neo4j2VertexIterable(this..index().getNodeAutoIndexer().getAutoIndex().get(keyvalue), thisthis.checkElementsInTransaction());
        else
            return new PropertyFilteredIterable<Vertex>(keyvaluethis.getVertices());
    }

    

The underlying Neo4j graph does not natively support this method within a transaction. If the graph is not currently in a transaction, then the operation runs efficiently and correctly. If the graph is currently in a transaction, please use setCheckElementsInTransaction() if it is necessary to ensure proper transactional semantics. Note that it is costly to check if an element is in the transaction.

Returns:
all the edges in the graph
    public Iterable<EdgegetEdges() {
        this.autoStartTransaction(false);
        return new Neo4j2EdgeIterable(GlobalGraphOperations.at().getAllRelationships(), thisthis.checkElementsInTransaction());
    }
    public Iterable<EdgegetEdges(final String keyfinal Object value) {
        this.autoStartTransaction(false);
        final AutoIndexer indexer = this..index().getRelationshipAutoIndexer();
        if (indexer.isEnabled() && indexer.getAutoIndexedProperties().contains(key))
            return new Neo4j2EdgeIterable(this..index().getRelationshipAutoIndexer().getAutoIndex().get(keyvalue), this,
                    this.checkElementsInTransaction());
        else
            return new PropertyFilteredIterable<Edge>(keyvaluethis.getEdges());
    }
    public <T extends Elementvoid dropKeyIndex(final String keyfinal Class<T> elementClass) {
        if (elementClass == null)
            throw ExceptionFactory.classForElementCannotBeNull();
        this.autoStartTransaction(true);
        if (Vertex.class.isAssignableFrom(elementClass)) {
            if (!this..index().getNodeAutoIndexer().isEnabled())
                return;
            this..index().getNodeAutoIndexer().stopAutoIndexingProperty(key);
        } else if (Edge.class.isAssignableFrom(elementClass)) {
            if (!this..index().getRelationshipAutoIndexer().isEnabled())
                return;
        } else {
            throw ExceptionFactory.classIsNotIndexable(elementClass);
        }
        this.dropInternalIndexKey(keyelementClass);
    }
    public <T extends Elementvoid createKeyIndex(final String keyfinal Class<T> elementClassfinal Parameter... indexParameters) {
        if (elementClass == null)
            throw ExceptionFactory.classForElementCannotBeNull();
        if (Vertex.class.isAssignableFrom(elementClass)) {
            this.autoStartTransaction(true);
            if (!this..index().getNodeAutoIndexer().isEnabled())
                this..index().getNodeAutoIndexer().setEnabled(true);
            this..index().getNodeAutoIndexer().startAutoIndexingProperty(key);
            if (!this.getInternalIndexKeys(Vertex.class).contains(key)) {
                KeyIndexableGraphHelper.reIndexElements(thisthis.getVertices(), new HashSet<String>(Arrays.asList(key)));
                this.autoStartTransaction(true);
                this.createInternalIndexKey(keyelementClass);
            }
        } else if (Edge.class.isAssignableFrom(elementClass)) {
            this.autoStartTransaction(true);
            if (!this..index().getRelationshipAutoIndexer().isEnabled())
                this..index().getRelationshipAutoIndexer().setEnabled(true);
            if (!this.getInternalIndexKeys(Edge.class).contains(key)) {
                KeyIndexableGraphHelper.reIndexElements(thisthis.getEdges(), new HashSet<String>(Arrays.asList(key)));
                this.autoStartTransaction(true);
                this.createInternalIndexKey(keyelementClass);
            }
        } else {
            throw ExceptionFactory.classIsNotIndexable(elementClass);
        }
    }
    public <T extends ElementSet<StringgetIndexedKeys(final Class<T> elementClass) {
        if (elementClass == null)
            throw ExceptionFactory.classForElementCannotBeNull();
        if (Vertex.class.isAssignableFrom(elementClass)) {
            if (!this..index().getNodeAutoIndexer().isEnabled())
                return Collections.emptySet();
            return this..index().getNodeAutoIndexer().getAutoIndexedProperties();
        } else if (Edge.class.isAssignableFrom(elementClass)) {
            if (!this..index().getRelationshipAutoIndexer().isEnabled())
                return Collections.emptySet();
            return this..index().getRelationshipAutoIndexer().getAutoIndexedProperties();
        } else {
            throw ExceptionFactory.classIsNotIndexable(elementClass);
        }
    }
    public void removeVertex(final Vertex vertex) {
        this.autoStartTransaction(true);
        try {
            final Node node = ((Neo4j2Vertexvertex).getRawVertex();
            for (final Relationship relationship : node.getRelationships(....)) {
                relationship.delete();
            }
            node.delete();
        } catch (NotFoundException nfe) {
            throw ExceptionFactory.vertexWithIdDoesNotExist(vertex.getId());
        } catch (IllegalStateException ise) {
            // wrap the neo4j exception so that the message is consistent in blueprints.
            throw ExceptionFactory.vertexWithIdDoesNotExist(vertex.getId());
        }
    }
    public Neo4j2Edge addEdge(final Object idfinal Vertex outVertexfinal Vertex inVertexfinal String label) {
        if (label == null)
            throw ExceptionFactory.edgeLabelCanNotBeNull();
        this.autoStartTransaction(true);
        return new Neo4j2Edge(((Neo4j2VertexoutVertex).getRawVertex().createRelationshipTo(((Neo4j2VertexinVertex).getRawVertex(),
                DynamicRelationshipType.withName(label)), this);
    }
    public Neo4j2Edge getEdge(final Object id) {
        if (null == id)
            throw ExceptionFactory.edgeIdCanNotBeNull();
        this.autoStartTransaction(true);
        try {
            final Long longId;
            if (id instanceof Long)
                longId = (Longid;
            else
                longId = Double.valueOf(id.toString()).longValue();
            return new Neo4j2Edge(this..getRelationshipById(longId), this);
        } catch (NotFoundException e) {
            return null;
        } catch (NumberFormatException e) {
            return null;
        }
    }
    public void removeEdge(final Edge edge) {
        this.autoStartTransaction(true);
        ((Relationship) ((Neo4j2Edgeedge).getRawElement()).delete();
    }
    public void stopTransaction(Conclusion conclusion) {
        if (. == conclusion)
            commit();
        else
            rollback();
    }
    public void commit() {
        if (null == .get()) {
            return;
        }
        try {
            .get().success();
        } finally {
            .get().finish();
            .remove();
        }
    }
    public void rollback() {
        if (null == .get()) {
            return;
        }
        try {
            if (t == null || t.getStatus() == .) {
                return;
            }
            .get().failure();
        } catch (SystemException e) {
            throw new RuntimeException(e);
        } finally {
            .get().close();
            .remove();
        }
    }
    public void shutdown() {
        try {
            this.commit();
        } catch (TransactionFailureException e) {
            .warning("Failure on shutdown "+e.getMessage());
            // TODO: inspect why certain transactions fail
        }
        this..shutdown();
    }
    // The forWrite flag is true when the autoStartTransaction method is
    // called before any operation which will modify the graph in any way. It
    // is not used in this simple implementation but is required in subclasses
    // which enforce transaction rules. Now that Neo4j reads also require a
    // transaction to be open it is otherwise impossible to tell the difference
    // between the beginning of a write operation and the beginning of a read
    // operation.
    public void autoStartTransaction(boolean forWrite) {
        if (.get() == null)
            .set(this..beginTx());
    }
    public GraphDatabaseService getRawGraph() {
        return this.;
    }
    public Features getFeatures() {
        return ;
    }
    public String toString() {
        return StringFactory.graphString(thisthis..toString());
    }
    public GraphQuery query() {
        return new DefaultGraphQuery(this);
    }
    public Iterator<Map<String,Object>> query(String queryMap<String,Objectparams) {
        return .execute(query,params==null ? Collections.<String,Object>emptyMap() : params).iterator();
    }
    public boolean nodeIsDeleted(long nodeId) {
    }
    public boolean relationshipIsDeleted(long nodeId) {
    }
New to GrepCode? Check out our FAQ X