Added auto config to factory bean. For a pre-existing store, it will use the strategy used when that store was created. Otherwise it defaults to Indexed. Also made count() implementation of IndexingNodeTypeStrategy iterate the results instead of use size().

This commit is contained in:
David Montag
2011-03-22 16:24:02 -07:00
parent 186a910c3f
commit af25f4435f
2 changed files with 76 additions and 9 deletions

View File

@@ -15,7 +15,10 @@ import org.springframework.persistence.support.EntityInstantiator;
public class IndexingNodeTypeStrategy implements NodeTypeStrategy {
private EntityInstantiator<NodeBacked, Node> graphEntityInstantiator;
public static final String NODE_INDEX_NAME = "__types__";
public static final String TYPE_PROPERTY_NAME = "__type__";
public static final String INDEX_KEY = "className";
private EntityInstantiator<NodeBacked, Node> graphEntityInstantiator;
private GraphDatabaseService graphDb;
public IndexingNodeTypeStrategy(GraphDatabaseService graphDb, EntityInstantiator<NodeBacked, Node> graphEntityInstantiator) {
@@ -24,7 +27,7 @@ public class IndexingNodeTypeStrategy implements NodeTypeStrategy {
}
private Index<Node> getTypesIndex() {
return graphDb.index().forNodes("__types__");
return graphDb.index().forNodes(NODE_INDEX_NAME);
}
@Override
@@ -32,20 +35,20 @@ public class IndexingNodeTypeStrategy implements NodeTypeStrategy {
Node node = entity.getPersistentState();
Class<? extends NodeBacked> entityClass = entity.getClass();
addToTypesIndex(node, entityClass);
node.setProperty("__type__", entityClass.getName());
node.setProperty(TYPE_PROPERTY_NAME, entityClass.getName());
}
private void addToTypesIndex(Node node, Class<? extends NodeBacked> entityClass) {
Class<?> klass = entityClass;
while (klass.getAnnotation(NodeEntity.class) != null) {
getTypesIndex().add(node, "className", klass.getName());
getTypesIndex().add(node, INDEX_KEY, klass.getName());
klass = klass.getSuperclass();
}
}
@Override
public <ENTITY extends NodeBacked> Iterable<ENTITY> findAll(Class<ENTITY> clazz) {
final IndexHits<Node> allEntitiesOfType = getTypesIndex().get("className", clazz.getName());
final IndexHits<Node> allEntitiesOfType = getTypesIndex().get(INDEX_KEY, clazz.getName());
return new FilteringIterable<ENTITY>(new IterableWrapper<ENTITY, Node>(allEntitiesOfType) {
@Override
@SuppressWarnings("unchecked")
@@ -64,7 +67,11 @@ public class IndexingNodeTypeStrategy implements NodeTypeStrategy {
@Override
public long count(Class<? extends NodeBacked> entityClass) {
return getTypesIndex().get("className", entityClass.getName()).size();
long count = 0;
for (Node node : getTypesIndex().get(INDEX_KEY, entityClass.getName())) {
count += 1;
}
return count;
}
@Override
@@ -72,7 +79,7 @@ public class IndexingNodeTypeStrategy implements NodeTypeStrategy {
public <ENTITY extends NodeBacked> Class<ENTITY> getJavaType(Node node) {
if (node == null) throw new IllegalArgumentException("Node is null");
try {
return (Class<ENTITY>) Class.forName((String) node.getProperty("__type__"));
return (Class<ENTITY>) Class.forName((String) node.getProperty(TYPE_PROPERTY_NAME));
} catch (NotFoundException e) {
return null;
} catch (ClassNotFoundException e) {

View File

@@ -2,6 +2,7 @@ package org.springframework.data.graph.neo4j.support;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.data.graph.core.NodeBacked;
import org.springframework.data.graph.core.NodeTypeStrategy;
@@ -10,24 +11,83 @@ import org.springframework.persistence.support.EntityInstantiator;
public class NodeTypeStrategyFactoryBean implements FactoryBean<NodeTypeStrategy> {
private GraphDatabaseService graphDatabaseService;
private EntityInstantiator<NodeBacked, Node> graphEntityInstantiator;
private Strategy strategy;
public NodeTypeStrategyFactoryBean(GraphDatabaseService graphDatabaseService, EntityInstantiator<NodeBacked, Node> graphEntityInstantiator) {
this.graphDatabaseService = graphDatabaseService;
this.graphEntityInstantiator = graphEntityInstantiator;
strategy = chooseStrategy();
}
private Strategy chooseStrategy() {
if (isAlreadyIndexed()) return Strategy.Indexed;
if (isAlreadySubRef()) return Strategy.SubRef;
return Strategy.Indexed;
}
private boolean isAlreadyIndexed() {
return graphDatabaseService.index().existsForNodes(IndexingNodeTypeStrategy.NODE_INDEX_NAME);
}
private boolean isAlreadySubRef() {
for (Relationship rel : graphDatabaseService.getReferenceNode().getRelationships()) {
if (rel.getType().name().startsWith(SubReferenceNodeTypeStrategy.SUBREF_PREFIX)) {
return true;
}
}
return false;
}
@Override
public NodeTypeStrategy getObject() throws Exception {
return new SubReferenceNodeTypeStrategy(graphDatabaseService, graphEntityInstantiator);
return strategy.getObject(graphDatabaseService, graphEntityInstantiator);
}
@Override
public Class<?> getObjectType() {
return SubReferenceNodeTypeStrategy.class;
return strategy.getObjectType();
}
@Override
public boolean isSingleton() {
return false;
}
private enum Strategy {
SubRef {
@Override
NodeTypeStrategy getObject(GraphDatabaseService graphDatabaseService, EntityInstantiator<NodeBacked, Node> graphEntityInstantiator) {
return new SubReferenceNodeTypeStrategy(graphDatabaseService, graphEntityInstantiator);
}
@Override
Class<? extends NodeTypeStrategy> getObjectType() {
return SubReferenceNodeTypeStrategy.class;
}
},
Indexed {
@Override
NodeTypeStrategy getObject(GraphDatabaseService graphDatabaseService, EntityInstantiator<NodeBacked, Node> graphEntityInstantiator) {
return new IndexingNodeTypeStrategy(graphDatabaseService, graphEntityInstantiator);
}
@Override
Class<? extends NodeTypeStrategy> getObjectType() {
return IndexingNodeTypeStrategy.class;
}
},
Noop {
@Override
NodeTypeStrategy getObject(GraphDatabaseService graphDatabaseService, EntityInstantiator<NodeBacked, Node> graphEntityInstantiator) {
return new NoopNodeTypeStrategy();
}
@Override
Class<? extends NodeTypeStrategy> getObjectType() {
return NoopNodeTypeStrategy.class;
}
};
abstract NodeTypeStrategy getObject(GraphDatabaseService graphDatabaseService, EntityInstantiator<NodeBacked, Node> graphEntityInstantiator);
abstract Class<? extends NodeTypeStrategy> getObjectType();
}
}