From af25f4435f94473387317609ea0cdaf3448a6c93 Mon Sep 17 00:00:00 2001 From: David Montag Date: Tue, 22 Mar 2011 16:24:02 -0700 Subject: [PATCH] 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(). --- .../support/IndexingNodeTypeStrategy.java | 21 ++++-- .../support/NodeTypeStrategyFactoryBean.java | 64 ++++++++++++++++++- 2 files changed, 76 insertions(+), 9 deletions(-) diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/IndexingNodeTypeStrategy.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/IndexingNodeTypeStrategy.java index ae6c78270..eac2afc1e 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/IndexingNodeTypeStrategy.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/IndexingNodeTypeStrategy.java @@ -15,7 +15,10 @@ import org.springframework.persistence.support.EntityInstantiator; public class IndexingNodeTypeStrategy implements NodeTypeStrategy { - private EntityInstantiator 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 graphEntityInstantiator; private GraphDatabaseService graphDb; public IndexingNodeTypeStrategy(GraphDatabaseService graphDb, EntityInstantiator graphEntityInstantiator) { @@ -24,7 +27,7 @@ public class IndexingNodeTypeStrategy implements NodeTypeStrategy { } private Index 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 entityClass = entity.getClass(); addToTypesIndex(node, entityClass); - node.setProperty("__type__", entityClass.getName()); + node.setProperty(TYPE_PROPERTY_NAME, entityClass.getName()); } private void addToTypesIndex(Node node, Class 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 Iterable findAll(Class clazz) { - final IndexHits allEntitiesOfType = getTypesIndex().get("className", clazz.getName()); + final IndexHits allEntitiesOfType = getTypesIndex().get(INDEX_KEY, clazz.getName()); return new FilteringIterable(new IterableWrapper(allEntitiesOfType) { @Override @SuppressWarnings("unchecked") @@ -64,7 +67,11 @@ public class IndexingNodeTypeStrategy implements NodeTypeStrategy { @Override public long count(Class 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 Class getJavaType(Node node) { if (node == null) throw new IllegalArgumentException("Node is null"); try { - return (Class) Class.forName((String) node.getProperty("__type__")); + return (Class) Class.forName((String) node.getProperty(TYPE_PROPERTY_NAME)); } catch (NotFoundException e) { return null; } catch (ClassNotFoundException e) { diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/NodeTypeStrategyFactoryBean.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/NodeTypeStrategyFactoryBean.java index ec4c95a93..0810258c4 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/NodeTypeStrategyFactoryBean.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/support/NodeTypeStrategyFactoryBean.java @@ -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 { private GraphDatabaseService graphDatabaseService; private EntityInstantiator graphEntityInstantiator; + private Strategy strategy; public NodeTypeStrategyFactoryBean(GraphDatabaseService graphDatabaseService, EntityInstantiator 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 graphEntityInstantiator) { + return new SubReferenceNodeTypeStrategy(graphDatabaseService, graphEntityInstantiator); + } + + @Override + Class getObjectType() { + return SubReferenceNodeTypeStrategy.class; + } + }, + Indexed { + @Override + NodeTypeStrategy getObject(GraphDatabaseService graphDatabaseService, EntityInstantiator graphEntityInstantiator) { + return new IndexingNodeTypeStrategy(graphDatabaseService, graphEntityInstantiator); + } + + @Override + Class getObjectType() { + return IndexingNodeTypeStrategy.class; + } + }, + Noop { + @Override + NodeTypeStrategy getObject(GraphDatabaseService graphDatabaseService, EntityInstantiator graphEntityInstantiator) { + return new NoopNodeTypeStrategy(); + } + + @Override + Class getObjectType() { + return NoopNodeTypeStrategy.class; + } + }; + abstract NodeTypeStrategy getObject(GraphDatabaseService graphDatabaseService, EntityInstantiator graphEntityInstantiator); + abstract Class getObjectType(); + } }