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.utils.JavaHandlerUtils;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37
38
39
40
41
42 @EntityType(EntityClass.DOCUMENTARY_UNIT)
43 public interface DocumentaryUnit extends AbstractUnit {
44
45 Logger logger = LoggerFactory.getLogger(DocumentaryUnit.class);
46
47
48
49
50
51
52 @Fetch(Ontology.DOC_HELD_BY_REPOSITORY)
53 @JavaHandler
54 Repository getRepository();
55
56
57
58
59
60
61
62 @Adjacency(label = Ontology.DOC_HELD_BY_REPOSITORY, direction = Direction.OUT)
63 Repository getRepositoryIfTopLevel();
64
65
66
67
68
69
70 @JavaHandler
71 void setRepository(Repository repository);
72
73
74
75
76
77
78 @Fetch(Ontology.DOC_IS_CHILD_OF)
79 @Adjacency(label = Ontology.DOC_IS_CHILD_OF)
80 DocumentaryUnit getParent();
81
82
83
84
85
86
87 @JavaHandler
88 void addChild(DocumentaryUnit child);
89
90
91
92
93
94
95 @JavaHandler
96 Iterable<DocumentaryUnit> getAncestors();
97
98
99
100
101
102
103
104 @JavaHandler
105 Iterable<DocumentaryUnit> getAncestorsAndSelf();
106
107
108
109
110
111
112 @JavaHandler
113 Iterable<VirtualUnit> getVirtualCollections();
114
115
116
117
118
119
120
121 @Meta(CHILD_COUNT)
122 @JavaHandler
123 int getChildCount();
124
125
126
127
128
129
130 @JavaHandler
131 Iterable<DocumentaryUnit> getChildren();
132
133
134
135
136
137
138
139 @JavaHandler
140 Iterable<DocumentaryUnit> getAllChildren();
141
142
143
144
145
146
147 @Adjacency(label = Ontology.DESCRIPTION_FOR_ENTITY, direction = Direction.IN)
148 Iterable<DocumentaryUnitDescription> getDocumentDescriptions();
149
150
151
152
153 abstract class Impl implements JavaHandlerContext<Vertex>, DocumentaryUnit {
154
155 public int getChildCount() {
156 return Math.toIntExact(gremlin().inE(Ontology.DOC_IS_CHILD_OF).count());
157 }
158
159 public Iterable<DocumentaryUnit> getChildren() {
160 return frameVertices(gremlin().in(Ontology.DOC_IS_CHILD_OF));
161 }
162
163 public void addChild(DocumentaryUnit child) {
164 JavaHandlerUtils
165 .addSingleRelationship(child.asVertex(), it(), Ontology.DOC_IS_CHILD_OF);
166 }
167
168 public Iterable<DocumentaryUnit> getAllChildren() {
169 Pipeline<Vertex, Vertex> otherPipe = gremlin().as("n").in(Ontology.DOC_IS_CHILD_OF)
170 .loop("n", JavaHandlerUtils.noopLoopFunc, JavaHandlerUtils.noopLoopFunc);
171
172 return frameVertices(gremlin().in(Ontology.DOC_IS_CHILD_OF).cast(Vertex.class).copySplit(gremlin(), otherPipe)
173 .fairMerge().cast(Vertex.class));
174 }
175
176
177 public void setRepository(Repository repository) {
178
179
180 repository.addTopLevelDocumentaryUnit(frame(it(), DocumentaryUnit.class));
181 }
182
183 public Repository getRepository() {
184 Pipeline<Vertex, Vertex> otherPipe = gremlin().as("n").out(Ontology.DOC_IS_CHILD_OF)
185 .loop("n", JavaHandlerUtils.defaultMaxLoops,
186 vertexLoopBundle -> !vertexLoopBundle.getObject().getVertices(Direction.OUT,
187 Ontology.DOC_IS_CHILD_OF).iterator().hasNext());
188
189 GremlinPipeline<Vertex, Vertex> out = gremlin().cast(Vertex.class).copySplit(gremlin(), otherPipe)
190 .exhaustMerge().out(Ontology.DOC_HELD_BY_REPOSITORY);
191
192 return (Repository) (out.hasNext() ? frame(out.next()) : null);
193 }
194
195 public Iterable<DocumentaryUnit> getAncestors() {
196 return frameVertices(gremlin().as("n")
197 .out(Ontology.DOC_IS_CHILD_OF)
198 .loop("n", JavaHandlerUtils.defaultMaxLoops, JavaHandlerUtils.noopLoopFunc));
199 }
200
201 public Iterable<DocumentaryUnit> getAncestorsAndSelf() {
202 GremlinPipeline<Vertex, Vertex> ancestors = gremlin()
203 .as("n")
204 .out(Ontology.DOC_IS_CHILD_OF)
205 .loop("n", JavaHandlerUtils.defaultMaxLoops, JavaHandlerUtils.noopLoopFunc);
206
207 GremlinPipeline<Vertex, Vertex> all = gremlin().cast(Vertex.class)
208 .copySplit(gremlin(), ancestors).exhaustMerge().cast(Vertex.class);
209
210 return frameVertices(all);
211 }
212
213 public Iterable<VirtualUnit> getVirtualCollections() {
214 GremlinPipeline<Vertex, ?> ancestors = gremlin()
215 .as("n")
216 .out(Ontology.DOC_IS_CHILD_OF)
217 .loop("n", JavaHandlerUtils.defaultMaxLoops, JavaHandlerUtils.noopLoopFunc);
218
219 GremlinPipeline<Vertex, ?> ancestorsAndSelf = gremlin()
220 .cast(Vertex.class)
221 .copySplit(gremlin(), ancestors)
222 .exhaustMerge();
223
224
225 Pipeline<Vertex, Vertex> all = ancestorsAndSelf
226 .in(Ontology.VC_INCLUDES_UNIT)
227 .as("n").out(Ontology.VC_IS_PART_OF)
228 .loop("n", JavaHandlerUtils.defaultMaxLoops, vertexLoopBundle ->
229 (!vertexLoopBundle.getObject()
230 .getEdges(Direction.OUT, Ontology.VC_IS_PART_OF)
231 .iterator().hasNext())
232 && EntityClass.VIRTUAL_UNIT
233 .getName()
234 .equals(vertexLoopBundle.getObject()
235 .getProperty(EntityType.TYPE_KEY)))
236 .cast(Vertex.class);
237
238 return frameVertices(all);
239 }
240 }
241 }