From b40ea309aede01b1536f907cb1aa39571e9c9f57 Mon Sep 17 00:00:00 2001 From: Nicki Watt Date: Mon, 30 Sep 2013 16:05:43 +0100 Subject: [PATCH] DATAGRAPH-387 : More updates for LabelNodeTypeRepresentationStrategy --- ...edNodeTypeRepresentationStrategyTests.java | 21 ++++- .../ResourceIterableClosableIterable.java | 20 +++-- .../WrappedIterableClosableIterable.java | 33 ++++++-- ...tIndexBasedTypeRepresentationStrategy.java | 11 +++ ...elBasedNodeTypeRepresentationStrategy.java | 63 ++++++-------- .../LabelBasedStrategyCypherHelper.java | 82 +++++++++++++++++++ ...ferenceNodeTypeRepresentationStrategy.java | 20 +++-- .../TypeRepresentationStrategyFactory.java | 40 ++------- 8 files changed, 195 insertions(+), 95 deletions(-) create mode 100644 spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/typerepresentation/LabelBasedStrategyCypherHelper.java diff --git a/spring-data-neo4j-aspects/src/test/java/org/springframework/data/neo4j/aspects/support/typerepresentation/LabelBasedNodeTypeRepresentationStrategyTests.java b/spring-data-neo4j-aspects/src/test/java/org/springframework/data/neo4j/aspects/support/typerepresentation/LabelBasedNodeTypeRepresentationStrategyTests.java index 77e6d0d9d..d92bbcd62 100644 --- a/spring-data-neo4j-aspects/src/test/java/org/springframework/data/neo4j/aspects/support/typerepresentation/LabelBasedNodeTypeRepresentationStrategyTests.java +++ b/spring-data-neo4j-aspects/src/test/java/org/springframework/data/neo4j/aspects/support/typerepresentation/LabelBasedNodeTypeRepresentationStrategyTests.java @@ -61,8 +61,10 @@ public class LabelBasedNodeTypeRepresentationStrategyTests extends EntityTestBas private Thing thing; private SubThing subThing; + private SubThing subSubThing; private StoredEntityType thingType; private StoredEntityType subThingType; + private StoredEntityType subSubThingType; @BeforeTransaction public void cleanDb() { @@ -76,6 +78,7 @@ public class LabelBasedNodeTypeRepresentationStrategyTests extends EntityTestBas } thingType = typeOf(Thing.class); subThingType = typeOf(SubThing.class); + subSubThingType = typeOf(SubSubThing.class); } @Test @@ -95,7 +98,7 @@ public class LabelBasedNodeTypeRepresentationStrategyTests extends EntityTestBas ClosableIterable allThings = nodeTypeRepresentationStrategy.findAll(thingType); assertEquals("Did not find all things.", - new HashSet(Arrays.asList(neo4jTemplate.getPersistentState(subThing), neo4jTemplate.getPersistentState(thing))), + new HashSet(Arrays.asList(neo4jTemplate.getPersistentState(subSubThing), neo4jTemplate.getPersistentState(subThing), neo4jTemplate.getPersistentState(thing))), IteratorUtil.addToCollection(allThings, new HashSet())); } @@ -104,16 +107,17 @@ public class LabelBasedNodeTypeRepresentationStrategyTests extends EntityTestBas public void testCountOfSuperTypeIncludesSubTypes() throws Exception { final int EXPECTED_NUM_THINGS = 1; final int EXPECTED_NUM_SUBTHINGS = 1; - final int TOTAL_EXPECTED = EXPECTED_NUM_THINGS + EXPECTED_NUM_SUBTHINGS; + final int EXPECTED_NUM_SUBSUBTHINGS = 1; + final int TOTAL_EXPECTED = EXPECTED_NUM_THINGS + EXPECTED_NUM_SUBTHINGS + EXPECTED_NUM_SUBSUBTHINGS; assertEquals(TOTAL_EXPECTED, nodeTypeRepresentationStrategy.count(thingType)); } @Test @Transactional public void testCountOfSubTypeExcludesConcreteParents() throws Exception { - final int EXPECTED_NUM_THINGS = 1; final int EXPECTED_NUM_SUBTHINGS = 1; - final int TOTAL_EXPECTED = EXPECTED_NUM_SUBTHINGS; + final int EXPECTED_NUM_SUBSUBTHINGS = 1; + final int TOTAL_EXPECTED = EXPECTED_NUM_SUBTHINGS + EXPECTED_NUM_SUBSUBTHINGS; assertEquals(TOTAL_EXPECTED, nodeTypeRepresentationStrategy.count(subThingType)); } @@ -122,8 +126,10 @@ public class LabelBasedNodeTypeRepresentationStrategyTests extends EntityTestBas public void testGetJavaType() throws Exception { assertEquals(thingType.getAlias(), nodeTypeRepresentationStrategy.readAliasFrom(node(thing))); assertEquals(subThingType.getAlias(), nodeTypeRepresentationStrategy.readAliasFrom(node(subThing))); + assertEquals(subSubThingType.getAlias(), nodeTypeRepresentationStrategy.readAliasFrom(node(subSubThing))); assertEquals(Thing.class, neo4jTemplate.getStoredJavaType(node(thing))); assertEquals(SubThing.class, neo4jTemplate.getStoredJavaType(node(subThing))); + assertEquals(SubSubThing.class, neo4jTemplate.getStoredJavaType(node(subSubThing))); } @Test @@ -162,6 +168,10 @@ public class LabelBasedNodeTypeRepresentationStrategyTests extends EntityTestBas subThing = neo4jTemplate.setPersistentState(new SubThing(),n2); nodeTypeRepresentationStrategy.writeTypeTo(n2, neo4jTemplate.getEntityType(SubThing.class)); subThing.setName("subThing"); + Node n3 = graphDatabaseService.createNode(); + subSubThing = neo4jTemplate.setPersistentState(new SubSubThing(),n3); + nodeTypeRepresentationStrategy.writeTypeTo(n3, neo4jTemplate.getEntityType(SubSubThing.class)); + subThing.setName("subSubThing"); tx.success(); return thing; } finally { @@ -193,4 +203,7 @@ public class LabelBasedNodeTypeRepresentationStrategyTests extends EntityTestBas public static class SubThing extends Thing { } + + public static class SubSubThing extends SubThing { + } } diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/mapping/ResourceIterableClosableIterable.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/mapping/ResourceIterableClosableIterable.java index 84c507016..73531f546 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/mapping/ResourceIterableClosableIterable.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/mapping/ResourceIterableClosableIterable.java @@ -1,32 +1,40 @@ package org.springframework.data.neo4j.support.mapping; -import com.tinkerpop.gremlin.Tokens; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.ResourceIterable; import org.neo4j.graphdb.ResourceIterator; import org.neo4j.helpers.collection.ClosableIterable; -import java.util.Iterator; +import java.util.ArrayList; +import java.util.List; /** + * TODO - Sort out closing of Iterators properly + * * @author Nicki Watt * @since 24-09-2013 */ public class ResourceIterableClosableIterable implements ClosableIterable , ResourceIterable { - private ResourceIterator iterator; + private ResourceIterable resourceIterable; + private List requestedIterators; public ResourceIterableClosableIterable(ResourceIterable resourceIterable) { - this.iterator = resourceIterable.iterator(); + this.resourceIterable = resourceIterable; + this.requestedIterators = new ArrayList(); } @Override public void close() { - iterator.close(); + for (ResourceIterator ri : requestedIterators) { + ri.close(); + } } @Override public ResourceIterator iterator() { - return iterator; + ResourceIterator ri = resourceIterable.iterator(); + requestedIterators.add(ri); + return ri; } }; diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/mapping/WrappedIterableClosableIterable.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/mapping/WrappedIterableClosableIterable.java index 0ce05b259..b3a948a2b 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/mapping/WrappedIterableClosableIterable.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/mapping/WrappedIterableClosableIterable.java @@ -1,11 +1,12 @@ package org.springframework.data.neo4j.support.mapping; -import org.neo4j.graphdb.Node; import org.neo4j.graphdb.ResourceIterable; import org.neo4j.graphdb.ResourceIterator; import org.neo4j.helpers.collection.ClosableIterable; +import java.util.ArrayList; import java.util.Iterator; +import java.util.List; /** * @author Nicki Watt @@ -13,19 +14,39 @@ import java.util.Iterator; */ public class WrappedIterableClosableIterable implements ClosableIterable { - private Iterator iterator; + private Iterable iterable; + private boolean canBeClosed; + private List openedResourceIterators; public WrappedIterableClosableIterable(Iterable iterable) { - this.iterator = iterable.iterator(); + this.iterable = iterable; + this.canBeClosed = (iterable instanceof ResourceIterable || iterable instanceof ClosableIterable); + this.openedResourceIterators = new ArrayList(); } + /** + * Note: Once this method has been called, it is not valid to + * call any other methods on this object thereafter; + */ @Override public void close() { - // no op - // Is this valid??? + if (canBeClosed) { + if (iterable instanceof ClosableIterable) { + ((ClosableIterable)iterable).close(); + } + for (ResourceIterator ri : openedResourceIterators) { + ri.close(); + } + } + openedResourceIterators = null; + iterable = null; } @Override public Iterator iterator() { - return iterator; + Iterator it = iterable.iterator(); + if (it instanceof ResourceIterator) { + openedResourceIterators.add((ResourceIterator)it); + } + return it; } }; diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/typerepresentation/AbstractIndexBasedTypeRepresentationStrategy.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/typerepresentation/AbstractIndexBasedTypeRepresentationStrategy.java index 535cc45cd..58ac4382d 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/typerepresentation/AbstractIndexBasedTypeRepresentationStrategy.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/typerepresentation/AbstractIndexBasedTypeRepresentationStrategy.java @@ -15,6 +15,7 @@ */ package org.springframework.data.neo4j.support.typerepresentation; +import org.neo4j.graphdb.Node; import org.neo4j.graphdb.PropertyContainer; import org.neo4j.graphdb.Transaction; import org.neo4j.graphdb.index.Index; @@ -25,6 +26,7 @@ import org.springframework.data.neo4j.core.TypeRepresentationStrategy; import org.springframework.data.neo4j.support.index.ClosableIndexHits; import org.springframework.data.neo4j.support.index.IndexProvider; import org.springframework.data.neo4j.support.index.IndexType; +import org.springframework.data.neo4j.support.index.NoSuchIndexException; import org.springframework.data.neo4j.support.mapping.StoredEntityType; import java.lang.Object; @@ -49,6 +51,15 @@ public abstract class AbstractIndexBasedTypeRepresentationStrategy index = graphDatabaseService.getIndex(IndexBasedNodeTypeRepresentationStrategy.INDEX_NAME); + return index!=null && Node.class.isAssignableFrom(index.getEntityType()); + } catch(NoSuchIndexException nsie) { + return false; + } + } + private Object indexValueForType(Object alias) { return indexProvider == null ? alias : indexProvider.createIndexValueForType(alias); } diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/typerepresentation/LabelBasedNodeTypeRepresentationStrategy.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/typerepresentation/LabelBasedNodeTypeRepresentationStrategy.java index 0ab322104..37707aaab 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/typerepresentation/LabelBasedNodeTypeRepresentationStrategy.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/typerepresentation/LabelBasedNodeTypeRepresentationStrategy.java @@ -28,10 +28,6 @@ import org.springframework.data.neo4j.support.mapping.StoredEntityType; import org.springframework.data.neo4j.support.mapping.WrappedIterableClosableIterable; import org.springframework.data.neo4j.support.query.QueryEngine; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - /** * Provides a Node Type Representation Strategy which makes use of Labels, and specifically * uses Cypher as the mechanism for interacting with the graph database. @@ -47,14 +43,15 @@ public class LabelBasedNodeTypeRepresentationStrategy implements NodeTypeReprese protected GraphDatabase graphDb; protected final Class clazz; + protected final LabelBasedStrategyCypherHelper cypherHelper; protected QueryEngine queryEngine; - private boolean sdnLabelStrategyPresent; public LabelBasedNodeTypeRepresentationStrategy(GraphDatabase graphDb) { this.graphDb = graphDb; this.clazz = Node.class; this.queryEngine = graphDb.queryEngineFor(QueryType.Cypher); - this.sdnLabelStrategyPresent = false; + this.cypherHelper = new LabelBasedStrategyCypherHelper(queryEngine); + markSDNLabelStrategyInUse(); } @Override @@ -65,10 +62,7 @@ public class LabelBasedNodeTypeRepresentationStrategy implements NodeTypeReprese if (state.hasLabel(sdnLabel)) { return; // already there } - - markSDNLabelStrategyInUseIfNotExists(); addLabelsForEntityHierarchy(state,type); - } /** @@ -78,56 +72,45 @@ public class LabelBasedNodeTypeRepresentationStrategy implements NodeTypeReprese * as the primary SDN marker Label. */ private void addLabelsForEntityHierarchy(Node state, StoredEntityType type) { - String addLabelStatement = String.format("match n where id(n)={nodeId} set n:`%s`:`%s`" , LABELSTRATEGY_PREFIX + type.getAlias(),type.getAlias()); + String labels = cypherHelper.buildLabelString(LABELSTRATEGY_PREFIX + type.getAlias(), (String)type.getAlias()); + labels = buildLabelStringIncludingEachEntityInHierarchy(labels, type); + cypherHelper.setLabelsOnNode(state.getId(), labels); + } + + private String buildLabelStringIncludingEachEntityInHierarchy(String labels, StoredEntityType type) { for (StoredEntityType superType : type.getSuperTypes()) { - addLabelStatement += String.format(":`%s`", superType.getAlias()); + labels += cypherHelper.buildLabelString((String)superType.getAlias()); + labels += buildLabelStringIncludingEachEntityInHierarchy(labels, superType); } - Map params = new HashMap(); - params.put("nodeId",state.getId()); - queryEngine.query( addLabelStatement, params); + return labels; } /** - * Checks if a special label (SDN_LABEL_STRATEGY) exists against the reference node, and - * if it does not, it is added. This label serves as an indicator that the Labeling strategy - * has/is being used on this data set. + * Ensures that a special label (SDN_LABEL_STRATEGY) exists against the + * reference node, and if it does not, it is added. This label serves + * as an indicator that the Labeling strategy has/is going to be used on this + * data set. */ - private void markSDNLabelStrategyInUseIfNotExists() { - if (!sdnLabelStrategyPresent) { - String query = String.format("match n where id(n)=%d and n:`%s` return count(*) ", REFERENCE_NODE_ID, SDN_LABEL_STRATEGY.name()); - Long labelCount = queryEngine.query(query, Collections.EMPTY_MAP).to(Long.class).single(); - - if (labelCount == 0) { - String update = String.format("match n where id(n)=%d set n:`%s` ", REFERENCE_NODE_ID, SDN_LABEL_STRATEGY.name()); - queryEngine.query(update, Collections.EMPTY_MAP); - } - sdnLabelStrategyPresent = true; - } + private void markSDNLabelStrategyInUse() { + cypherHelper.setLabelOnNode(REFERENCE_NODE_ID, SDN_LABEL_STRATEGY.name()); } @Override public ClosableIterable findAll(StoredEntityType type) { - String query = String.format("match n:`%s` return n", type.getAlias().toString()); - Iterable rin = queryEngine.query(query, Collections.EMPTY_MAP).to(Node.class); + Iterable rin = cypherHelper.getNodesWithLabel(type.getAlias().toString()); return new WrappedIterableClosableIterable(rin); - } @Override public long count(StoredEntityType type) { - String query = String.format("match n:`%s` return count(*)", type.getAlias().toString()); - return queryEngine.query(query, Collections.EMPTY_MAP).to(Long.class).single(); + return cypherHelper.countNodesWithLabel(type.getAlias().toString()); } @Override public Object readAliasFrom(Node state) { if (state == null) throw new IllegalArgumentException("Node is null"); - - String query = String.format("match n where id(n)=%d return labels(n) as labels", state.getId()); - Map queryResult = queryEngine.query(query, Collections.EMPTY_MAP).to(Map.class).single(); - Iterable labels = (Iterable)queryResult.get("labels"); - + Iterable labels = cypherHelper.getLabelsForNode(state.getId()); for (String label: labels) { if (label.startsWith(LABELSTRATEGY_PREFIX)) { return label.substring(LABELSTRATEGY_PREFIX.length()); @@ -142,4 +125,8 @@ public class LabelBasedNodeTypeRepresentationStrategy implements NodeTypeReprese // don't think we need to do anything here! } + public static boolean isStrategyAlreadyInUse(GraphDatabase graphDatabaseService) { + return graphDatabaseService.getReferenceNode().hasLabel(SDN_LABEL_STRATEGY); + + } } \ No newline at end of file diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/typerepresentation/LabelBasedStrategyCypherHelper.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/typerepresentation/LabelBasedStrategyCypherHelper.java new file mode 100644 index 000000000..1992e1b12 --- /dev/null +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/typerepresentation/LabelBasedStrategyCypherHelper.java @@ -0,0 +1,82 @@ +package org.springframework.data.neo4j.support.typerepresentation; + +import org.neo4j.graphdb.Node; +import org.springframework.data.neo4j.repository.query.CypherQuery; +import org.springframework.data.neo4j.support.query.QueryEngine; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * Provides some helper Cypher based functionality specifically + * for use by the Label Based Node Type Representation Strategy. + * This class may well become more broadly accessible / generic in time + * however for now, serves to specifically aid the + * Label Based Node Type Representation Strategy. + * + * @author Nicki Watt + * @since 24-09-2013 + */ +public class LabelBasedStrategyCypherHelper { + + static final String CYPHER_ADD_LABEL_TO_NODE = "match n where id(n)={nodeId} set n:`%s`"; + static final String CYPHER_ADD_LABELS_TO_NODE = "match n where id(n)={nodeId} set n%s"; + static final String CYPHER_COUNT_LABELS_ON_NODE = "match n where id(n)={nodeId} and n:`%s` return count(*) "; + static final String CYPHER_RETURN_NODES_WITH_LABEL = "match n:`%s` return n"; + static final String CYPHER_RETURN_COUNT_OF_NODES_WITH_LABEL = "match n:`%s` return count(*)"; + static final String CYPHER_RETURN_LABELS_FOR_NODE = "match n where id(n)={nodeId} return labels(n) as labels"; + + private QueryEngine queryEngine; + + public LabelBasedStrategyCypherHelper(QueryEngine queryEngine) { + this.queryEngine = queryEngine; + } + + public void setLabelOnNode(Long nodeId, String label) { + String addLabelStatement = String.format(CYPHER_ADD_LABEL_TO_NODE , label); + queryEngine.query( addLabelStatement, getParamsWithNodeId(nodeId) ); + } + + public void setLabelsOnNode(Long nodeId, String labelString) { + String addLabelStatement = String.format(CYPHER_ADD_LABELS_TO_NODE , labelString); + queryEngine.query( addLabelStatement, getParamsWithNodeId(nodeId) ); + } + + public boolean doesNodeHaveLabel(Long nodeId, String label) { + String query = String.format(CYPHER_COUNT_LABELS_ON_NODE, label); + long labelCount = queryEngine.query(query, getParamsWithNodeId(nodeId)).to(Long.class).single(); + return labelCount > 0; + } + + public Iterable getNodesWithLabel(String label) { + String query = String.format(CYPHER_RETURN_NODES_WITH_LABEL, label); + return queryEngine.query(query, Collections.EMPTY_MAP).to(Node.class); + } + + + + public String buildLabelString(String... labels) { + String result = ""; + for (String label: labels) { + result += ":`" + label + "`"; + } + return result; + } + + private Map getParamsWithNodeId(long id) { + Map params = new HashMap(); + params.put("nodeId",id); + return params; + } + + public long countNodesWithLabel(String label) { + String query = String.format(CYPHER_RETURN_COUNT_OF_NODES_WITH_LABEL, label); + return queryEngine.query(query, Collections.EMPTY_MAP).to(Long.class).single(); + } + + public Iterable getLabelsForNode(long nodeId) { + Map queryResult = queryEngine.query(CYPHER_RETURN_LABELS_FOR_NODE, getParamsWithNodeId(nodeId)).to(Map.class).single(); + return (Iterable)queryResult.get("labels"); + } +} diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/typerepresentation/SubReferenceNodeTypeRepresentationStrategy.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/typerepresentation/SubReferenceNodeTypeRepresentationStrategy.java index b5164527a..ca5f4b60a 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/typerepresentation/SubReferenceNodeTypeRepresentationStrategy.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/typerepresentation/SubReferenceNodeTypeRepresentationStrategy.java @@ -16,12 +16,7 @@ package org.springframework.data.neo4j.support.typerepresentation; -import org.neo4j.graphdb.Direction; -import org.neo4j.graphdb.DynamicRelationshipType; -import org.neo4j.graphdb.Node; -import org.neo4j.graphdb.PropertyContainer; -import org.neo4j.graphdb.Relationship; -import org.neo4j.graphdb.RelationshipType; +import org.neo4j.graphdb.*; import org.neo4j.graphdb.traversal.TraversalDescription; import org.neo4j.helpers.collection.ClosableIterable; import org.neo4j.helpers.collection.IterableWrapper; @@ -92,6 +87,19 @@ public class SubReferenceNodeTypeRepresentationStrategy implements NodeTypeRepre entity.removeProperty("___dummy_property_for_locking___"); } + public static boolean isStrategyAlreadyInUse(GraphDatabase graphDatabaseService) { + try { + for (Relationship rel : graphDatabaseService.getReferenceNode().getRelationships()) { + if (rel.getType().name().startsWith(SubReferenceNodeTypeRepresentationStrategy.SUBREF_PREFIX)) { + return true; + } + } + } catch(NotFoundException nfe) { + // ignore + } + return false; + } + @Override public void writeTypeTo(Node state, StoredEntityType type) { final Node subReference = obtainSubreferenceNode(type); diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/typerepresentation/TypeRepresentationStrategyFactory.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/typerepresentation/TypeRepresentationStrategyFactory.java index 9233f63c2..083f71177 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/typerepresentation/TypeRepresentationStrategyFactory.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/typerepresentation/TypeRepresentationStrategyFactory.java @@ -30,7 +30,6 @@ public class TypeRepresentationStrategyFactory { private final GraphDatabase graphDatabaseService; private final Strategy strategy; private IndexProvider indexProvider; - private QueryEngine queryEngine; public TypeRepresentationStrategyFactory(GraphDatabase graphDatabaseService) { this(graphDatabaseService,chooseStrategy(graphDatabaseService), null); @@ -52,44 +51,15 @@ public class TypeRepresentationStrategyFactory { } private static Strategy chooseStrategy(GraphDatabase graphDatabaseService) { - Transaction tx = graphDatabaseService.beginTx(); - try { - if (isAlreadyIndexed(graphDatabaseService)) return Strategy.Indexed; - if (isAlreadySubRef(graphDatabaseService)) return Strategy.SubRef; - if (isAlreadyLabeled(graphDatabaseService)) return Strategy.Labeled; + try (Transaction tx = graphDatabaseService.beginTx()) { + if (AbstractIndexBasedTypeRepresentationStrategy.isStrategyAlreadyInUse(graphDatabaseService)) return Strategy.Indexed; + if (SubReferenceNodeTypeRepresentationStrategy.isStrategyAlreadyInUse(graphDatabaseService)) return Strategy.SubRef; + if (LabelBasedNodeTypeRepresentationStrategy.isStrategyAlreadyInUse(graphDatabaseService)) return Strategy.Labeled; + tx.success(); return Strategy.Indexed; - } finally { - tx.success();tx.finish(); } } - private static boolean isAlreadyLabeled(GraphDatabase graphDatabaseService) { - return graphDatabaseService.getReferenceNode().hasLabel( - LabelBasedNodeTypeRepresentationStrategy.SDN_LABEL_STRATEGY); - } - - private static boolean isAlreadyIndexed(GraphDatabase graphDatabaseService) { - try { - final Index index = graphDatabaseService.getIndex(IndexBasedNodeTypeRepresentationStrategy.INDEX_NAME); - return index!=null && Node.class.isAssignableFrom(index.getEntityType()); - } catch(NoSuchIndexException nsie) { - return false; - } - } - - private static boolean isAlreadySubRef(GraphDatabase graphDatabaseService) { - try { - for (Relationship rel : graphDatabaseService.getReferenceNode().getRelationships()) { - if (rel.getType().name().startsWith(SubReferenceNodeTypeRepresentationStrategy.SUBREF_PREFIX)) { - return true; - } - } - } catch(NotFoundException nfe) { - // ignore - } - return false; - } - public NodeTypeRepresentationStrategy getNodeTypeRepresentationStrategy() { return strategy.getNodeTypeRepresentationStrategy(graphDatabaseService, indexProvider); }