GraphDatabase for RestGraphDatabase

This commit is contained in:
Michael Hunger
2011-03-31 14:08:26 +02:00
parent eaa5b4a672
commit d606d319fa
4 changed files with 289 additions and 83 deletions

View File

@@ -0,0 +1,131 @@
package org.neo4j.kernel;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.kernel.impl.core.*;
import org.neo4j.kernel.impl.nioneo.store.FileSystemAbstraction;
import org.neo4j.kernel.impl.nioneo.store.StoreId;
import org.neo4j.kernel.impl.transaction.LockManager;
import org.neo4j.kernel.impl.transaction.TxModule;
import org.neo4j.kernel.impl.transaction.xaframework.LogBufferFactory;
import org.neo4j.kernel.impl.transaction.xaframework.TxIdGenerator;
import org.neo4j.rest.graphdb.RestGraphDatabase;
import javax.transaction.*;
import javax.transaction.xa.XAResource;
import java.util.Collections;
import java.util.Map;
/**
* @author mh
* @since 23.02.11
*/
public class RestConfig extends Config {
public RestConfig(GraphDatabaseService graphDb, String storeDir, StoreId storeId,
Map<String, String> inputParams, KernelPanicEventGenerator kpe,
TxModule txModule, LockManager lockManager, LockReleaser lockReleaser,
IdGeneratorFactory idGeneratorFactory,
TxEventSyncHookFactory txSyncHookFactory, RelationshipTypeCreator relTypeCreator,
TxIdGenerator txIdGenerator, LastCommittedTxIdSetter lastCommittedTxIdSetter,
FileSystemAbstraction fileSystem, LogBufferFactory logBufferFactory) {
super(graphDb, storeDir, storeId,
inputParams, kpe, txModule, lockManager, lockReleaser, idGeneratorFactory, txSyncHookFactory, relTypeCreator, txIdGenerator, lastCommittedTxIdSetter, fileSystem, logBufferFactory);
}
public RestConfig(RestGraphDatabase restGraphDatabase) {
super(restGraphDatabase, restGraphDatabase.getStoreDir(), null,
Collections.<String,String>emptyMap(),null,
new TxModule(true,null){
@Override
public TransactionManager getTxManager() {
return new NullTransactionManager();
}
},
null,null,
null,null,null,null,null,
null,null);
}
private static class NullTransactionManager implements TransactionManager {
private static final Transaction NULL_JAVA_TRANSACTION = new Transaction() {
@Override
public void commit() throws HeuristicMixedException, HeuristicRollbackException, RollbackException, SecurityException, SystemException {
}
@Override
public boolean delistResource(XAResource xaResource, int i) throws IllegalStateException, SystemException {
return false;
}
@Override
public boolean enlistResource(XAResource xaResource) throws IllegalStateException, RollbackException, SystemException {
return false;
}
@Override
public int getStatus() throws SystemException {
return Status.STATUS_NO_TRANSACTION;
}
@Override
public void registerSynchronization(Synchronization synchronization) throws IllegalStateException, RollbackException, SystemException {
}
@Override
public void rollback() throws IllegalStateException, SystemException {
}
@Override
public void setRollbackOnly() throws IllegalStateException, SystemException {
}
};
@Override
public void begin() throws NotSupportedException, SystemException {
}
@Override
public void commit() throws HeuristicMixedException, HeuristicRollbackException, IllegalStateException, RollbackException, SecurityException, SystemException {
}
@Override
public int getStatus() throws SystemException {
return 0;
}
@Override
public Transaction getTransaction() throws SystemException {
return NULL_JAVA_TRANSACTION;
}
@Override
public void resume(Transaction transaction) throws IllegalStateException, InvalidTransactionException, SystemException {
}
@Override
public void rollback() throws IllegalStateException, SecurityException, SystemException {
}
@Override
public void setRollbackOnly() throws IllegalStateException, SystemException {
}
@Override
public void setTransactionTimeout(int i) throws SystemException {
}
@Override
public Transaction suspend() throws SystemException {
return NULL_JAVA_TRANSACTION;
}
}
}

