Skip to content

Commit 17d2c17

Browse files
committed
DocumentRelationBuilderHasTypeArrayKey
1 parent 6b8456e commit 17d2c17

2 files changed

Lines changed: 469 additions & 0 deletions

File tree

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
/**
2+
* Copyright (c) 2016 LARUS Business Automation [http://www.larus-ba.it]
3+
* <p>
4+
* This file is part of the "LARUS Integration Framework for Neo4j".
5+
* <p>
6+
* The "LARUS Integration Framework for Neo4j" is licensed
7+
* under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
* <p>
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
* <p>
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
20+
package org.neo4j.helpers.json.document.impl;
21+
22+
import java.util.HashSet;
23+
import java.util.List;
24+
import java.util.Set;
25+
import java.util.stream.Collectors;
26+
import java.util.stream.StreamSupport;
27+
28+
import org.apache.commons.lang3.ArrayUtils;
29+
import org.neo4j.graphdb.Direction;
30+
import org.neo4j.graphdb.GraphDatabaseService;
31+
import org.neo4j.graphdb.Node;
32+
import org.neo4j.graphdb.Relationship;
33+
import org.neo4j.graphdb.RelationshipType;
34+
import org.neo4j.graphdb.Result;
35+
import org.neo4j.helpers.json.document.DocumentRelationBuilder;
36+
import org.neo4j.helpers.json.document.context.DocumentRelationContext;
37+
import org.neo4j.logging.Log;
38+
39+
/**
40+
* Build relationship with name "HAS_"+the type of destination node
41+
* ES: HAS_TRACKS
42+
* @author Omar Rampado
43+
* FIXME merge code with DocumentRelationBuilderTypeArrayKey
44+
*/
45+
public class DocumentRelationBuilderHasTypeArrayKey implements DocumentRelationBuilder {
46+
47+
private static final String DOC_KEYS = "docKeys";
48+
49+
private GraphDatabaseService db;
50+
51+
private Log log;
52+
53+
/**
54+
* @param db the db to set
55+
*/
56+
public void setDb(GraphDatabaseService db) {
57+
this.db = db;
58+
}
59+
60+
/**
61+
* @param log the log to set
62+
*/
63+
public void setLog(Log log) {
64+
this.log = log;
65+
}
66+
67+
/* (non-Javadoc)
68+
* @see org.neo4j.helpers.json.document.DocumentRelationBuilder#buildRelation(org.neo4j.graphdb.Node, org.neo4j.graphdb.Node, org.neo4j.helpers.json.document.DocumentRelationContext)
69+
*/
70+
@Override
71+
public Relationship buildRelation(Node parent, Node child, DocumentRelationContext context) {
72+
String childType = (String) child.getProperty("type");
73+
String relationName = "HAS_"+childType.toUpperCase();
74+
75+
RelationshipType type = RelationshipType.withName( relationName );
76+
77+
//check if already exists
78+
Iterable<Relationship> relationships = child.getRelationships(Direction.INCOMING,type);
79+
80+
Relationship relationship;
81+
82+
//find only relation between parent and child node
83+
List<Relationship> rels = StreamSupport.stream(relationships.spliterator(), false)
84+
.filter(rel -> rel.getStartNode().getId() == parent.getId())
85+
.collect(Collectors.toList());
86+
87+
if(rels.isEmpty())
88+
{
89+
relationship = parent.createRelationshipTo(child, type);
90+
if(log.isDebugEnabled())
91+
log.debug("Create new Relation "+relationship);
92+
}else
93+
{
94+
relationship = rels.get(0);
95+
if(log.isDebugEnabled())
96+
log.debug("Update Relation "+relationship);
97+
}
98+
99+
//manage array of keys
100+
101+
String[] keys = new String[0];
102+
103+
//create property if doesn't exists (new relation)
104+
if(relationship.getAllProperties().containsKey(DOC_KEYS))
105+
{
106+
keys = (String[]) relationship.getProperty(DOC_KEYS);
107+
}
108+
109+
//set document key into property
110+
String documentKey = context.getDocumentKey();
111+
if(! ArrayUtils.contains(keys, documentKey))
112+
{
113+
keys = ArrayUtils.add(keys, documentKey);
114+
relationship.setProperty(DOC_KEYS, keys);
115+
}
116+
117+
118+
return relationship;
119+
}
120+
121+
/* (non-Javadoc)
122+
* @see org.neo4j.helpers.json.document.DocumentRelationBuilder#deleteRelations(org.neo4j.helpers.json.document.DocumentRelationContext)
123+
*/
124+
@Override
125+
public Set<Node> deleteRelations(DocumentRelationContext context) {
126+
Set<Node> orphans = new HashSet<>();
127+
128+
Result result = db.execute("MATCH (p)-[r]->(c) WHERE \""+context.getDocumentKey()+"\" IN r."+DOC_KEYS+" RETURN r");
129+
result.forEachRemaining((res)->{
130+
Relationship rel = (Relationship) res.get("r");
131+
String[] keys = (String[]) rel.getProperty(DOC_KEYS);
132+
if(keys.length == 1)
133+
{
134+
Node parent = rel.getStartNode();
135+
Node child = rel.getEndNode();
136+
rel.delete();
137+
if(log.isDebugEnabled())
138+
{
139+
log.debug("Delete relation "+rel);
140+
}
141+
142+
updateOrphans(orphans, parent);
143+
updateOrphans(orphans, child);
144+
145+
}else
146+
{
147+
//if other document pass through this relationship
148+
keys = ArrayUtils.removeElement(keys, context.getDocumentKey());
149+
rel.setProperty(DOC_KEYS, keys);
150+
}
151+
});
152+
153+
return orphans;
154+
}
155+
156+
/**
157+
* Update orphans collection with node
158+
* @param orphans
159+
* @param node
160+
* @return true if node is orphan
161+
*/
162+
private boolean updateOrphans(Set<Node> orphans, Node node)
163+
{
164+
boolean orphan = ! node.getRelationships().iterator().hasNext();
165+
166+
if(orphan)
167+
{
168+
orphans.add(node);
169+
}
170+
171+
return orphan;
172+
}
173+
174+
}

0 commit comments

Comments
 (0)