DATAGRAPH-387 : More updates for LabelNodeTypeRepresentationStrategy
This commit is contained in:
committed by
Michael Hunger
parent
400f195680
commit
b40ea309ae
@@ -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<Node> allThings = nodeTypeRepresentationStrategy.findAll(thingType);
|
||||
assertEquals("Did not find all things.",
|
||||
new HashSet<PropertyContainer>(Arrays.asList(neo4jTemplate.getPersistentState(subThing), neo4jTemplate.getPersistentState(thing))),
|
||||
new HashSet<PropertyContainer>(Arrays.asList(neo4jTemplate.getPersistentState(subSubThing), neo4jTemplate.getPersistentState(subThing), neo4jTemplate.getPersistentState(thing))),
|
||||
IteratorUtil.addToCollection(allThings, new HashSet<Node>()));
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Node> resourceIterable;
|
||||
private List<ResourceIterator> requestedIterators;
|
||||
|
||||
public ResourceIterableClosableIterable(ResourceIterable<Node> resourceIterable) {
|
||||
this.iterator = resourceIterable.iterator();
|
||||
this.resourceIterable = resourceIterable;
|
||||
this.requestedIterators = new ArrayList<ResourceIterator>();
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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<S> implements ClosableIterable {
|
||||
|
||||
private Iterator iterator;
|
||||
private Iterable<S> iterable;
|
||||
private boolean canBeClosed;
|
||||
private List<ResourceIterator> openedResourceIterators;
|
||||
public WrappedIterableClosableIterable(Iterable<S> iterable) {
|
||||
this.iterator = iterable.iterator();
|
||||
this.iterable = iterable;
|
||||
this.canBeClosed = (iterable instanceof ResourceIterable || iterable instanceof ClosableIterable);
|
||||
this.openedResourceIterators = new ArrayList<ResourceIterator>();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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<S extends Pro
|
||||
typesIndex = createTypesIndex();
|
||||
}
|
||||
|
||||
public static boolean isStrategyAlreadyInUse(GraphDatabase graphDatabaseService) {
|
||||
try {
|
||||
final Index<PropertyContainer> 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);
|
||||
}
|
||||
|
||||
@@ -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<Node> clazz;
|
||||
protected final LabelBasedStrategyCypherHelper cypherHelper;
|
||||
protected QueryEngine<CypherQuery> 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<String,Object> params = new HashMap<String,Object>();
|
||||
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 <U> ClosableIterable<Node> findAll(StoredEntityType type) {
|
||||
String query = String.format("match n:`%s` return n", type.getAlias().toString());
|
||||
Iterable<Node> rin = queryEngine.query(query, Collections.EMPTY_MAP).to(Node.class);
|
||||
Iterable<Node> rin = cypherHelper.getNodesWithLabel(type.getAlias().toString());
|
||||
return new WrappedIterableClosableIterable<Node>(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<String> labels = (Iterable)queryResult.get("labels");
|
||||
|
||||
Iterable<String> 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);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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<CypherQuery> queryEngine;
|
||||
|
||||
public LabelBasedStrategyCypherHelper(QueryEngine<CypherQuery> 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<Node> 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<String, Object> getParamsWithNodeId(long id) {
|
||||
Map<String,Object> params = new HashMap<String,Object>();
|
||||
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<String> getLabelsForNode(long nodeId) {
|
||||
Map queryResult = queryEngine.query(CYPHER_RETURN_LABELS_FOR_NODE, getParamsWithNodeId(nodeId)).to(Map.class).single();
|
||||
return (Iterable)queryResult.get("labels");
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -30,7 +30,6 @@ public class TypeRepresentationStrategyFactory {
|
||||
private final GraphDatabase graphDatabaseService;
|
||||
private final Strategy strategy;
|
||||
private IndexProvider indexProvider;
|
||||
private QueryEngine<CypherQuery> 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<PropertyContainer> 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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user