View File

@@ -0,0 +1,48 @@
package org.springframework.data.graph.core;
import java.util.Map;
/**
* @author mh
* @since 31.03.11
*/
public class Property {
public final String name;
public final Object value;
public Property(String name, Object value) {
this.name = name;
this.value = value;
}
public static Property _(String name, Object value) {
return new Property(name, value);
}
public static Property[] _(String name1, Object value1, String name2, Object value2) {
return new Property[]{new Property(name1, value1), new Property(name2, value2)};
}
public static Property[] _(String name1, Object value1, String name2, Object value2, String name3, Object value3) {
return new Property[]{new Property(name1, value1), new Property(name2, value2), new Property(name3, value3)};
}
public static Property[] _(Object... nameValuePairs) {
if (nameValuePairs.length % 2 != 0)
throw new IllegalArgumentException("there must be an even number of name value pairs");
Property[] result = new Property[nameValuePairs.length / 2];
for (int i = 0; i < result.length; i++) {
result[i] = new Property(nameValuePairs[i * 2].toString(), nameValuePairs[i * 2 + 1]);
}
return result;
}
public static Property[] _(Map<String, Object> properties) {
Property[] result = new Property[properties.size()];
int i = 0;
for (Map.Entry<String, Object> entry : properties.entrySet()) {
result[i++] = new Property(entry.getKey(), entry.getValue());
}
return result;
}
}

View File

@@ -0,0 +1,110 @@
package org.springframework.data.graph.neo4j.support;
import org.neo4j.graphdb.*;
import org.neo4j.graphdb.index.Index;
import org.neo4j.graphdb.index.IndexManager;
import org.neo4j.graphdb.traversal.TraversalDescription;
import org.neo4j.index.impl.lucene.LuceneIndexImplementation;
import org.neo4j.kernel.AbstractGraphDatabase;
import org.neo4j.kernel.Traversal;
import org.springframework.data.graph.core.GraphDatabase;
import org.springframework.data.graph.core.NodeBacked;
import org.springframework.data.graph.core.Property;
import org.springframework.data.graph.core.RelationshipBacked;
import java.util.Map;
/**
* @author mh
* @since 29.03.11
*/
public class DelegatingGraphDatabase implements GraphDatabase {
protected AbstractGraphDatabase delegate;
public DelegatingGraphDatabase(final AbstractGraphDatabase delegate) {
this.delegate = delegate;
}
@Override
public Node getReferenceNode() {
return delegate.getReferenceNode();
}
@Override
public Node getNodeById(long id) {
return delegate.getNodeById(id);
}
@Override
public Node createNode(Property... props) {
return setProperties(delegate.createNode(), props);
}
private <T extends PropertyContainer> T setProperties(T element, Property[] props) {
if (props==null || props.length==0) return element;
for (Property prop : props) {
element.setProperty(prop.name, prop.value);
}
return element;
}
@Override
public Relationship getRelationshipById(long id) {
return delegate.getRelationshipById(id);
}
@Override
public Relationship createRelationship(Node startNode, Node endNode, RelationshipType type, Property... props) {
return setProperties(startNode.createRelationshipTo(endNode,type),props);
}
@Override
public <T extends PropertyContainer> Index<T> getIndex(String indexName) {
IndexManager indexManager = delegate.index();
if (indexManager.existsForNodes(indexName)) return (Index<T>) indexManager.forNodes(indexName);
if (indexManager.existsForRelationships(indexName)) return (Index<T>) indexManager.forRelationships(indexName);
throw new IllegalArgumentException("Index "+indexName+" does not exist.");
}
// TODO handle existing indexes
@Override
public <T extends PropertyContainer> Index<T> createIndex(Class<T> type, String indexName, boolean fullText) {
IndexManager indexManager = delegate.index();
if (isNode(type)) {
if (indexManager.existsForNodes(indexName))
return (Index<T>) checkAndGetExistingIndex(indexName, fullText, indexManager.forNodes(indexName));
return (Index<T>) indexManager.forNodes(indexName, indexConfigFor(fullText));
} else {
if (indexManager.existsForRelationships(indexName))
return (Index<T>) checkAndGetExistingIndex(indexName, fullText, indexManager.forRelationships(indexName));
return (Index<T>) indexManager.forRelationships(indexName, indexConfigFor(fullText));
}
}
public boolean isNode(Class<? extends PropertyContainer> type) {
if (type.equals(Node.class)) return true;
if (type.equals(Relationship.class)) return false;
throw new IllegalArgumentException("Unknown Graph Primitive, neither Node nor Relationship"+type);
}
private <T extends PropertyContainer> Index<T> checkAndGetExistingIndex(final String indexName, boolean fullText, final Index<T> index) {
Map<String, String> existingConfig = delegate.index().getConfiguration(index);
Map<String, String> config = indexConfigFor(fullText);
if (config.equals(existingConfig)) return index;
throw new IllegalArgumentException("Setup for index "+indexName+" does not match "+(fullText ? "fulltext":"exact"));
}
private Map<String, String> indexConfigFor(boolean fullText) {
return fullText ? LuceneIndexImplementation.FULLTEXT_CONFIG : LuceneIndexImplementation.EXACT_CONFIG;
}
@Override
public TraversalDescription createTraversalDescription() {
return Traversal.description();
}
public void shutdown() {
delegate.shutdown();
}
}

