View Javadoc
1   package de.dlr.shepard.context.references.structureddata.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.context.collection.entities.DataObject;
13  import de.dlr.shepard.context.collection.services.CollectionService;
14  import de.dlr.shepard.context.collection.services.DataObjectService;
15  import de.dlr.shepard.context.references.IReferenceService;
16  import de.dlr.shepard.context.references.structureddata.daos.StructuredDataReferenceDAO;
17  import de.dlr.shepard.context.references.structureddata.entities.StructuredDataReference;
18  import de.dlr.shepard.context.references.structureddata.io.StructuredDataReferenceIO;
19  import de.dlr.shepard.context.version.services.VersionService;
20  import de.dlr.shepard.data.structureddata.daos.StructuredDataDAO;
21  import de.dlr.shepard.data.structureddata.entities.StructuredDataContainer;
22  import de.dlr.shepard.data.structureddata.entities.StructuredDataPayload;
23  import de.dlr.shepard.data.structureddata.services.StructuredDataContainerService;
24  import de.dlr.shepard.data.structureddata.services.StructuredDataService;
25  import io.quarkus.logging.Log;
26  import jakarta.enterprise.context.RequestScoped;
27  import jakarta.inject.Inject;
28  import jakarta.ws.rs.NotFoundException;
29  import java.util.ArrayList;
30  import java.util.List;
31  import java.util.UUID;
32  
33  @RequestScoped
34  public class StructuredDataReferenceService
35    implements IReferenceService<StructuredDataReference, StructuredDataReferenceIO> {
36  
37    @Inject
38    StructuredDataReferenceDAO structuredDataReferenceDAO;
39  
40    @Inject
41    DataObjectService dataObjectService;
42  
43    @Inject
44    StructuredDataDAO structuredDataDAO;
45  
46    @Inject
47    StructuredDataContainerService structuredDataContainerService;
48  
49    @Inject
50    VersionService versionService;
51  
52    @Inject
53    DateHelper dateHelper;
54  
55    @Inject
56    UserService userService;
57  
58    @Inject
59    StructuredDataService structuredDataService;
60  
61    @Inject
62    PermissionsService permissionsService;
63  
64    @Inject
65    AuthenticationContext authenticationContext;
66  
67    @Inject
68    CollectionService collectionService;
69  
70    @Override
71    public StructuredDataReference createReference(
72      long collectionShepardId,
73      long dataObjectShepardId,
74      StructuredDataReferenceIO structuredDataReference
75    ) {
76      DataObject dataObject = dataObjectService.getDataObject(collectionShepardId, dataObjectShepardId);
77      collectionService.assertIsAllowedToEditCollection(collectionShepardId);
78  
79      User user = userService.getCurrentUser();
80  
81      StructuredDataContainer container;
82      try {
83        container = structuredDataContainerService.getContainer(structuredDataReference.getStructuredDataContainerId());
84      } catch (InvalidPathException e) {
85        throw new InvalidBodyException(
86          "ID ERROR - Structured Data Container with id %s is null or deleted".formatted(
87              structuredDataReference.getStructuredDataContainerId()
88            )
89        );
90      }
91  
92      var toCreate = new StructuredDataReference();
93      toCreate.setCreatedAt(dateHelper.getDate());
94      toCreate.setCreatedBy(user);
95      toCreate.setDataObject(dataObject);
96      toCreate.setName(structuredDataReference.getName());
97      toCreate.setStructuredDataContainer(container);
98  
99      // Get existing structured data
100     for (var oid : structuredDataReference.getStructuredDataOids()) {
101       var structuredData = structuredDataDAO.find(container.getId(), oid);
102       if (structuredData != null) {
103         toCreate.addStructuredData(structuredData);
104       } else {
105         Log.warnf("Could not find structured data with oid: %s", oid);
106       }
107     }
108 
109     StructuredDataReference created = structuredDataReferenceDAO.createOrUpdate(toCreate);
110     created.setShepardId(created.getId());
111     created = structuredDataReferenceDAO.createOrUpdate(created);
112     versionService.attachToVersionOfVersionableEntityAndReturnVersion(dataObject.getId(), created.getId());
113     return created;
114   }
115 
116   /**
117    * Gets Structured Data Reference list for a given dataobject.
118    *
119    * @param collectionShepardId
120    * @param dataObjectShepardId
121    * @param versionUID the version UUID
122    * @return List<StructuredDataReference>
123    * @throws InvalidPathException If collection or dataobject cannot be found, or no association between dataobject and collection exists
124    * @throws InvalidAuthException If user has no read permissions on collection or dataobject specified by request path
125    */
126   @Override
127   public List<StructuredDataReference> getAllReferencesByDataObjectId(
128     long collectionShepardId,
129     long dataObjectShepardId,
130     UUID versionUID
131   ) {
132     dataObjectService.getDataObject(collectionShepardId, dataObjectShepardId, versionUID);
133 
134     List<StructuredDataReference> references = structuredDataReferenceDAO.findByDataObjectShepardId(
135       dataObjectShepardId
136     );
137     return references;
138   }
139 
140   /**
141    * Searches the neo4j database for a StructuredDataReference
142    *
143    * @param collectionShepardId
144    * @param dataObjectShepardId
145    * @param shepardId  identifies the searched StructuredDataReference
146    * @param versionUID the collections UUID
147    * @return CollectionReference
148    * @throws InvalidPathException If collection reference with Id does not exist or is deleted, or if collection or dataobject Id of path is not valid
149    * @throws InvalidAuthException If user has no read permissions on collection or dataobject specified by request path
150    */
151   @Override
152   public StructuredDataReference getReference(
153     long collectionShepardId,
154     long dataObjectShepardId,
155     long shepardId,
156     UUID versionUID
157   ) {
158     dataObjectService.getDataObject(collectionShepardId, dataObjectShepardId, versionUID);
159 
160     StructuredDataReference structuredDataReference = structuredDataReferenceDAO.findByShepardId(shepardId, versionUID);
161     if (structuredDataReference == null || structuredDataReference.isDeleted()) {
162       String errorMsg = "ID ERROR - Structured Data Reference with id %s is null or deleted".formatted(shepardId);
163       Log.errorf(errorMsg);
164       throw new InvalidPathException(errorMsg);
165     }
166 
167     if (
168       structuredDataReference.getDataObject() == null ||
169       !structuredDataReference.getDataObject().getShepardId().equals(dataObjectShepardId)
170     ) {
171       Log.error("ID ERROR - There is no association between dataObject and reference");
172       throw new InvalidPathException("ID ERROR - There is no association between dataObject and reference");
173     }
174 
175     return structuredDataReference;
176   }
177 
178   /**
179    * Deletes the Structured Data reference.
180    *
181    * @param collectionShepardId
182    * @param dataObjectShepardId
183    * @param dataObjectReferenceShepardId
184    * @throws InvalidPathException if collection or dataobject specified by their Ids are null or deleted
185    * @throws InvalidAuthException if user has no permissions to request the collection, which the reference is assigned to
186    * @throws InvalidBodyException If user has no permissions to access the referenced Structured Data or the referenced collection cannot be found
187    */
188   @Override
189   public void deleteReference(
190     long collectionShepardId,
191     long dataObjectShepardId,
192     long structuredDataReferenceShepardId
193   ) {
194     StructuredDataReference structuredDataReference = getReference(
195       collectionShepardId,
196       dataObjectShepardId,
197       structuredDataReferenceShepardId,
198       null
199     );
200     collectionService.assertIsAllowedToEditCollection(collectionShepardId);
201 
202     User user = userService.getCurrentUser();
203     structuredDataReference.setDeleted(true);
204     structuredDataReference.setUpdatedBy(user);
205     structuredDataReference.setUpdatedAt(dateHelper.getDate());
206     structuredDataReferenceDAO.createOrUpdate(structuredDataReference);
207   }
208 
209   /**
210    * Returns all structured data objects with payload.
211    *
212    * The payload attribute is null when the container is not accessible.
213    *
214    * @param structuredDataReferenceShepardId identifies the sd reference
215    * @return a list of StructuredDataPayload
216    */
217   public List<StructuredDataPayload> getAllPayloads(
218     long collectionShepardId,
219     long dataObjectShepardId,
220     long structuredDataReferenceShepardId
221   ) {
222     StructuredDataReference reference = getReference(
223       collectionShepardId,
224       dataObjectShepardId,
225       structuredDataReferenceShepardId,
226       null
227     );
228 
229     if (reference.getStructuredDataContainer() == null || reference.getStructuredDataContainer().isDeleted()) {
230       String errorMsg =
231         "StructuredData Container referenced by StructuredData Reference with Id %s is null or deleted".formatted(
232             structuredDataReferenceShepardId
233           );
234       Log.error(errorMsg);
235       throw new NotFoundException(errorMsg);
236     }
237 
238     try {
239       // check that referenced container is actually accessible
240       structuredDataContainerService.getContainer(reference.getStructuredDataContainer().getId());
241     } catch (InvalidPathException ex) {
242       throw new InvalidRequestException(ex.getMessage());
243     }
244 
245     String mongoId = reference.getStructuredDataContainer().getMongoId();
246     var result = new ArrayList<StructuredDataPayload>(reference.getStructuredDatas().size());
247     for (var structuredData : reference.getStructuredDatas()) {
248       try {
249         StructuredDataPayload payload = structuredDataService.getPayload(mongoId, structuredData.getOid());
250         result.add(payload);
251       } catch (NotFoundException ex) {
252         result.add(new StructuredDataPayload(structuredData, null));
253       }
254     }
255     return result;
256   }
257 
258   /**
259    * Returns a specific StructuredDataPayload
260    *
261    * @param structuredDataReferenceShepardId identifies the sd reference
262    * @param oid identifies the structured data
263    * @param username the current user
264    * @return StructuredDataPayload
265    * @throws InvalidRequestException when container is not accessible
266    * @throws InvalidAuthException when the user is not authorized to access the container
267    */
268   public StructuredDataPayload getPayload(
269     long collectionShepardId,
270     long dataObjectShepardId,
271     long structuredDataReferenceShepardId,
272     String oid
273   ) {
274     StructuredDataReference reference = getReference(
275       collectionShepardId,
276       dataObjectShepardId,
277       structuredDataReferenceShepardId,
278       null
279     );
280 
281     if (reference.getStructuredDataContainer() == null || reference.getStructuredDataContainer().isDeleted()) {
282       String errorMsg =
283         "Structured Data Container referenced by StructuredDataReference with id %s is deleted".formatted(
284             reference.getShepardId()
285           );
286       Log.errorf(errorMsg);
287       throw new InvalidRequestException(errorMsg);
288     }
289 
290     try {
291       structuredDataContainerService.getContainer(reference.getStructuredDataContainer().getId());
292     } catch (InvalidPathException e) {
293       throw new NotFoundException(
294         "The StructuredData Container with id %d could not be found.".formatted(
295             reference.getStructuredDataContainer().getId()
296           )
297       );
298     }
299 
300     String mongoId = reference.getStructuredDataContainer().getMongoId();
301     return structuredDataService.getPayload(mongoId, oid);
302   }
303 }