DATAGRAPH-387 : LabelingNodeTypeRepresentationStrategy (phase 1)
This commit is contained in:
committed by
Michael Hunger
parent
a44acd6614
commit
aac1a16e9e
@@ -0,0 +1,183 @@
|
||||
/**
|
||||
* Copyright 2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.neo4j.aspects.support.typerepresentation;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.neo4j.graphdb.Node;
|
||||
import org.neo4j.graphdb.PropertyContainer;
|
||||
import org.neo4j.graphdb.Transaction;
|
||||
import org.neo4j.helpers.collection.IteratorUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.neo4j.annotation.NodeEntity;
|
||||
import org.springframework.data.neo4j.aspects.support.EntityTestBase;
|
||||
import org.springframework.data.neo4j.support.Neo4jTemplate;
|
||||
import org.springframework.data.neo4j.support.mapping.Neo4jMappingContext;
|
||||
import org.springframework.data.neo4j.support.mapping.StoredEntityType;
|
||||
import org.springframework.data.neo4j.support.typerepresentation.CoreAPIBasedLabelingNodeTypeRepresentationStrategy;
|
||||
import org.springframework.test.context.CleanContextCacheTestExecutionListener;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.TestExecutionListeners;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
|
||||
import org.springframework.test.context.transaction.BeforeTransaction;
|
||||
import org.springframework.test.context.transaction.TransactionalTestExecutionListener;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(locations = {"classpath:org/springframework/data/neo4j/aspects/support/Neo4jGraphPersistenceTests-context.xml",
|
||||
"classpath:org/springframework/data/neo4j/aspects/support/LabelingTypeRepresentationStrategyOverride-context.xml"})
|
||||
@TestExecutionListeners({CleanContextCacheTestExecutionListener.class, DependencyInjectionTestExecutionListener.class, TransactionalTestExecutionListener.class})
|
||||
public class LabelingNodeTypeRepresentationStrategyTests extends EntityTestBase {
|
||||
|
||||
@Autowired
|
||||
private CoreAPIBasedLabelingNodeTypeRepresentationStrategy nodeTypeRepresentationStrategy;
|
||||
|
||||
@Autowired
|
||||
Neo4jTemplate neo4jTemplate;
|
||||
@Autowired
|
||||
Neo4jMappingContext ctx;
|
||||
|
||||
private Thing thing;
|
||||
private SubThing subThing;
|
||||
private StoredEntityType thingType;
|
||||
private StoredEntityType subThingType;
|
||||
|
||||
@BeforeTransaction
|
||||
public void cleanDb() {
|
||||
super.cleanDb();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
if (thing == null) {
|
||||
createThingsAndLinks();
|
||||
}
|
||||
thingType = typeOf(Thing.class);
|
||||
subThingType = typeOf(SubThing.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
public void testPostEntityCreation() throws Exception {
|
||||
// Anything to test here??
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPreEntityRemoval() throws Exception {
|
||||
// preEntityRemoval is a no op method, so nothing to test here!
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
public void testFindAll() throws Exception {
|
||||
|
||||
assertEquals("Did not find all things.",
|
||||
new HashSet<PropertyContainer>(Arrays.asList(neo4jTemplate.getPersistentState(subThing), neo4jTemplate.getPersistentState(thing))),
|
||||
IteratorUtil.addToCollection(nodeTypeRepresentationStrategy.findAll(thingType), new HashSet<Node>()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
public void testCount() throws Exception {
|
||||
assertEquals(2, nodeTypeRepresentationStrategy.count(thingType));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
public void testGetJavaType() throws Exception {
|
||||
assertEquals(thingType.getAlias(), nodeTypeRepresentationStrategy.readAliasFrom(node(thing)));
|
||||
assertEquals(subThingType.getAlias(), nodeTypeRepresentationStrategy.readAliasFrom(node(subThing)));
|
||||
assertEquals(Thing.class, neo4jTemplate.getStoredJavaType(node(thing)));
|
||||
assertEquals(SubThing.class, neo4jTemplate.getStoredJavaType(node(subThing)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
public void testCreateEntityAndInferType() throws Exception {
|
||||
Thing newThing = neo4jTemplate.createEntityFromStoredType(node(thing), neo4jTemplate.getMappingPolicy(thing));
|
||||
assertEquals(thing, newThing);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
public void testCreateEntityAndSpecifyType() throws Exception {
|
||||
Thing newThing = neo4jTemplate.createEntityFromState(node(subThing), Thing.class, neo4jTemplate.getMappingPolicy(subThing));
|
||||
assertEquals(subThing, newThing);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
public void testProjectEntity() throws Exception {
|
||||
Unrelated other = neo4jTemplate.projectTo(node(thing), Unrelated.class);
|
||||
assertEquals("thing", other.getName());
|
||||
}
|
||||
|
||||
private Node node(Thing thing) {
|
||||
return getNodeState(thing);
|
||||
}
|
||||
|
||||
private Thing createThingsAndLinks() {
|
||||
Transaction tx = graphDatabaseService.beginTx();
|
||||
try {
|
||||
Node n1 = graphDatabaseService.createNode();
|
||||
thing = neo4jTemplate.setPersistentState(new Thing(),n1);
|
||||
nodeTypeRepresentationStrategy.writeTypeTo(n1, neo4jTemplate.getEntityType(Thing.class));
|
||||
thing.setName("thing");
|
||||
Node n2 = graphDatabaseService.createNode();
|
||||
subThing = neo4jTemplate.setPersistentState(new SubThing(),n2);
|
||||
nodeTypeRepresentationStrategy.writeTypeTo(n2, neo4jTemplate.getEntityType(SubThing.class));
|
||||
subThing.setName("subThing");
|
||||
tx.success();
|
||||
return thing;
|
||||
} finally {
|
||||
tx.finish();
|
||||
}
|
||||
}
|
||||
|
||||
@NodeEntity
|
||||
public static class Unrelated {
|
||||
String name;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
@NodeEntity
|
||||
public static class Thing {
|
||||
String name;
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
public static class SubThing extends Thing {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<bean id="typeRepresentationStrategyFactory" class="org.springframework.data.neo4j.support.typerepresentation.TypeRepresentationStrategyFactory">
|
||||
<constructor-arg index="0" ref="graphDatabase"/>
|
||||
<constructor-arg index="1" value="Labeled"/>
|
||||
</bean>
|
||||
</beans>
|
||||
@@ -33,6 +33,8 @@ import org.springframework.data.neo4j.annotation.QueryType;
|
||||
import org.springframework.data.neo4j.conversion.DefaultConverter;
|
||||
import org.springframework.data.neo4j.conversion.ResultConverter;
|
||||
import org.springframework.data.neo4j.core.GraphDatabase;
|
||||
import org.springframework.data.neo4j.core.GraphDatabaseGlobalOperations;
|
||||
import org.springframework.data.neo4j.support.DelegatingGraphDatabaseGlobalOperations;
|
||||
import org.springframework.data.neo4j.support.index.NoSuchIndexException;
|
||||
import org.springframework.data.neo4j.support.query.ConversionServiceQueryResultConverter;
|
||||
import org.springframework.data.neo4j.support.query.QueryEngine;
|
||||
@@ -46,6 +48,7 @@ public class SpringRestGraphDatabase extends org.neo4j.rest.graphdb.RestGraphDat
|
||||
}
|
||||
private ConversionService conversionService;
|
||||
private ResultConverter resultConverter;
|
||||
private GraphDatabaseGlobalOperations globalOperations;
|
||||
|
||||
public SpringRestGraphDatabase( RestAPI api){
|
||||
super(api);
|
||||
@@ -59,6 +62,14 @@ public class SpringRestGraphDatabase extends org.neo4j.rest.graphdb.RestGraphDat
|
||||
this(new RestAPIFacade( uri, user, password ));
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphDatabaseGlobalOperations getGlobalGraphOperations() {
|
||||
if (this.globalOperations == null) {
|
||||
this.globalOperations = new DelegatingGraphDatabaseGlobalOperations(this);
|
||||
}
|
||||
return globalOperations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node createNode(Map<String, Object> props) {
|
||||
return super.getRestAPI().createNode(props);
|
||||
|
||||
@@ -30,6 +30,13 @@ import java.util.Map;
|
||||
|
||||
|
||||
public interface GraphDatabase {
|
||||
|
||||
/**
|
||||
* @return an object which is able to provide global graph
|
||||
* type operations
|
||||
*/
|
||||
GraphDatabaseGlobalOperations getGlobalGraphOperations();
|
||||
|
||||
/**
|
||||
* @return the reference node of the underlying graph database
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.springframework.data.neo4j.core;
|
||||
|
||||
import org.neo4j.graphdb.*;
|
||||
|
||||
/**
|
||||
* Defines the list of global graph operations which can be used
|
||||
* within SDN. (At present restricted to those providing Label
|
||||
* based functionality)
|
||||
*
|
||||
* @author Nicki Watt
|
||||
* @since 24-09-2013
|
||||
*/
|
||||
public interface GraphDatabaseGlobalOperations {
|
||||
|
||||
public ResourceIterable<Label> getAllLabels();
|
||||
|
||||
public ResourceIterable<Node> getAllNodesWithLabel(Label label);
|
||||
|
||||
}
|
||||
@@ -33,6 +33,7 @@ import org.springframework.data.neo4j.conversion.DefaultConverter;
|
||||
import org.springframework.data.neo4j.conversion.Result;
|
||||
import org.springframework.data.neo4j.conversion.ResultConverter;
|
||||
import org.springframework.data.neo4j.core.GraphDatabase;
|
||||
import org.springframework.data.neo4j.core.GraphDatabaseGlobalOperations;
|
||||
import org.springframework.data.neo4j.support.index.IndexType;
|
||||
import org.springframework.data.neo4j.support.index.NoSuchIndexException;
|
||||
import org.springframework.data.neo4j.support.query.ConversionServiceQueryResultConverter;
|
||||
@@ -55,6 +56,7 @@ public class DelegatingGraphDatabase implements GraphDatabase {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(DelegatingGraphDatabase.class);
|
||||
|
||||
protected GraphDatabaseGlobalOperations globalOperations;
|
||||
protected GraphDatabaseService delegate;
|
||||
private ConversionService conversionService;
|
||||
private ResultConverter resultConverter;
|
||||
@@ -62,17 +64,23 @@ public class DelegatingGraphDatabase implements GraphDatabase {
|
||||
private volatile QueryEngine<Object> gremlinQueryEngine;
|
||||
|
||||
public DelegatingGraphDatabase(final GraphDatabaseService delegate) {
|
||||
this.delegate = delegate;
|
||||
this(delegate,null);
|
||||
}
|
||||
public DelegatingGraphDatabase(final GraphDatabaseService delegate, ResultConverter resultConverter) {
|
||||
this.delegate = delegate;
|
||||
this.resultConverter = resultConverter;
|
||||
this.globalOperations = new DelegatingGraphDatabaseGlobalOperations(delegate);
|
||||
}
|
||||
|
||||
public void setConversionService(ConversionService conversionService) {
|
||||
this.conversionService = conversionService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphDatabaseGlobalOperations getGlobalGraphOperations() {
|
||||
return globalOperations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setResultConverter(ResultConverter resultConverter) {
|
||||
this.resultConverter = resultConverter;
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package org.springframework.data.neo4j.support;
|
||||
|
||||
import org.neo4j.graphdb.*;
|
||||
import org.neo4j.tooling.GlobalGraphOperations;
|
||||
import org.springframework.data.neo4j.core.GraphDatabaseGlobalOperations;
|
||||
|
||||
/**
|
||||
* @author Nicki Watt
|
||||
* @since 24-09-2013
|
||||
*/
|
||||
public class DelegatingGraphDatabaseGlobalOperations implements GraphDatabaseGlobalOperations {
|
||||
|
||||
private GraphDatabaseService graphDatabaseService;
|
||||
private GlobalGraphOperations globalGraphOperations;
|
||||
|
||||
public DelegatingGraphDatabaseGlobalOperations(GraphDatabaseService delegate) {
|
||||
this.graphDatabaseService = delegate;
|
||||
}
|
||||
|
||||
private GlobalGraphOperations getGlobalGraphOperations() {
|
||||
if (globalGraphOperations == null) {
|
||||
globalGraphOperations = GlobalGraphOperations.at(graphDatabaseService);
|
||||
}
|
||||
return globalGraphOperations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceIterable<Label> getAllLabels() {
|
||||
return getGlobalGraphOperations().getAllLabels();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceIterable<Node> getAllNodesWithLabel(Label label) {
|
||||
return getGlobalGraphOperations().getAllNodesWithLabel(label);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
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.Iterator;
|
||||
|
||||
/**
|
||||
* @author Nicki Watt
|
||||
* @since 24-09-2013
|
||||
*/
|
||||
public class ResourceIterableClosableIterable implements ClosableIterable {
|
||||
|
||||
private ResourceIterator iterator;
|
||||
public ResourceIterableClosableIterable(ResourceIterable<Node> resourceIterable) {
|
||||
this.iterator = resourceIterable.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
iterator.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator iterator() {
|
||||
return iterator;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,120 @@
|
||||
/**
|
||||
* Copyright 2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.neo4j.support.typerepresentation;
|
||||
|
||||
import org.neo4j.graphdb.DynamicLabel;
|
||||
import org.neo4j.graphdb.Label;
|
||||
import org.neo4j.graphdb.Node;
|
||||
import org.neo4j.graphdb.ResourceIterable;
|
||||
import org.neo4j.helpers.collection.ClosableIterable;
|
||||
import org.springframework.data.neo4j.core.GraphDatabase;
|
||||
import org.springframework.data.neo4j.core.GraphDatabaseGlobalOperations;
|
||||
import org.springframework.data.neo4j.core.NodeTypeRepresentationStrategy;
|
||||
import org.springframework.data.neo4j.support.mapping.ResourceIterableClosableIterable;
|
||||
import org.springframework.data.neo4j.support.mapping.StoredEntityType;
|
||||
|
||||
/**
|
||||
* Provides a Node Type Representation Strategy which makes use of Labels, and specifically
|
||||
* uses the Core API as the mechanism for dealing with this. (This is inline with how
|
||||
* the original Node Type Representation Strategies used to work - moving forward a
|
||||
* Cypher based one will be used, however this exists for comparison purposes at this
|
||||
* point in time in the development)
|
||||
*
|
||||
* @author Nicki Watt
|
||||
* @since 24-09-2013
|
||||
*/
|
||||
public class CoreAPIBasedLabelingNodeTypeRepresentationStrategy implements NodeTypeRepresentationStrategy {
|
||||
|
||||
// option A : store type in entity
|
||||
// public static final String TYPE_PROPERTY_NAME = "__type__";
|
||||
// option B : add special type label
|
||||
public static final String TYPE_LABEL_PREFIX = "__TYPE__";
|
||||
protected GraphDatabase graphDb;
|
||||
protected final Class<Node> clazz;
|
||||
|
||||
public CoreAPIBasedLabelingNodeTypeRepresentationStrategy(GraphDatabase graphDb) {
|
||||
this.graphDb = graphDb;
|
||||
this.clazz = Node.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTypeTo(Node state, StoredEntityType type) {
|
||||
if (type == null || !type.isNodeEntity()) return;
|
||||
|
||||
ResourceIterable<Label> labels = state.getLabels();
|
||||
if (labels.iterator().hasNext()) {
|
||||
return; // already there
|
||||
}
|
||||
|
||||
addLabel(state,type,true);
|
||||
for (StoredEntityType superType : type.getSuperTypes()) {
|
||||
addLabel(state, superType, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void addLabel(Node state, StoredEntityType type, boolean isPrimary) {
|
||||
String alias = type.getAlias().toString();
|
||||
state.addLabel(DynamicLabel.label(alias));
|
||||
if (isPrimary) {
|
||||
// option A : store type in entity
|
||||
// state.setProperty(TYPE_PROPERTY_NAME,alias);
|
||||
|
||||
// option B : add special type label
|
||||
state.addLabel(DynamicLabel.label(TYPE_LABEL_PREFIX + alias));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <U> ClosableIterable<Node> findAll(StoredEntityType type) {
|
||||
long count = 0;
|
||||
GraphDatabaseGlobalOperations globalOps = graphDb.getGlobalGraphOperations();
|
||||
final ResourceIterable<Node> rin = globalOps.getAllNodesWithLabel(DynamicLabel.label(type.getAlias().toString()));
|
||||
return new ResourceIterableClosableIterable(rin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long count(StoredEntityType type) {
|
||||
long count = 0;
|
||||
GraphDatabaseGlobalOperations globalOps = graphDb.getGlobalGraphOperations();
|
||||
for (Node n : globalOps.getAllNodesWithLabel(DynamicLabel.label(type.getAlias().toString()))) {
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readAliasFrom(Node state) {
|
||||
if (state == null)
|
||||
throw new IllegalArgumentException("Node is null");
|
||||
|
||||
// Option A: Derive alias from property
|
||||
// return state.getProperty(TYPE_PROPERTY_NAME);
|
||||
|
||||
// Option B: Derive alias from special Label
|
||||
for (Label label: state.getLabels()) {
|
||||
if (label.name().startsWith(TYPE_LABEL_PREFIX)) {
|
||||
return label.name().substring(TYPE_LABEL_PREFIX.length());
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("No primary SDN label exists .. (i.e one with SDN_) ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preEntityRemoval(Node state) {
|
||||
// don't think we need to do anything here!
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* Copyright 2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.neo4j.support.typerepresentation;
|
||||
|
||||
import org.neo4j.graphdb.Node;
|
||||
import org.neo4j.helpers.collection.ClosableIterable;
|
||||
import org.springframework.data.neo4j.core.GraphDatabase;
|
||||
import org.springframework.data.neo4j.core.NodeTypeRepresentationStrategy;
|
||||
import org.springframework.data.neo4j.support.mapping.StoredEntityType;
|
||||
|
||||
/**
|
||||
* Provides a Node Type Representation Strategy which makes use of Labels, and specifically
|
||||
* uses Cypher as the mechanism for dealing with this.
|
||||
*
|
||||
* @author Nicki Watt
|
||||
* @since 24-09-2013
|
||||
*/
|
||||
public class CypherBasedLabelingNodeTypeRepresentationStrategy implements NodeTypeRepresentationStrategy {
|
||||
|
||||
// option A : store type in entity
|
||||
// public static final String TYPE_PROPERTY_NAME = "__type__";
|
||||
// option B : add special type label
|
||||
public static final String TYPE_LABEL_PREFIX = "__TYPE__";
|
||||
protected GraphDatabase graphDb;
|
||||
protected final Class<Node> clazz;
|
||||
|
||||
public CypherBasedLabelingNodeTypeRepresentationStrategy(GraphDatabase graphDb) {
|
||||
this.graphDb = graphDb;
|
||||
this.clazz = Node.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTypeTo(Node state, StoredEntityType type) {
|
||||
throw new RuntimeException("TODO");
|
||||
}
|
||||
|
||||
private void addLabel(Node state, StoredEntityType type, boolean isPrimary) {
|
||||
throw new RuntimeException("TODO");
|
||||
}
|
||||
|
||||
@Override
|
||||
public <U> ClosableIterable<Node> findAll(StoredEntityType type) {
|
||||
throw new RuntimeException("TODO");
|
||||
}
|
||||
|
||||
@Override
|
||||
public long count(StoredEntityType type) {
|
||||
throw new RuntimeException("TODO");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readAliasFrom(Node state) {
|
||||
throw new RuntimeException("TODO");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preEntityRemoval(Node state) {
|
||||
// don't think we need to do anything here!
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@ package org.springframework.data.neo4j.support.typerepresentation;
|
||||
import org.neo4j.graphdb.*;
|
||||
import org.neo4j.graphdb.index.Index;
|
||||
import org.springframework.data.neo4j.core.GraphDatabase;
|
||||
import org.springframework.data.neo4j.core.GraphDatabaseGlobalOperations;
|
||||
import org.springframework.data.neo4j.core.NodeTypeRepresentationStrategy;
|
||||
import org.springframework.data.neo4j.core.RelationshipTypeRepresentationStrategy;
|
||||
import org.springframework.data.neo4j.support.index.IndexProvider;
|
||||
@@ -53,12 +54,24 @@ public class TypeRepresentationStrategyFactory {
|
||||
try {
|
||||
if (isAlreadyIndexed(graphDatabaseService)) return Strategy.Indexed;
|
||||
if (isAlreadySubRef(graphDatabaseService)) return Strategy.SubRef;
|
||||
if (isAlreadyLabeled(graphDatabaseService)) return Strategy.Labeled;
|
||||
return Strategy.Indexed;
|
||||
} finally {
|
||||
tx.success();tx.finish();
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isAlreadyLabeled(GraphDatabase graphDatabaseService) {
|
||||
GraphDatabaseGlobalOperations globalOps = graphDatabaseService.getGlobalGraphOperations();
|
||||
try {
|
||||
return globalOps.getAllLabels().iterator().hasNext();
|
||||
} catch (UnsupportedOperationException e) {
|
||||
// Currently the REST DB does not support global ops
|
||||
// TODO : Look to change REST project to support it
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isAlreadyIndexed(GraphDatabase graphDatabaseService) {
|
||||
try {
|
||||
final Index<PropertyContainer> index = graphDatabaseService.getIndex(IndexingNodeTypeRepresentationStrategy.INDEX_NAME);
|
||||
@@ -105,6 +118,17 @@ public class TypeRepresentationStrategyFactory {
|
||||
return new NoopRelationshipTypeRepresentationStrategy();
|
||||
}
|
||||
},
|
||||
Labeled {
|
||||
@Override
|
||||
public NodeTypeRepresentationStrategy getNodeTypeRepresentationStrategy(GraphDatabase graphDatabaseService, IndexProvider indexProvider) {
|
||||
return new CoreAPIBasedLabelingNodeTypeRepresentationStrategy(graphDatabaseService);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RelationshipTypeRepresentationStrategy getRelationshipTypeRepresentationStrategy(GraphDatabase graphDatabaseService, IndexProvider indexProvider) {
|
||||
return new NoopRelationshipTypeRepresentationStrategy();
|
||||
}
|
||||
},
|
||||
Indexed {
|
||||
@Override
|
||||
public NodeTypeRepresentationStrategy getNodeTypeRepresentationStrategy(GraphDatabase graphDatabaseService, IndexProvider indexProvider) {
|
||||
|
||||
Reference in New Issue
Block a user