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.events;
21
22 import com.tinkerpop.blueprints.Direction;
23 import com.tinkerpop.blueprints.Vertex;
24 import com.tinkerpop.frames.Adjacency;
25 import com.tinkerpop.frames.Property;
26 import com.tinkerpop.frames.modules.javahandler.JavaHandler;
27 import com.tinkerpop.frames.modules.javahandler.JavaHandlerContext;
28 import com.tinkerpop.gremlin.java.GremlinPipeline;
29 import eu.ehri.project.definitions.Entities;
30 import eu.ehri.project.definitions.EventTypes;
31 import eu.ehri.project.definitions.Ontology;
32 import eu.ehri.project.models.EntityClass;
33 import eu.ehri.project.models.annotations.EntityType;
34 import eu.ehri.project.models.annotations.Fetch;
35 import eu.ehri.project.models.annotations.Mandatory;
36 import eu.ehri.project.models.annotations.Meta;
37 import eu.ehri.project.models.base.Accessible;
38 import eu.ehri.project.models.base.Actioner;
39 import eu.ehri.project.models.base.Entity;
40 import eu.ehri.project.models.base.ItemHolder;
41 import eu.ehri.project.models.utils.JavaHandlerUtils;
42
43
44
45
46
47 @EntityType(EntityClass.SYSTEM_EVENT)
48 public interface SystemEvent extends Accessible {
49
50 @Meta(ItemHolder.CHILD_COUNT)
51 @JavaHandler
52 int subjectCount();
53
54
55
56
57
58
59 @Mandatory
60 @Property(Ontology.EVENT_TIMESTAMP)
61 String getTimestamp();
62
63
64
65
66
67
68 @Mandatory
69 @Property(Ontology.EVENT_TYPE)
70 EventTypes getEventType();
71
72
73
74
75
76
77 @Property(Ontology.EVENT_LOG_MESSAGE)
78 String getLogMessage();
79
80
81
82
83
84
85 @Fetch(value = Ontology.EVENT_HAS_ACTIONER, numLevels = 0)
86 @JavaHandler
87 Actioner getActioner();
88
89
90
91
92
93
94 @JavaHandler
95 Iterable<Accessible> getSubjects();
96
97
98
99
100
101
102
103 @Fetch(value = Ontology.VERSION_HAS_EVENT, ifLevel = 0)
104 @Adjacency(label = Ontology.VERSION_HAS_EVENT, direction = Direction.IN)
105 Iterable<Version> getPriorVersions();
106
107
108
109
110
111
112
113 @Fetch(value = Ontology.EVENT_HAS_FIRST_SUBJECT, ifLevel = 0)
114 @JavaHandler
115 Accessible getFirstSubject();
116
117
118
119
120
121
122 @Adjacency(label = Ontology.ACTIONER_HAS_LIFECYCLE_ACTION)
123 SystemEvent getPriorEvent();
124
125
126
127
128
129
130
131 @Fetch(value = Ontology.EVENT_HAS_SCOPE, ifLevel = 0)
132 @Adjacency(label = Ontology.EVENT_HAS_SCOPE, direction = Direction.OUT)
133 Entity getEventScope();
134
135
136
137
138
139
140 @Adjacency(label = Ontology.EVENT_HAS_SCOPE, direction = Direction.OUT)
141 void setEventScope(Entity frame);
142
143
144
145
146 abstract class Impl implements JavaHandlerContext<Vertex>, SystemEvent {
147
148 @Override
149 public int subjectCount() {
150 return Math.toIntExact(gremlin().inE(Ontology.ENTITY_HAS_EVENT).count());
151 }
152
153 @Override
154 public Iterable<Accessible> getSubjects() {
155 return frameVertices(gremlin().in(Ontology.ENTITY_HAS_EVENT)
156 .as("n").in(Ontology.ENTITY_HAS_LIFECYCLE_EVENT)
157 .loop("n", JavaHandlerUtils.noopLoopFunc,
158 vertexLoopBundle -> isValidEndpoint(vertexLoopBundle.getObject(),
159 Ontology.ENTITY_HAS_LIFECYCLE_EVENT)));
160 }
161
162 @Override
163 public Accessible getFirstSubject() {
164
165
166
167 GremlinPipeline<Vertex, Vertex> subjects = gremlin().in(Ontology.ENTITY_HAS_EVENT)
168 .as("n").in(Ontology.ENTITY_HAS_LIFECYCLE_EVENT)
169 .loop("n", JavaHandlerUtils.noopLoopFunc,
170 vertexLoopBundle -> isValidEndpoint(vertexLoopBundle.getObject(),
171 Ontology.ENTITY_HAS_LIFECYCLE_EVENT));
172 return (Accessible) (subjects.iterator().hasNext()
173 ? frame(subjects.iterator().next())
174 : null);
175 }
176
177 @Override
178 public Actioner getActioner() {
179 GremlinPipeline<Vertex, Vertex> actioners = gremlin().in(Ontology.ACTION_HAS_EVENT)
180 .as("n").in(Ontology.ACTIONER_HAS_LIFECYCLE_ACTION)
181 .loop("n", JavaHandlerUtils.noopLoopFunc,
182 vertexLoopBundle -> isValidEndpoint(vertexLoopBundle.getObject(),
183 Ontology.ACTIONER_HAS_LIFECYCLE_ACTION));
184 return (Actioner) (actioners.iterator().hasNext()
185 ? frame(actioners.iterator().next())
186 : null);
187 }
188
189 private boolean isValidEndpoint(Vertex vertex, String linkRel) {
190
191
192
193 if (vertex.getEdges(Direction.IN, linkRel).iterator().hasNext()) {
194 return false;
195 } else {
196 String type = vertex.getProperty(EntityType.TYPE_KEY);
197 return type != null && !type.equals(Entities.EVENT_LINK);
198 }
199 }
200 }
201 }