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