View Javadoc
1   package de.dlr.shepard.context.version.daos;
2   
3   import de.dlr.shepard.common.neo4j.daos.GenericDAO;
4   import de.dlr.shepard.common.util.CypherQueryHelper;
5   import de.dlr.shepard.common.util.CypherQueryHelper.Neighborhood;
6   import de.dlr.shepard.context.version.entities.Version;
7   import jakarta.enterprise.context.RequestScoped;
8   import java.util.ArrayList;
9   import java.util.HashMap;
10  import java.util.HashSet;
11  import java.util.Iterator;
12  import java.util.List;
13  import java.util.Map;
14  import java.util.UUID;
15  
16  @SuppressWarnings("PMD.AvoidDuplicateLiterals")
17  @RequestScoped
18  public class VersionDAO extends GenericDAO<Version> {
19  
20    /**
21     * Find a version by uid
22     *
23     * @param id Identifies the version
24     * @return the found version
25     */
26    public Version find(UUID id) {
27      return session.load(getEntityType(), id, DEPTH_ENTITY);
28    }
29  
30    @Override
31    public Class<Version> getEntityType() {
32      return Version.class;
33    }
34  
35    public List<Version> findAllVersions(long collectionId) {
36      HashSet<Version> resultHashSet = new HashSet<>();
37      Map<String, Object> paramsMap = new HashMap<>();
38      String query = "";
39      query = query + "MATCH (col:Collection)-[]->(ver:Version) WHERE col.shepardId = " + collectionId + " ";
40      query = query + CypherQueryHelper.getReturnPart("ver", Neighborhood.EVERYTHING);
41  
42      var resultSet = findByQuery(query, paramsMap);
43      for (Version next : resultSet) {
44        resultHashSet.add(find(next.getUid()));
45      }
46      return new ArrayList<>(resultHashSet);
47    }
48  
49    public Version findHEADVersion(long collectionId) {
50      Version ret = null;
51      String query =
52        "MATCH (c:Collection)-[:has_version]->(v:Version) WHERE c.shepardId = " +
53        collectionId +
54        " AND " +
55        CypherQueryHelper.getVersionHeadPart("v") +
56        " " +
57        CypherQueryHelper.getReturnPart("v", Neighborhood.EVERYTHING);
58      Map<String, Object> paramsMap = new HashMap<>();
59      var resultSet = findByQuery(query, paramsMap);
60      Iterator<Version> it = resultSet.iterator();
61      if (it.hasNext()) {
62        ret = it.next();
63      }
64      return ret;
65    }
66  
67    public Version findVersionLightByNeo4jId(long neo4jId) {
68      Version ret = null;
69      String query = "MATCH (ve:VersionableEntity)-[:has_version]->(v) WHERE id(ve) = " + neo4jId + " RETURN v";
70      Map<String, Object> paramsMap = new HashMap<>();
71      var resultSet = findByQuery(query, paramsMap);
72      Iterator<Version> it = resultSet.iterator();
73      if (it.hasNext()) {
74        ret = it.next();
75      }
76      return ret;
77    }
78  
79    public void createLink(long versionableEntityId, UUID versionUID) {
80      HashMap<String, Object> params = new HashMap<>();
81      params.put("versionableEntityId", versionableEntityId);
82      params.put("versionUID", versionUID);
83      String query =
84        """
85        MATCH (ve:VersionableEntity), (v:Version) WHERE id(ve) = $versionableEntityId AND v.uid = $versionUID
86         CREATE (ve)-[:has_version]->(v)
87        """;
88      runQuery(query, params);
89    }
90  
91    public void copyDataObjectsWithParentsAndPredecessors(UUID sourceVersionUID, UUID targetVersionUID) {
92      copyDataObjects(sourceVersionUID, targetVersionUID);
93      copyChildRelations(sourceVersionUID, targetVersionUID);
94      copySuccessorRelations(sourceVersionUID, targetVersionUID);
95      copyDataObjectCreatedByRelations(sourceVersionUID, targetVersionUID);
96    }
97  
98    private void copyDataObjectCreatedByRelations(UUID sourceVersionUID, UUID targetVersionUID) {
99      HashMap<String, Object> params = new HashMap<>();
100     params.put("sourceVersionUID", sourceVersionUID);
101     params.put("targetVersionUID", targetVersionUID);
102     String query =
103       """
104       MATCH (u_creator:User)<-[:created_by]-(do_source:DataObject)-[:has_version]->(v_source:Version),(do_target:DataObject)-[:has_version]->(v_target:Version)
105       WHERE v_source.uid = $sourceVersionUID AND v_target.uid = $targetVersionUID AND do_source.shepardId = do_target.shepardId
106       CREATE (do_target)-[:created_by]->(u_creator)
107       """;
108     runQuery(query, params);
109   }
110 
111   private void copyDataObjects(UUID sourceVersionUID, UUID targetVersionUID) {
112     HashMap<String, Object> params = new HashMap<>();
113     params.put("sourceVersionUID", sourceVersionUID);
114     params.put("targetVersionUID", targetVersionUID);
115     String query =
116       """
117       MATCH (do_source:DataObject)-[:has_version]->(v_source:Version)-[:has_predecessor]->(v_target:Version)<-[:has_version]-(col_target:Collection)
118       WHERE v_source.uid = $sourceVersionUID AND v_target.uid = $targetVersionUID
119       CREATE (col_target)-[:has_dataobject]->(do_target:DataObject:VersionableEntity:BasicEntity)-[:has_version]->(v_target)
120       SET do_target = do_source
121       """;
122     runQuery(query, params);
123   }
124 
125   private void copyChildRelations(UUID sourceVersionUID, UUID targetVersionUID) {
126     HashMap<String, Object> params = new HashMap<>();
127     params.put("sourceVersionUID", sourceVersionUID);
128     params.put("targetVersionUID", targetVersionUID);
129     String query =
130       """
131       MATCH (do_source_parent:DataObject)-[:has_child]->(do_source_child:DataObject)-[:has_version]->(v_source:Version)-[:has_predecessor]->(v_target:Version)<-[:has_version]-(do_target_parent:DataObject),
132       (v_target)<-[:has_version]-(do_target_child:DataObject)
133       WHERE v_source.uid = $sourceVersionUID AND v_target.uid = $targetVersionUID AND do_source_parent.shepardId=do_target_parent.shepardId AND do_source_child.shepardId=do_target_child.shepardId
134       CREATE (do_target_parent)-[:has_child]->(do_target_child)
135       """;
136     runQuery(query, params);
137   }
138 
139   private void copySuccessorRelations(UUID sourceVersionUID, UUID targetVersionUID) {
140     HashMap<String, Object> params = new HashMap<>();
141     params.put("sourceVersionUID", sourceVersionUID);
142     params.put("targetVersionUID", targetVersionUID);
143     String query =
144       """
145       MATCH (do_source_predecessor:DataObject)-[:has_successor]->(do_source_successor:DataObject)-[:has_version]->(v_source:Version)-[:has_predecessor]->(v_target:Version)<-[:has_version]-(do_target_predecessor:DataObject),
146       (v_target)<-[:has_version]-(do_target_successor:DataObject)
147       WHERE v_source.uid = $sourceVersionUID AND v_target.uid = $targetVersionUID
148       AND do_source_predecessor.shepardId=do_target_predecessor.shepardId AND do_source_successor.shepardId=do_target_successor.shepardId
149       CREATE (do_target_predecessor)-[:has_successor]->(do_target_successor)
150       """;
151     runQuery(query, params);
152   }
153 
154   public void copyDataObjectReferences(UUID sourceVersionUID, UUID targetVersionUID) {
155     copyInternalDataObjectReferences(sourceVersionUID, targetVersionUID);
156     copyExternalDataObjectReferences(sourceVersionUID, targetVersionUID);
157   }
158 
159   public void copyCollectionReferences(UUID sourceVersionUID, UUID targetVersionUID) {
160     HashMap<String, Object> params = new HashMap<>();
161     params.put("sourceVersionUID", sourceVersionUID);
162     params.put("targetVersionUID", targetVersionUID);
163     String query =
164       """
165       MATCH (v_source:Version)<-[has_version]-(do_source:DataObject)-[:has_reference]->(cr_source:CollectionReference)-[:points_to]->(c_pointed:Collection),
166       (cr_source)-[:created_by]->(u_creator:User),
167       (v_target:Version)<-[:has_version]-(do_target:DataObject)
168       WHERE v_source.uid = $sourceVersionUID AND v_target.uid = $targetVersionUID
169       AND do_source.shepardId = do_target.shepardId
170       CREATE (v_target)<-[:has_version]-(cr_target:CollectionReference:BasicReference)<-[:has_reference]-(do_target),
171       (c_pointed)<-[:points_to]-(cr_target)-[:created_by]->(u_creator)
172       SET cr_target = cr_source
173       """;
174     runQuery(query, params);
175   }
176 
177   public void copyExternalDataObjectReferences(UUID sourceVersionUID, UUID targetVersionUID) {
178     HashMap<String, Object> params = new HashMap<>();
179     params.put("sourceVersionUID", sourceVersionUID);
180     params.put("targetVersionUID", targetVersionUID);
181     String query =
182       """
183       MATCH (v_source_pointer:Version)<-[:has_version]-(c_pointer:Collection)-[:has_dataobject]->(do_source_pointer:DataObject)-[:has_reference]->(dor_source:DataObjectReference)-[:points_to]->(do_pointed_to:DataObject)<-[:has_dataobject]-(c_pointed_to:Collection)-[:has_version]->(v_source_pointed_to:Version),
184       (dor_source:DataObjectReference)-[:created_by]->(u_creator:User),
185       (v_target_pointer:Version)<-[:has_version]-(do_target_pointer:DataObject)
186       WHERE v_source_pointer.uid = $sourceVersionUID AND v_target_pointer.uid = $targetVersionUID
187       AND do_source_pointer.shepardId = do_target_pointer.shepardId AND NOT(c_pointer.shepardId = c_pointed_to.shepardId)
188       CREATE (do_target_pointer)-[:has_reference]->(dor_target:DataObjectReference:BasicReference:VersionableEntity:BasicEntity)-[:points_to]->(do_pointed_to),
189       (v_target_pointer)<-[:has_version]-(dor_target)-[:created_by]->(u_creator)
190       SET dor_target=dor_source
191       """;
192     runQuery(query, params);
193   }
194 
195   public void copyInternalDataObjectReferences(UUID sourceVersionUID, UUID targetVersionUID) {
196     HashMap<String, Object> params = new HashMap<>();
197     params.put("sourceVersionUID", sourceVersionUID);
198     params.put("targetVersionUID", targetVersionUID);
199     String query =
200       """
201       MATCH (v_source:Version)<-[:has_version]-(c_pointer:Collection)-[:has_dataobject]->(do_source_pointer:DataObject)-[:has_reference]->(dor_source:DataObjectReference)-[:points_to]->(do_source_pointed_to:DataObject)<-[:has_dataobject]-(c_pointed_to:Collection),
202       (do_target_pointed_to:DataObject)-[:has_version]->(v_target:Version)<-[:has_version]-(do_target_pointer:DataObject)
203       WHERE v_source.uid = $sourceVersionUID AND v_target.uid = $targetVersionUID
204       AND do_source_pointer.shepardId = do_target_pointer.shepardId AND do_source_pointed_to.shepardId = do_target_pointed_to.shepardId AND id(c_pointer) = id(c_pointed_to)
205       CREATE (do_target_pointer)-[:has_reference]->(dor_target:DataObjectReference:BasicReference:VersionableEntity:BasicEntity)-[:points_to]->(do_target_pointed_to)
206       SET dor_target = dor_source
207       """;
208     runQuery(query, params);
209     attachVersionAndCreatedByToDataObjectReferences(sourceVersionUID, targetVersionUID);
210   }
211 
212   public void attachVersionAndCreatedByToDataObjectReferences(UUID sourceVersionUID, UUID targetVersionUID) {
213     HashMap<String, Object> params = new HashMap<>();
214     params.put("sourceVersionUID", sourceVersionUID);
215     params.put("targetVersionUID", targetVersionUID);
216     String query =
217       """
218       MATCH (v_source:Version)<-[:has_version]-(dor_source:DataObjectReference)-[:created_by]->(u_creator:User), (v_target:Version)<-[:has_version]-(do_target_pointer:DataObject)-[:has_reference]->(dor_target:DataObjectReference)
219       WHERE v_source.uid = $sourceVersionUID AND v_target.uid = $targetVersionUID
220       AND dor_source.shepardId = dor_target.shepardId
221       CREATE (v_target)<-[:has_version]-(dor_target)-[:created_by]->(u_creator)
222       """;
223     runQuery(query, params);
224   }
225 
226   public void copyFileReferences(UUID sourceVersionUID, UUID targetVersionUID) {
227     HashMap<String, Object> params = new HashMap<>();
228     params.put("sourceVersionUID", sourceVersionUID);
229     params.put("targetVersionUID", targetVersionUID);
230     String query =
231       """
232       MATCH (v_source:Version)<-[has_version]-(do_source:DataObject)-[:has_reference]->(fr_source:FileReference)-[:is_in_container]->(fc_pointed:FileContainer),
233       (fr_source)-[:created_by]->(u_creator:User), (v_target:Version)<-[:has_version]-(do_target:DataObject)
234       WHERE v_source.uid = $sourceVersionUID AND v_target.uid = $targetVersionUID AND do_source.shepardId = do_target.shepardId
235       CREATE (v_target)<-[:has_version]-(fr_target:FileReference:BasicReference:VersionableEntity:BasicEntity)<-[:has_reference]-(do_target),
236       (fc_pointed)<-[:is_in_container]-(fr_target)-[:created_by]->(u_creator)
237       SET fr_target = fr_source
238       """;
239     runQuery(query, params);
240     query = """
241     MATCH (v_source:Version)<-[:has_version]-(fr_source:FileReference)-[:has_payload]->(sf:ShepardFile),
242     (v_target:Version)<-[:has_version]-(fr_target:FileReference)
243     WHERE v_source.uid = $sourceVersionUID AND v_target.uid = $targetVersionUID AND fr_source.shepardId = fr_target.shepardId
244     CREATE (fr_target)-[:has_payload]->(sf)
245     """;
246     runQuery(query, params);
247   }
248 
249   public void copyStructuredDataReferences(UUID sourceVersionUID, UUID targetVersionUID) {
250     HashMap<String, Object> params = new HashMap<>();
251     params.put("sourceVersionUID", sourceVersionUID);
252     params.put("targetVersionUID", targetVersionUID);
253     String query =
254       """
255       MATCH (v_source:Version)<-[has_version]-(do_source:DataObject)-[:has_reference]->(sdr_source:StructuredDataReference)-[:is_in_container]->(sdc_pointed:StructuredDataContainer),
256       (sdr_source)-[:created_by]->(u_creator:User),
257       (v_target:Version)<-[:has_version]-(do_target:DataObject)
258       WHERE v_source.uid = $sourceVersionUID AND v_target.uid = $targetVersionUID
259       AND do_source.shepardId = do_target.shepardId
260       CREATE (v_target)<-[:has_version]-(sdr_target:StructuredDataReference:BasicReference:VersionableEntity:BasicEntity)<-[:has_reference]-(do_target),
261       (sdc_pointed)<-[:is_in_container]-(sdr_target)-[:created_by]->(u_creator)
262       SET sdr_target = sdr_source
263       """;
264     runQuery(query, params);
265     query = """
266     MATCH (v_source:Version)<-[:has_version]-(sdr_source:StructuredDataReference)-[:has_payload]->(sd:StructuredData),
267     (v_target:Version)<-[:has_version]-(sdr_target:StructuredDataReference)
268     WHERE v_source.uid = $sourceVersionUID AND v_target.uid = $targetVersionUID
269     AND sdr_source.shepardId = sdr_target.shepardId
270     CREATE (sdr_target)-[:has_payload]->(sd)
271     """;
272     runQuery(query, params);
273   }
274 
275   public void copyTimeseriesReferences(UUID sourceVersionUID, UUID targetVersionUID) {
276     HashMap<String, Object> params = new HashMap<>();
277     params.put("sourceVersionUID", sourceVersionUID);
278     params.put("targetVersionUID", targetVersionUID);
279     String query =
280       """
281       MATCH (v_source:Version)<-[has_version]-(do_source:DataObject)-[:has_reference]->(tsr_source:TimeseriesReference)-[:is_in_container]->(tsc_pointed:TimeseriesContainer),
282       (tsr_source)-[:created_by]->(u_creator:User),
283       (v_target:Version)<-[:has_version]-(do_target:DataObject)
284       WHERE v_source.uid = $sourceVersionUID AND v_target.uid = $targetVersionUID
285       AND do_source.shepardId = do_target.shepardId
286       CREATE (v_target)<-[:has_version]-(tsr_target:TimeseriesReference:BasicReference:VersionableEntity:BasicEntity)<-[:has_reference]-(do_target),
287       (tsc_pointed)<-[:is_in_container]-(tsr_target)-[:created_by]->(u_creator)
288       SET tsr_target = tsr_source
289       """;
290     runQuery(query, params);
291     query = """
292     MATCH (v_source:Version)<-[:has_version]-(tsr_source:TimeseriesReference)-[:has_payload]->(ts:TimeseriesTuple),
293     (v_target:Version)<-[:has_version]-(tsr_target:TimeseriesReference)
294     WHERE v_source.uid = $sourceVersionUID AND v_target.uid = $targetVersionUID
295     AND tsr_source.shepardId = tsr_target.shepardId
296     CREATE (tsr_target)-[:has_payload]->(ts)
297     """;
298     runQuery(query, params);
299   }
300 
301   public void copyURIReferences(UUID sourceVersionUID, UUID targetVersionUID) {
302     HashMap<String, Object> params = new HashMap<>();
303     params.put("sourceVersionUID", sourceVersionUID);
304     params.put("targetVersionUID", targetVersionUID);
305     String query =
306       """
307       MATCH (v_source:Version)<-[:has_version]-(do_source:DataObject)-[:has_reference]->(ur_source:URIReference)-[:created_by]->(u_creator:User),
308       (v_target:Version)<-[:has_version]-(do_target:DataObject)
309       WHERE v_source.uid = $sourceVersionUID AND v_target.uid = $targetVersionUID
310       AND do_source.shepardId = do_target.shepardId
311       CREATE (v_target)<-[:has_version]-(ur_target:URIReference:BasicReference:VersionableEntity:BasicEntity)<-[:has_reference]-(do_target),
312       (ur_target)-[:created_by]->(u_creator)
313       SET ur_target=ur_source
314       """;
315     runQuery(query, params);
316   }
317 
318   public void addAnnotations(UUID sourceVersionUID, UUID targetVersionUID) {
319     HashMap<String, Object> params = new HashMap<>();
320     params.put("sourceVersionUID", sourceVersionUID);
321     params.put("targetVersionUID", targetVersionUID);
322     String query =
323       """
324       MATCH (v_source:Version)<-[:has_version]-(sourceEntity)-[:has_annotation]->(a:SemanticAnnotation),
325       (v_target:Version)<-[:has_version]-(targetEntity)
326       WHERE v_source.uid = $sourceVersionUID AND v_target.uid = $targetVersionUID
327       AND sourceEntity.shepardId = targetEntity.shepardId
328       CREATE (targetEntity)-[:has_annotation]->(a)
329       """;
330     runQuery(query, params);
331   }
332 
333   public void removeHasPredecessor(UUID sourceVersionUID, UUID targetVersionUID) {
334     HashMap<String, Object> params = new HashMap<>();
335     params.put("sourceVersionUID", sourceVersionUID);
336     params.put("targetVersionUID", targetVersionUID);
337     String query =
338       """
339       MATCH (v_source:Version)-[hp:has_predecessor]->(v_target:Version)
340       WHERE v_source.uid = $sourceVersionUID AND v_target.uid = $targetVersionUID
341       DELETE hp
342       """;
343     runQuery(query, params);
344   }
345 }