1 package de.dlr.shepard.context.collection.services;
2
3 import de.dlr.shepard.auth.permission.services.PermissionsService;
4 import de.dlr.shepard.auth.security.AuthenticationContext;
5 import de.dlr.shepard.auth.users.entities.User;
6 import de.dlr.shepard.auth.users.services.UserService;
7 import de.dlr.shepard.common.exceptions.InvalidAuthException;
8 import de.dlr.shepard.common.exceptions.InvalidBodyException;
9 import de.dlr.shepard.common.exceptions.InvalidPathException;
10 import de.dlr.shepard.common.exceptions.InvalidRequestException;
11 import de.dlr.shepard.common.util.DateHelper;
12 import de.dlr.shepard.common.util.QueryParamHelper;
13 import de.dlr.shepard.context.collection.daos.DataObjectDAO;
14 import de.dlr.shepard.context.collection.entities.Collection;
15 import de.dlr.shepard.context.collection.entities.DataObject;
16 import de.dlr.shepard.context.collection.io.DataObjectIO;
17 import de.dlr.shepard.context.references.dataobject.daos.DataObjectReferenceDAO;
18 import de.dlr.shepard.context.references.dataobject.entities.DataObjectReference;
19 import de.dlr.shepard.context.version.services.VersionService;
20 import io.quarkus.logging.Log;
21 import jakarta.enterprise.context.RequestScoped;
22 import jakarta.inject.Inject;
23 import java.util.ArrayList;
24 import java.util.Date;
25 import java.util.HashSet;
26 import java.util.List;
27 import java.util.UUID;
28
29 @RequestScoped
30 public class DataObjectService {
31
32 @Inject
33 DataObjectDAO dataObjectDAO;
34
35 @Inject
36 DataObjectReferenceDAO dataObjectReferenceDAO;
37
38 @Inject
39 UserService userService;
40
41 @Inject
42 DateHelper dateHelper;
43
44 @Inject
45 VersionService versionService;
46
47 @Inject
48 CollectionService collectionService;
49
50 @Inject
51 PermissionsService permissionsService;
52
53 @Inject
54 AuthenticationContext authenticationContext;
55
56
57
58
59
60
61
62
63
64
65 public DataObject createDataObject(long collectionShepardId, DataObjectIO dataObject) {
66 Collection collection = collectionService.getCollection(collectionShepardId);
67 collectionService.assertIsAllowedToEditCollection(collectionShepardId);
68
69 User user = userService.getCurrentUser();
70 DataObject parent = findRelatedDataObject(collection.getShepardId(), dataObject.getParentId(), null);
71 List<DataObject> predecessors = findRelatedDataObjects(
72 collection.getShepardId(),
73 dataObject.getPredecessorIds(),
74 null
75 );
76 DataObject toCreate = new DataObject();
77 toCreate.setAttributes(dataObject.getAttributes());
78 toCreate.setDescription(dataObject.getDescription());
79 toCreate.setName(dataObject.getName());
80 toCreate.setCollection(collection);
81 toCreate.setParent(parent);
82 toCreate.setPredecessors(predecessors);
83 toCreate.setCreatedAt(dateHelper.getDate());
84 toCreate.setCreatedBy(user);
85 DataObject created = dataObjectDAO.createOrUpdate(toCreate);
86 created.setShepardId(created.getId());
87 created = dataObjectDAO.createOrUpdate(created);
88 versionService.attachToVersionOfVersionableEntityAndReturnVersion(collectionShepardId, created.getShepardId());
89 return created;
90 }
91
92
93
94
95
96
97
98
99
100
101 public DataObject getDataObject(long shepardId) {
102 return getDataObject(shepardId, null);
103 }
104
105
106
107
108
109
110
111
112
113
114
115
116 public DataObject getDataObject(long shepardId, UUID versionUID) {
117 DataObject ret;
118 String errorMsg;
119 if (versionUID == null) {
120 ret = dataObjectDAO.findByShepardId(shepardId);
121 errorMsg = String.format("DataObject with id %s is null or deleted", shepardId);
122 } else {
123 ret = dataObjectDAO.findByShepardId(shepardId, versionUID);
124 errorMsg = String.format("DataObject with id %s and versionUID %s is null or deleted", shepardId, versionUID);
125 }
126 if (ret == null || ret.isDeleted()) {
127 Log.error(errorMsg);
128 throw new InvalidPathException("ID ERROR - " + errorMsg);
129 }
130
131 collectionService.assertIsAllowedToReadCollection(ret.getCollection().getShepardId());
132 cutDeleted(ret);
133
134 HashSet<Long> incomingReferencesIdList = new HashSet<Long>();
135 for (DataObjectReference reference : ret.getIncoming()) incomingReferencesIdList.add(reference.getId());
136 List<DataObjectReference> completeIncomingReferences = new ArrayList<DataObjectReference>();
137 for (Long id : incomingReferencesIdList) completeIncomingReferences.add(dataObjectReferenceDAO.findByNeo4jId(id));
138
139 HashSet<Long> childrenIdList = new HashSet<Long>();
140 for (DataObject child : ret.getChildren()) childrenIdList.add(child.getId());
141 List<DataObject> completeChildren = new ArrayList<DataObject>();
142 for (Long id : childrenIdList) completeChildren.add(dataObjectDAO.findByNeo4jId(id));
143
144 HashSet<Long> predecessorsIdList = new HashSet<Long>();
145 for (DataObject predecessor : ret.getPredecessors()) predecessorsIdList.add(predecessor.getId());
146 List<DataObject> completePredecessors = new ArrayList<DataObject>();
147 for (Long id : predecessorsIdList) completePredecessors.add(dataObjectDAO.findByNeo4jId(id));
148
149 HashSet<Long> successorsIdList = new HashSet<Long>();
150 for (DataObject successor : ret.getSuccessors()) successorsIdList.add(successor.getId());
151 List<DataObject> completeSuccessors = new ArrayList<DataObject>();
152 for (Long id : successorsIdList) completeSuccessors.add(dataObjectDAO.findByNeo4jId(id));
153
154 ret.setChildren(completeChildren);
155 ret.setIncoming(completeIncomingReferences);
156 ret.setPredecessors(completePredecessors);
157 ret.setSuccessors(completeSuccessors);
158 if (ret.getParent() != null) ret.setParent(dataObjectDAO.findByNeo4jId(ret.getParent().getId()));
159 return ret;
160 }
161
162
163
164
165
166
167
168
169
170
171
172
173 public DataObject getDataObject(long collectionShepardId, long shepardId) {
174 return getDataObject(collectionShepardId, shepardId, null);
175 }
176
177
178
179
180
181
182
183
184
185
186
187
188
189 public DataObject getDataObject(long shepardCollectionId, long shepardId, UUID versionUID) {
190 collectionService.getCollection(shepardCollectionId);
191
192 DataObject dataObject;
193 try {
194
195
196
197 dataObject = getDataObject(shepardId, versionUID);
198 } catch (InvalidAuthException ex) {
199 throw new InvalidPathException("ID ERROR - There is no association between collection and dataObject");
200 }
201
202 if (!dataObject.getCollection().getShepardId().equals(shepardCollectionId)) {
203 throw new InvalidPathException("ID ERROR - There is no association between collection and dataObject");
204 }
205 return dataObject;
206 }
207
208
209
210
211
212
213
214
215
216
217
218
219
220 public List<DataObject> getAllDataObjectsByShepardIds(
221 long collectionShepardId,
222 QueryParamHelper paramsWithShepardIds,
223 UUID versionUID
224 ) {
225 collectionService.getCollection(collectionShepardId, versionUID);
226
227 var unfiltered = dataObjectDAO.findByCollectionByShepardIds(collectionShepardId, paramsWithShepardIds, versionUID);
228 var dataObjects = unfiltered.stream().map(this::cutDeleted).toList();
229 return dataObjects;
230 }
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246 public DataObject updateDataObject(long collectionShepardId, long dataObjectShepardId, DataObjectIO dataObject) {
247 DataObject old = getDataObject(collectionShepardId, dataObjectShepardId);
248 collectionService.assertIsAllowedToEditCollection(collectionShepardId);
249
250 User user = userService.getCurrentUser();
251
252 if (old.getParent() != null) {
253 dataObjectDAO.deleteHasChildRelation(old.getParent().getShepardId(), old.getShepardId());
254 }
255 if (old.getPredecessors() != null) {
256 old
257 .getPredecessors()
258 .forEach(predecessor -> {
259 dataObjectDAO.deleteHasSuccessorRelation(predecessor.getShepardId(), old.getShepardId());
260 });
261 }
262
263 DataObject newParent = findRelatedDataObject(
264 old.getCollection().getShepardId(),
265 dataObject.getParentId(),
266 dataObjectShepardId
267 );
268 List<DataObject> newPredecessors = findRelatedDataObjects(
269 old.getCollection().getShepardId(),
270 dataObject.getPredecessorIds(),
271 dataObjectShepardId
272 );
273
274 old.setShepardId(old.getShepardId());
275 old.setName(dataObject.getName());
276 old.setDescription(dataObject.getDescription());
277 old.setAttributes(dataObject.getAttributes());
278 old.setParent(newParent);
279 old.setPredecessors(newPredecessors);
280 old.setUpdatedAt(dateHelper.getDate());
281 old.setUpdatedBy(user);
282
283 DataObject updated = dataObjectDAO.createOrUpdate(old);
284 cutDeleted(updated);
285 return updated;
286 }
287
288
289
290
291
292
293
294
295
296
297
298
299
300 public void deleteDataObject(long collectionShepardId, long dataObjectShepardId) {
301 getDataObject(collectionShepardId, dataObjectShepardId);
302 collectionService.assertIsAllowedToEditCollection(collectionShepardId);
303
304 Date date = dateHelper.getDate();
305 User user = userService.getCurrentUser();
306
307 if (!dataObjectDAO.deleteDataObjectByShepardId(dataObjectShepardId, user, date)) {
308 throw new InvalidRequestException(
309 String.format("Could not delete DataObject with ShepardId %s", dataObjectShepardId)
310 );
311 }
312 }
313
314 private DataObject cutDeleted(DataObject dataObject) {
315 var incoming = dataObject.getIncoming().stream().filter(i -> !i.isDeleted()).toList();
316 dataObject.setIncoming(incoming);
317 if (dataObject.getParent() != null && dataObject.getParent().isDeleted()) {
318 dataObject.setParent(null);
319 }
320 var children = dataObject.getChildren().stream().filter(s -> !s.isDeleted()).toList();
321 dataObject.setChildren(children);
322 var predecessors = dataObject.getPredecessors().stream().filter(s -> !s.isDeleted()).toList();
323 dataObject.setPredecessors(predecessors);
324 var successors = dataObject.getSuccessors().stream().filter(s -> !s.isDeleted()).toList();
325 dataObject.setSuccessors(successors);
326 var references = dataObject.getReferences().stream().filter(ref -> !ref.isDeleted()).toList();
327 dataObject.setReferences(references);
328 return dataObject;
329 }
330
331 private List<DataObject> findRelatedDataObjects(
332 long collectionShepardId,
333 long[] referencedShepardIds,
334 Long dataObjectShepardId
335 ) {
336 if (referencedShepardIds == null) return new ArrayList<>();
337
338 var result = new ArrayList<DataObject>(referencedShepardIds.length);
339
340
341
342
343
344 for (var shepardId : referencedShepardIds) {
345 result.add(findRelatedDataObject(collectionShepardId, shepardId, dataObjectShepardId));
346 }
347 return result;
348 }
349
350 private DataObject findRelatedDataObject(
351 long collectionShepardId,
352 Long referencedShepardId,
353 Long dataObjectShepardId
354 ) {
355 if (referencedShepardId == null) return null;
356 else if (referencedShepardId.equals(dataObjectShepardId)) throw new InvalidBodyException(
357 "Self references are not allowed."
358 );
359
360 var dataObject = dataObjectDAO.findByShepardId(referencedShepardId);
361 if (dataObject == null || dataObject.isDeleted()) throw new InvalidBodyException(
362 String.format("The DataObject with id %d could not be found.", referencedShepardId)
363 );
364
365
366 if (!dataObject.getCollection().getShepardId().equals(collectionShepardId)) throw new InvalidBodyException(
367 "Related data objects must belong to the same collection as the new data object"
368 );
369
370 return dataObject;
371 }
372
373
374
375
376 public void clearSession() {
377 dataObjectDAO.clearSession();
378 }
379 }