1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package eu.ehri.project.models;
21
22 import com.tinkerpop.blueprints.Direction;
23 import com.tinkerpop.blueprints.Vertex;
24 import com.tinkerpop.frames.Adjacency;
25 import com.tinkerpop.frames.modules.javahandler.JavaHandler;
26 import com.tinkerpop.frames.modules.javahandler.JavaHandlerContext;
27 import com.tinkerpop.gremlin.java.GremlinPipeline;
28 import com.tinkerpop.pipes.util.Pipeline;
29 import eu.ehri.project.definitions.Ontology;
30 import eu.ehri.project.models.annotations.EntityType;
31 import eu.ehri.project.models.annotations.Fetch;
32 import eu.ehri.project.models.annotations.Meta;
33 import eu.ehri.project.models.base.AbstractUnit;
34 import eu.ehri.project.models.base.Accessor;
35 import eu.ehri.project.models.utils.JavaHandlerUtils;
36
37 import static eu.ehri.project.models.utils.JavaHandlerUtils.addSingleRelationship;
38 import static eu.ehri.project.models.utils.JavaHandlerUtils.addUniqueRelationship;
39 import static eu.ehri.project.models.utils.JavaHandlerUtils.removeAllRelationships;
40
41
42
43
44
45
46
47
48
49
50
51
52 @EntityType(EntityClass.VIRTUAL_UNIT)
53 public interface VirtualUnit extends AbstractUnit {
54
55 @Meta(CHILD_COUNT)
56 @JavaHandler
57 int getChildCount();
58
59 @Fetch(Ontology.VC_IS_PART_OF)
60 @Adjacency(label = Ontology.VC_IS_PART_OF)
61 VirtualUnit getParent();
62
63
64
65
66
67
68
69 @JavaHandler
70 boolean addChild(VirtualUnit child);
71
72
73
74
75
76
77
78 @JavaHandler
79 boolean removeChild(VirtualUnit child);
80
81
82
83
84 @JavaHandler
85 Iterable<VirtualUnit> getAncestors();
86
87
88
89
90
91
92 @JavaHandler
93 Iterable<VirtualUnit> getChildren();
94
95
96
97
98
99
100
101 @JavaHandler
102 Iterable<VirtualUnit> getAllChildren();
103
104
105
106
107
108
109 @Fetch(value = Ontology.VC_INCLUDES_UNIT, full = true)
110 @Adjacency(label = Ontology.VC_INCLUDES_UNIT, direction = Direction.OUT)
111 Iterable<DocumentaryUnit> getIncludedUnits();
112
113
114
115
116
117
118
119 @JavaHandler
120 Iterable<Repository> getRepositories();
121
122
123
124
125
126
127
128 @JavaHandler
129 boolean addIncludedUnit(DocumentaryUnit unit);
130
131
132
133
134
135
136 @JavaHandler
137 void removeIncludedUnit(DocumentaryUnit unit);
138
139
140
141
142
143
144 @Fetch(value = Ontology.VC_HAS_AUTHOR, numLevels = 0)
145 @Adjacency(label = Ontology.VC_HAS_AUTHOR, direction = Direction.OUT)
146 Accessor getAuthor();
147
148
149
150
151
152
153 @JavaHandler
154 void setAuthor(Accessor accessor);
155
156
157
158
159
160
161 @Adjacency(label = Ontology.DESCRIPTION_FOR_ENTITY, direction = Direction.IN)
162 Iterable<DocumentaryUnitDescription> getVirtualDescriptions();
163
164
165
166
167 abstract class Impl implements JavaHandlerContext<Vertex>, VirtualUnit {
168
169 @Override
170 public void setAuthor(Accessor accessor) {
171 addSingleRelationship(it(), accessor.asVertex(), Ontology.VC_HAS_AUTHOR);
172 }
173
174 @Override
175 public void removeIncludedUnit(DocumentaryUnit unit) {
176 removeAllRelationships(it(), unit.asVertex(), Ontology.VC_INCLUDES_UNIT);
177 }
178
179 @Override
180 public Iterable<VirtualUnit> getChildren() {
181 return frameVertices(gremlin().in(Ontology.VC_IS_PART_OF));
182 }
183
184 @Override
185 public boolean addChild(VirtualUnit child) {
186 if (child.asVertex().equals(it())) {
187
188 return false;
189 }
190 for (Vertex parent : traverseAncestors()) {
191 if (child.asVertex().equals(parent)) {
192
193 return false;
194 }
195 }
196
197 return addUniqueRelationship(child.asVertex(), it(), Ontology.VC_IS_PART_OF);
198 }
199
200 @Override
201 public boolean removeChild(VirtualUnit child) {
202 return removeAllRelationships(child.asVertex(), it(), Ontology.VC_IS_PART_OF);
203 }
204
205 private GremlinPipeline<Vertex, Vertex> traverseAncestors() {
206 return gremlin().as("n")
207 .out(Ontology.VC_IS_PART_OF)
208 .loop("n", JavaHandlerUtils.defaultMaxLoops, JavaHandlerUtils.noopLoopFunc);
209 }
210
211 @Override
212 public Iterable<VirtualUnit> getAllChildren() {
213 Pipeline<Vertex, Vertex> otherPipe = gremlin().as("n").in(Ontology.VC_IS_PART_OF)
214 .loop("n", JavaHandlerUtils.noopLoopFunc, JavaHandlerUtils.noopLoopFunc);
215
216 return frameVertices(gremlin().in(Ontology.VC_IS_PART_OF).cast(Vertex.class).copySplit(gremlin(), otherPipe)
217 .fairMerge().cast(Vertex.class));
218 }
219
220 @Override
221 public Iterable<VirtualUnit> getAncestors() {
222 return frameVertices(traverseAncestors());
223 }
224
225 @Override
226 public boolean addIncludedUnit(DocumentaryUnit unit) {
227 return addUniqueRelationship(it(), unit.asVertex(), Ontology.VC_INCLUDES_UNIT);
228 }
229
230 @Override
231 public int getChildCount() {
232 long incCount = gremlin().outE(Ontology.VC_INCLUDES_UNIT).count();
233 long vcCount = gremlin().inE(Ontology.VC_IS_PART_OF).count();
234 return Math.toIntExact(incCount + vcCount);
235 }
236 }
237 }