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 }