View File

@@ -1,83 +0,0 @@
package org.springframework.data.graph.neo4j.support;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.PropertyContainer;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.RelationshipType;
import org.neo4j.graphdb.index.Index;
import org.neo4j.graphdb.index.IndexManager;
import org.neo4j.graphdb.traversal.TraversalDescription;
import org.neo4j.index.impl.lucene.LuceneIndexImplementation;
import org.neo4j.kernel.EmbeddedGraphDatabase;
import org.neo4j.kernel.Traversal;
import org.springframework.data.graph.core.GraphDatabase;
import org.springframework.data.graph.core.NodeBacked;
import org.springframework.data.graph.core.RelationshipBacked;
import java.io.File;
import java.util.Map;
/**
* @author mh
* @since 29.03.11
*/
public class LocalGraphDatabase implements GraphDatabase {
protected EmbeddedGraphDatabase delegate;
public LocalGraphDatabase(File file) {
delegate = new EmbeddedGraphDatabase(file.getAbsolutePath());
}
@Override
public Node getReferenceNode() {
return delegate.getReferenceNode();
}
@Override
public Node getNode(long id) {
return delegate.getNodeById(id);
}
@Override
public Node createNode(Map<String, Object> props, String... indexFields) {
return null;
}
@Override
public Relationship getRelationship(long id) {
return delegate.getRelationshipById(id);
}
@Override
public Relationship createRelationship(Node startNode, Node endNode, RelationshipType type, Map<String, Object> props, String... indexFields) {
return null;
}
@Override
public <T extends PropertyContainer> Index<T> getIndex(String indexName) {
IndexManager indexManager = delegate.index();
if (indexManager.existsForNodes(indexName)) return (Index<T>) indexManager.forNodes(indexName);
if (indexManager.existsForRelationships(indexName)) return (Index<T>) indexManager.forRelationships(indexName);
throw new IllegalArgumentException("Index "+indexName+" does not exist.");
}
// TODO handle existing indexes
@Override
public <T extends PropertyContainer> Index<T> createIndex(Class<T> type, String indexName, boolean fullText) {
IndexManager indexManager = delegate.index();
Map<String, String> config = fullText ? LuceneIndexImplementation.FULLTEXT_CONFIG : LuceneIndexImplementation.EXACT_CONFIG;
if (NodeBacked.class.isAssignableFrom(type)) return (Index<T>) indexManager.forNodes(indexName, config);
if (RelationshipBacked.class.isAssignableFrom(type)) return (Index<T>) indexManager.forRelationships(indexName, config);
throw new IllegalArgumentException("Wrong index type supplied "+type);
}
@Override
public TraversalDescription createTraversalDescription() {
return Traversal.description();
}
public void shutdown() {
delegate.shutdown();
}
}