1 package de.tud.plt.r43ples.core;
2
3 import org.apache.jena.query.*;
4 import org.apache.jena.rdf.model.Model;
5 import org.apache.jena.util.FileUtils;
6 import de.tud.plt.r43ples.exception.InternalErrorException;
7 import de.tud.plt.r43ples.existentobjects.Branch;
8 import de.tud.plt.r43ples.existentobjects.ChangeSet;
9 import de.tud.plt.r43ples.existentobjects.Revision;
10 import de.tud.plt.r43ples.existentobjects.ThreeWayMergeCommit;
11 import de.tud.plt.r43ples.iohelper.Helper;
12 import de.tud.plt.r43ples.iohelper.JenaModelManagement;
13 import de.tud.plt.r43ples.management.Config;
14 import de.tud.plt.r43ples.optimization.ChangeSetPath;
15 import de.tud.plt.r43ples.triplestoreInterface.TripleStoreInterfaceSingleton;
16 import org.apache.logging.log4j.LogManager;
17 import org.apache.logging.log4j.Logger;
18
19
20
21
22
23
24 public class ThreeWayMergeCommitDraft extends MergeCommitDraft {
25
26
27 private Logger logger = LogManager.getLogger(ThreeWayMergeCommitDraft.class);
28
29
30 private Branch usedSourceBranch;
31
32 private Branch usedTargetBranch;
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 protected ThreeWayMergeCommitDraft(String graphName, String branchNameFrom, String branchNameInto, String user, String message, String triples, MergeTypes type, boolean with) throws InternalErrorException {
50 super(graphName, branchNameFrom, branchNameInto, user, message, MergeActions.MERGE, triples, type, with);
51 this.usedSourceBranch = getRevisionGraph().getBranch(getBranchNameFrom(), true);
52 this.usedTargetBranch = getRevisionGraph().getBranch(getBranchNameInto(), true);
53 }
54
55
56
57
58
59
60
61 protected ThreeWayMergeCommit createCommitInTripleStore() throws InternalErrorException {
62
63 Revision fromRevision = this.usedSourceBranch.getLeafRevision();
64
65 Revision intoRevision = this.usedTargetBranch.getLeafRevision();
66
67
68 String usedSDDURI = getRevisionGraph().getSDG();
69
70
71 Revision commonRevision = this.getPathCalculationInterface().getCommonRevisionWithShortestPath(fromRevision, intoRevision);
72
73
74 String namedGraphUriFrom = getUriCalculator().getTemporaryRevisionProgressFromURI(getRevisionGraph());
75 String namedGraphUriInto = getUriCalculator().getTemporaryRevisionProgressIntoURI(getRevisionGraph());
76 String namedGraphUriDiff = getUriCalculator().getTemporaryDifferenceModelURI(getRevisionGraph());
77 String uriA = "http://eatld.et.tu-dresden.de/branch-from";
78 String uriB = "http://eatld.et.tu-dresden.de/branch-into";
79
80 ChangeSetPath changesetsFromCommontoSourceBranch = this.getPathCalculationInterface().getChangeSetsBetweenStartAndTargetRevision(commonRevision, fromRevision);
81 ChangeSetPath changesetsFromCommontoTargetBranch = this.getPathCalculationInterface().getChangeSetsBetweenStartAndTargetRevision(commonRevision, intoRevision);
82
83
84 createRevisionProgresses(
85 changesetsFromCommontoSourceBranch, namedGraphUriFrom, uriA,
86 changesetsFromCommontoTargetBranch, namedGraphUriInto, uriB,
87 commonRevision);
88
89
90 createDifferenceTripleModel(namedGraphUriDiff, namedGraphUriFrom, uriA, namedGraphUriInto, uriB,
91 usedSDDURI);
92
93
94 Revision revision;
95
96
97 if ((getType() != null) && (getType().equals(MergeTypes.AUTO)) && !isWith()) {
98 logger.debug("AUTO MERGE query detected");
99
100 revision = createMergedRevision(namedGraphUriDiff, MergeQueryTypeEnum.AUTO, fromRevision);
101 return addMetaInformation(revision, namedGraphUriDiff, commonRevision, fromRevision, intoRevision);
102 } else if ((getType() != null) && (getType().equals(MergeTypes.MANUAL)) && isWith()) {
103 logger.debug("MANUAL MERGE query detected");
104
105 revision = createMergedRevision(namedGraphUriDiff, MergeQueryTypeEnum.MANUAL, fromRevision);
106 return addMetaInformation(revision, namedGraphUriDiff, commonRevision, fromRevision, intoRevision);
107 } else if ((getType() == null) && isWith()) {
108 logger.debug("MERGE WITH query detected");
109
110 revision = createMergedRevision(namedGraphUriDiff, MergeQueryTypeEnum.WITH, fromRevision);
111 return addMetaInformation(revision, namedGraphUriDiff, commonRevision, fromRevision, intoRevision);
112 } else if ((getType() == null) && !isWith()) {
113 logger.debug("MERGE query detected");
114
115 String queryASK = String.format("ASK { %n" + " GRAPH <%s> { %n"
116 + " ?ref <http://eatld.et.tu-dresden.de/mmo#isConflicting> \"true\"^^<http://www.w3.org/2001/XMLSchema#boolean> . %n"
117 + " } %n" + "}", namedGraphUriDiff);
118 if (getTripleStoreInterface().executeAskQuery(queryASK)) {
119
120
121 String conflictModel = Helper.getContentOfGraph(namedGraphUriDiff, "text/turtle");
122 return new ThreeWayMergeCommit(getRevisionGraph(), null,null, null, null, fromRevision, null, intoRevision, null, null, null, true, conflictModel, namedGraphUriDiff);
123 } else {
124
125
126 revision = createMergedRevision(namedGraphUriDiff, MergeQueryTypeEnum.COMMON, fromRevision);
127 return addMetaInformation(revision, namedGraphUriDiff, commonRevision, fromRevision, intoRevision);
128 }
129 } else {
130 throw new InternalErrorException("This is not a valid MERGE query");
131 }
132 }
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147 private ThreeWayMergeCommit addMetaInformation(Revision generatedRevision, String namedGraphUriDiff, Revision commonRevision, Revision usedSourceRevision, Revision usedTargetRevision) throws InternalErrorException {
148
149 String commitURI = getUriCalculator().getNewThreeWayMergeCommitURI(getRevisionGraph(), generatedRevision.getRevisionIdentifier());;
150
151 String personUri = Helper.getUserURI(getUser());
152
153
154 StringBuilder queryContent = new StringBuilder(1000);
155 queryContent.append(String.format(
156 "<%s> a rmo:ThreeWayMergeCommit, rmo:MergeCommit, rmo:BasicMergeCommit, rmo:Commit; "
157 + " rmo:wasAssociatedWith <%s> ;"
158 + " rmo:commitMessage \"%s\" ;"
159 + " rmo:timeStamp \"%s\"^^xsd:dateTime ; %n"
160 + " rmo:generated <%s> ;"
161 + " rmo:hasChangeSet <%s> ;"
162 + " rmo:hasChangeSet <%s> ;"
163 + " rmo:usedSourceRevision <%s> ;"
164 + " rmo:usedSourceBranch <%s> ;"
165 + " rmo:usedTargetRevision <%s> ;"
166 + " rmo:usedTargetBranch <%s> .",
167 commitURI, personUri, getMessage(), getTimeStamp(),
168 generatedRevision.getRevisionURI(), generatedRevision.getChangeSets().get(0).getChangeSetURI(), generatedRevision.getChangeSets().get(1).getChangeSetURI(), usedSourceRevision.getRevisionURI(), usedSourceBranch.getReferenceURI(),
169 usedTargetRevision.getRevisionURI(), usedTargetBranch.getReferenceURI()));
170
171
172 queryContent.append(String.format(
173 "<%1$s> rmo:succeedingRevision <%2$s> . %n"
174 + "<%2$s> rmo:wasDerivedFrom <%3$s> .",
175 generatedRevision.getChangeSets().get(1).getChangeSetURI(), generatedRevision.getRevisionURI(), usedSourceRevision.getRevisionURI()));
176
177 String query = Config.prefixes
178 + String.format("INSERT DATA { GRAPH <%s> { %s } }", getRevisionGraph().getRevisionGraphUri(),
179 queryContent.toString());
180
181 getTripleStoreInterface().executeUpdateQuery(query);
182
183
184 moveBranchReference(getRevisionGraph().getRevisionGraphUri(), usedTargetBranch.getReferenceURI(), usedTargetRevision.getRevisionURI(), generatedRevision.getRevisionURI());
185 updateReferencedFullGraph(usedTargetBranch.getFullGraphURI(), generatedRevision.getChangeSets().get(0));
186
187 usedTargetBranch = getRevisionGraph().getBranch(getBranchNameInto(), true);
188
189 return new ThreeWayMergeCommit(getRevisionGraph(), commitURI, getUser(), getTimeStamp(), getMessage(),
190 usedSourceRevision, usedSourceBranch, usedTargetRevision, usedTargetBranch, generatedRevision,
191 commonRevision, false, null, namedGraphUriDiff);
192 }
193
194
195
196
197
198
199
200
201
202
203 private Revision createMergedRevision(String graphNameDifferenceTripleModel, MergeQueryTypeEnum type, Revision usedSourceRevision) throws InternalErrorException {
204
205
206 String graphNameOfMerged = getUriCalculator().getTemporaryMergedURI(getRevisionGraph());
207 getTripleStoreInterface().executeUpdateQuery(String.format("DROP SILENT GRAPH <%s>", graphNameOfMerged));
208 getTripleStoreInterface().executeCreateGraph(graphNameOfMerged);
209
210
211 String graphNameOfBranchA = usedSourceBranch.getFullGraphURI();
212
213 String graphNameOfBranchB = usedTargetBranch.getFullGraphURI();
214
215 if (type.equals(MergeQueryTypeEnum.MANUAL)) {
216
217 Helper.executeINSERT(graphNameOfMerged, getTriples());
218 } else {
219
220 String queryCopy = String.format("COPY <%s> TO <%s>", graphNameOfBranchB, graphNameOfMerged);
221 getTripleStoreInterface().executeUpdateQuery(queryCopy);
222
223
224 String triplesToAdd = "";
225 String triplesToDelete = "";
226
227
228 String queryDifferenceGroup = Config.prefixes + String.format(
229 "SELECT ?differenceCombinationURI ?automaticResolutionState ?tripleStateA ?tripleStateB ?conflict %n"
230 + "WHERE { GRAPH <%s> { %n"
231 + " ?differenceCombinationURI a mmo:DifferenceGroup ; %n"
232 + " mmo:automaticResolutionState ?automaticResolutionState ; %n"
233 + " mmo:hasTripleStateA ?tripleStateA ; %n"
234 + " mmo:hasTripleStateB ?tripleStateB ; %n"
235 + " mmo:isConflicting ?conflict . %n"
236 + "} }", graphNameDifferenceTripleModel);
237
238
239 ResultSet resultSetDifferenceGroups = getTripleStoreInterface().executeSelectQuery(queryDifferenceGroup);
240 while (resultSetDifferenceGroups.hasNext()) {
241 QuerySolution qsCurrentDifferenceGroup = resultSetDifferenceGroups.next();
242
243 String currentDifferencGroupURI = qsCurrentDifferenceGroup.getResource("?differenceCombinationURI").toString();
244 String currentDifferencGroupAutomaticResolutionState = qsCurrentDifferenceGroup.getResource("?automaticResolutionState").toString();
245
246
247
248 boolean currentDifferencGroupConflict = qsCurrentDifferenceGroup.getLiteral("?conflict").getBoolean();
249
250
251 String queryDifference = Config.prefixes + String.format(
252 "SELECT ?s ?p ?o %n"
253 + "WHERE { GRAPH <%s> { %n"
254 + " <%s> a mmo:DifferenceGroup ; %n"
255 + " mmo:hasDifference ?blankDifference . %n"
256 + " ?blankDifference a mmo:Difference ; %n"
257 + " mmo:hasTriple ?triple . %n"
258 + " ?triple rdf:subject ?s . %n"
259 + " ?triple rdf:predicate ?p . %n"
260 + " ?triple rdf:object ?o . %n"
261 + "} }", graphNameDifferenceTripleModel, currentDifferencGroupURI);
262
263
264 ResultSet resultSetDifferences = getTripleStoreInterface().executeSelectQuery(queryDifference);
265 while (resultSetDifferences.hasNext()) {
266 QuerySolution qsCurrentDifference = resultSetDifferences.next();
267
268 String subject = "<" + qsCurrentDifference.getResource("?s").toString() + ">";
269 String predicate = "<" + qsCurrentDifference.getResource("?p").toString() + ">";
270
271
272 String object;
273 if (qsCurrentDifference.get("?o").isLiteral()) {
274 object = "\"" + qsCurrentDifference.getLiteral("?o").toString() + "\"";
275 } else {
276 object = "<" + qsCurrentDifference.getResource("?o").toString() + ">";
277 }
278
279 if ( type.equals(MergeQueryTypeEnum.AUTO) ||
280 type.equals(MergeQueryTypeEnum.COMMON) ||
281 (type.equals(MergeQueryTypeEnum.WITH) && !currentDifferencGroupConflict) ) {
282
283 if (currentDifferencGroupAutomaticResolutionState.equals(MergeTripleStateEnum.ADDED.getSdRepresentation())) {
284
285 triplesToAdd += subject + " " + predicate + " " + object + " . \n";
286 } else {
287
288 triplesToDelete += subject + " " + predicate + " " + object + " . \n";
289 }
290 } else {
291
292 Model model = JenaModelManagement.readNTripleStringToJenaModel(getTriples());
293
294 String queryAsk = String.format(
295 "ASK { %n"
296 + " %s %s %s %n"
297 + "}", subject, predicate, object);
298 Query query = QueryFactory.create(queryAsk);
299 QueryExecution qe = QueryExecutionFactory.create(query, model);
300 boolean resultAsk = qe.execAsk();
301 qe.close();
302 model.close();
303 if (resultAsk) {
304
305
306 triplesToAdd += subject + " " + predicate + " " + object + " . \n";
307 } else {
308
309 triplesToDelete += subject + " " + predicate + " " + object + " . \n";
310 }
311 }
312 }
313
314
315 Helper.executeINSERT(graphNameOfMerged, triplesToAdd);
316
317 Helper.executeDELETE(graphNameOfMerged, triplesToDelete);
318 }
319 }
320
321
322
323
324 String queryAddedTriplesA = String.format(
325 "CONSTRUCT {?s ?p ?o} %n"
326 + "WHERE { %n"
327 + " GRAPH <%s> { ?s ?p ?o } %n"
328 + " FILTER NOT EXISTS { "
329 + " GRAPH <%s> { ?s ?p ?o } %n"
330 + " } %n"
331 + "}", graphNameOfMerged, graphNameOfBranchA);
332
333 String addedTriplesA = getTripleStoreInterface().executeConstructQuery(queryAddedTriplesA, FileUtils.langNTriple);
334
335 String queryAddedTriplesB = String.format(
336 "CONSTRUCT {?s ?p ?o} %n"
337 + "WHERE { %n"
338 + " GRAPH <%s> { ?s ?p ?o } %n"
339 + " FILTER NOT EXISTS { %n"
340 + " GRAPH <%s> { ?s ?p ?o } %n"
341 + " } %n"
342 + "}", graphNameOfMerged, graphNameOfBranchB);
343
344 String addedTriplesB = getTripleStoreInterface().executeConstructQuery(queryAddedTriplesB, FileUtils.langNTriple);
345
346
347 String queryDeletedTriplesA = String.format(
348 "CONSTRUCT {?s ?p ?o} %n"
349 + "WHERE { %n"
350 + " GRAPH <%s> { ?s ?p ?o } %n"
351 + " FILTER NOT EXISTS { %n"
352 + " GRAPH <%s> { ?s ?p ?o } %n"
353 + " } %n"
354 + "}", graphNameOfBranchA, graphNameOfMerged);
355
356 String deletedTriplesA = getTripleStoreInterface().executeConstructQuery(queryDeletedTriplesA, FileUtils.langNTriple);
357
358 String queryDeletedTriplesB = String.format(
359 "CONSTRUCT {?s ?p ?o} %n"
360 + "WHERE { %n"
361 + " GRAPH <%s> { ?s ?p ?o } %n"
362 + " FILTER NOT EXISTS { %n"
363 + " GRAPH <%s> { ?s ?p ?o } %n"
364 + " } %n"
365 + "}", graphNameOfBranchB, graphNameOfMerged);
366
367 String deletedTriplesB = getTripleStoreInterface().executeConstructQuery(queryDeletedTriplesB, FileUtils.langNTriple);
368
369
370 RevisionDraft revisionDraft = new RevisionDraft(getUriCalculator(), getRevisionGraph(), usedTargetBranch,
371 addedTriplesB, deletedTriplesB, false);
372 Revision generatedRevision = revisionDraft.createInTripleStore();
373
374 ChangeSetDraft changeSetDraftA = new ChangeSetDraft(getUriCalculator(), getRevisionGraph(),
375 usedSourceBranch.getLeafRevision(), generatedRevision.getRevisionIdentifier(), generatedRevision.getRevisionURI(), usedSourceBranch.getReferenceURI(),
376 addedTriplesA, deletedTriplesA, false, false);
377 ChangeSet changeSetA = changeSetDraftA.createInTripleStore();
378
379 generatedRevision.addChangeSet(changeSetA);
380 return generatedRevision;
381 }
382
383
384
385
386
387
388
389
390
391
392
393
394 protected void createRevisionProgresses(ChangeSetPath pathFrom, String graphNameRevisionProgressFrom, String uriFrom,
395 ChangeSetPath pathInto, String graphNameRevisionProgressInto, String uriInto,
396 Revision commonRevision) throws InternalErrorException {
397 logger.info("Create the revision progress of branch from and into.");
398
399 if (!((pathFrom.getRevisionPath().size() > 0) && (pathInto.getRevisionPath().size() > 0))) {
400 throw new InternalErrorException("Revision path contains no revisions.");
401 }
402
403
404 FullGraph fullGraph = new FullGraph(this.getRevisionGraph(), commonRevision);
405
406
407 createRevisionProgress(fullGraph, pathFrom, graphNameRevisionProgressFrom, uriFrom);
408
409
410 createRevisionProgress(fullGraph, pathInto, graphNameRevisionProgressInto, uriInto);
411
412
413 fullGraph.purge();
414 }
415
416
417
418
419
420
421
422
423
424
425 protected void createRevisionProgress(FullGraph startingFullGraph, ChangeSetPath path, String graphNameRevisionProgress, String uri) throws InternalErrorException {
426 logger.info("Create the revision progress of " + uri + " in graph " + graphNameRevisionProgress + ".");
427
428 TripleStoreInterfaceSingleton.get().executeUpdateQuery(String.format("DROP SILENT GRAPH <%s>", graphNameRevisionProgress));
429 TripleStoreInterfaceSingleton.get().executeUpdateQuery(String.format("CREATE GRAPH <%s>", graphNameRevisionProgress));
430
431
432 logger.info("Create the initial content.");
433 String queryInitial = Config.prefixes + String.format(
434 "INSERT { GRAPH <%s> { %n"
435 + " <%s> a mmo:RevisionProgress; %n"
436 + " mmo:Original [ %n"
437 + " rdf:subject ?s ; %n"
438 + " rdf:predicate ?p ; %n"
439 + " rdf:object ?o ; %n"
440 + " rmo:references <%s> %n"
441 + " ] %n"
442 + "} } WHERE { %n"
443 + " GRAPH <%s> %n"
444 + " { ?s ?p ?o . } %n"
445 + "}", graphNameRevisionProgress, uri, startingFullGraph.getRevision().getRevisionURI(), startingFullGraph.getFullGraphUri());
446
447
448 TripleStoreInterfaceSingleton.get().executeUpdateQuery(queryInitial);
449
450
451 while (path.getRevisionPath().size() > 0) {
452 ChangeSet changeSet = path.getRevisionPath().removeLast();
453 logger.info("Update content by current add and delete set of changeset " + changeSet + " - remove old entries.");
454
455 String addSetURI = changeSet.getAddSetURI();
456 String deleteSetURI = changeSet.getDeleteSetURI();
457
458 if ((addSetURI != null) && (deleteSetURI != null)) {
459
460
461
462
463 String queryRevision = Config.prefixes + String.format(
464 "DELETE { GRAPH <%s> { %n"
465 + " <%s> mmo:Original ?blank . %n"
466 + " ?blank rdf:subject ?s . %n"
467 + " ?blank rdf:predicate ?p . %n"
468 + " ?blank rdf:object ?o . %n"
469 + " ?blank rmo:references ?revision . %n"
470 + "} } %n"
471 + "WHERE { "
472 + " GRAPH <%s> { %n"
473 + " <%s> mmo:Original ?blank . %n"
474 + " ?blank rdf:subject ?s . %n"
475 + " ?blank rdf:predicate ?p . %n"
476 + " ?blank rdf:object ?o . %n"
477 + " ?blank rmo:references ?revision . %n"
478 + " } %n"
479 + " GRAPH <%s> { %n"
480 + " ?s ?p ?o %n"
481 + " } %n"
482 + "};", graphNameRevisionProgress, uri, graphNameRevisionProgress, uri, addSetURI);
483
484 queryRevision += "\n";
485
486
487 queryRevision += String.format(
488 "DELETE { GRAPH <%s> { %n"
489 + " <%s> mmo:Added ?blank . %n"
490 + " ?blank rdf:subject ?s . %n"
491 + " ?blank rdf:predicate ?p . %n"
492 + " ?blank rdf:object ?o . %n"
493 + " ?blank rmo:references ?revision . %n"
494 + "} } %n"
495 + "WHERE { "
496 + " GRAPH <%s> { %n"
497 + " <%s> mmo:Added ?blank . %n"
498 + " ?blank rdf:subject ?s . %n"
499 + " ?blank rdf:predicate ?p . %n"
500 + " ?blank rdf:object ?o . %n"
501 + " ?blank rmo:references ?revision . %n"
502 + " } %n"
503 + " GRAPH <%s> { %n"
504 + " ?s ?p ?o %n"
505 + " } %n"
506 + "};", graphNameRevisionProgress, uri, graphNameRevisionProgress, uri, addSetURI);
507
508 queryRevision += "\n";
509
510
511 queryRevision += String.format(
512 "DELETE { GRAPH <%s> { %n"
513 + " <%s> mmo:Deleted ?blank . %n"
514 + " ?blank rdf:subject ?s . %n"
515 + " ?blank rdf:predicate ?p . %n"
516 + " ?blank rdf:object ?o . %n"
517 + " ?blank rmo:references ?revision . %n"
518 + "} } %n"
519 + "WHERE { "
520 + " GRAPH <%s> { %n"
521 + " <%s> mmo:Deleted ?blank . %n"
522 + " ?blank rdf:subject ?s . %n"
523 + " ?blank rdf:predicate ?p . %n"
524 + " ?blank rdf:object ?o . %n"
525 + " ?blank rmo:references ?revision . %n"
526 + " } %n"
527 + " GRAPH <%s> { %n"
528 + " ?s ?p ?o %n"
529 + " } %n"
530 + "};", graphNameRevisionProgress, uri, graphNameRevisionProgress, uri, addSetURI);
531
532 queryRevision += "\n";
533
534
535 queryRevision += String.format(
536 "INSERT { GRAPH <%s> {%n"
537 + " <%s> a mmo:RevisionProgress; %n"
538 + " mmo:Added [ %n"
539 + " rdf:subject ?s ; %n"
540 + " rdf:predicate ?p ; %n"
541 + " rdf:object ?o ; %n"
542 + " rmo:references <%s> %n"
543 + " ] %n"
544 + "} } WHERE { %n"
545 + " GRAPH <%s> %n"
546 + " { ?s ?p ?o . } %n"
547 + "};", graphNameRevisionProgress, uri, changeSet.getChangeSetURI(), addSetURI);
548
549 queryRevision += "\n \n";
550
551
552
553
554 queryRevision += String.format(
555 "DELETE { GRAPH <%s> { %n"
556 + " <%s> mmo:Original ?blank . %n"
557 + " ?blank rdf:subject ?s . %n"
558 + " ?blank rdf:predicate ?p . %n"
559 + " ?blank rdf:object ?o . %n"
560 + " ?blank rmo:references ?revision . %n"
561 + "} } %n"
562 + "WHERE { "
563 + " GRAPH <%s> { %n"
564 + " <%s> mmo:Original ?blank . %n"
565 + " ?blank rdf:subject ?s . %n"
566 + " ?blank rdf:predicate ?p . %n"
567 + " ?blank rdf:object ?o . %n"
568 + " ?blank rmo:references ?revision . %n"
569 + " } %n"
570 + " GRAPH <%s> { %n"
571 + " ?s ?p ?o %n"
572 + " } %n"
573 + "};", graphNameRevisionProgress, uri, graphNameRevisionProgress, uri, deleteSetURI);
574
575 queryRevision += "\n";
576
577
578 queryRevision += String.format(
579 "DELETE { GRAPH <%s> { %n"
580 + " <%s> mmo:Added ?blank . %n"
581 + " ?blank rdf:subject ?s . %n"
582 + " ?blank rdf:predicate ?p . %n"
583 + " ?blank rdf:object ?o . %n"
584 + " ?blank rmo:references ?revision . %n"
585 + "} } %n"
586 + "WHERE { "
587 + " GRAPH <%s> { %n"
588 + " <%s> mmo:Added ?blank . %n"
589 + " ?blank rdf:subject ?s . %n"
590 + " ?blank rdf:predicate ?p . %n"
591 + " ?blank rdf:object ?o . %n"
592 + " ?blank rmo:references ?revision . %n"
593 + " } %n"
594 + " GRAPH <%s> { %n"
595 + " ?s ?p ?o %n"
596 + " } %n"
597 + "};", graphNameRevisionProgress, uri, graphNameRevisionProgress, uri, deleteSetURI);
598
599 queryRevision += "\n";
600
601
602 queryRevision += String.format(
603 "DELETE { GRAPH <%s> { %n"
604 + " <%s> mmo:Deleted ?blank . %n"
605 + " ?blank rdf:subject ?s . %n"
606 + " ?blank rdf:predicate ?p . %n"
607 + " ?blank rdf:object ?o . %n"
608 + " ?blank rmo:references ?revision . %n"
609 + "} } %n"
610 + "WHERE { "
611 + " GRAPH <%s> { %n"
612 + " <%s> mmo:Deleted ?blank . %n"
613 + " ?blank rdf:subject ?s . %n"
614 + " ?blank rdf:predicate ?p . %n"
615 + " ?blank rdf:object ?o . %n"
616 + " ?blank rmo:references ?revision . %n"
617 + " } %n"
618 + " GRAPH <%s> { %n"
619 + " ?s ?p ?o %n"
620 + " } %n"
621 + "};", graphNameRevisionProgress, uri, graphNameRevisionProgress, uri, deleteSetURI);
622
623 queryRevision += "\n";
624
625
626 queryRevision += String.format(
627 "INSERT { GRAPH <%s> { %n"
628 + " <%s> a mmo:RevisionProgress; %n"
629 + " mmo:Deleted [ %n"
630 + " rdf:subject ?s ; %n"
631 + " rdf:predicate ?p ; %n"
632 + " rdf:object ?o ; %n"
633 + " rmo:references <%s> %n"
634 + " ] %n"
635 + "} } WHERE { %n"
636 + " GRAPH <%s> %n"
637 + " { ?s ?p ?o . } %n"
638 + "}", graphNameRevisionProgress, uri, changeSet.getChangeSetURI(), deleteSetURI);
639
640
641 TripleStoreInterfaceSingleton.get().executeUpdateQuery(queryRevision);
642
643 } else {
644
645 logger.error("ADD or DELETE set of " + changeSet.getChangeSetURI() + "does not exists.");
646 }
647 logger.info("Revision progress was created.");
648 }
649 }
650
651
652
653
654
655
656
657
658
659
660
661 private void createDifferenceTripleModel(String graphNameDifferenceTripleModel, String graphNameRevisionProgressA, String uriA, String graphNameRevisionProgressB, String uriB, String uriSDG) {
662
663 logger.info("Create the difference triple model");
664 TripleStoreInterfaceSingleton.get().executeUpdateQuery(String.format("DROP SILENT GRAPH <%s>", graphNameDifferenceTripleModel));
665 TripleStoreInterfaceSingleton.get().executeUpdateQuery(String.format("CREATE GRAPH <%s>", graphNameDifferenceTripleModel));
666
667
668 String sparqlTemplateRevisionA = String.format(
669 " GRAPH <%s> { %n"
670 + " <%s> <%s> ?blankA . %n"
671 + " ?blankA rdf:subject ?s . %n"
672 + " ?blankA rdf:predicate ?p . %n"
673 + " ?blankA rdf:object ?o . %n"
674 + " ?blankA rmo:references ?revisionA . %n"
675 + " } %n", graphNameRevisionProgressA, uriA, "%s");
676 String sparqlTemplateRevisionB = String.format(
677 " GRAPH <%s> { %n"
678 + " <%s> <%s> ?blankB . %n"
679 + " ?blankB rdf:subject ?s . %n"
680 + " ?blankB rdf:predicate ?p . %n"
681 + " ?blankB rdf:object ?o . %n"
682 + " ?blankB rmo:references ?revisionB . %n"
683 + " } %n", graphNameRevisionProgressB, uriB, "%s");
684
685 String sparqlTemplateNotExistsRevisionA = String.format(
686 "FILTER NOT EXISTS { %n"
687 + " GRAPH <%s> { %n"
688 + " <%s> ?everything ?blankA . %n"
689 + " ?blankA rdf:subject ?s . %n"
690 + " ?blankA rdf:predicate ?p . %n"
691 + " ?blankA rdf:object ?o . %n"
692 + " ?blankA rmo:references ?revisionA . %n"
693 + " } %n"
694 + "}", graphNameRevisionProgressA, uriA);
695
696 String sparqlTemplateNotExistsRevisionB = String.format(
697 "FILTER NOT EXISTS { %n"
698 + " GRAPH <%s> { %n"
699 + " <%s> ?everything ?blankB . %n"
700 + " ?blankB rdf:subject ?s . %n"
701 + " ?blankB rdf:predicate ?p . %n"
702 + " ?blankB rdf:object ?o . %n"
703 + " ?blankB rmo:references ?revisionB . %n"
704 + " } %n"
705 + "}", graphNameRevisionProgressB, uriB);
706
707
708 String queryDifferingSD = String.format(
709 "PREFIX mmo: <http://eatld.et.tu-dresden.de/mmo#> %n"
710 + "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> %n"
711 + "SELECT ?combinationURI ?tripleStateA ?tripleStateB ?conflict ?automaticResolutionState %n"
712 + "WHERE { GRAPH <%s> { %n"
713 + " <%s> a mmo:StructuralDefinitionGroup ;"
714 + " mmo:hasStructuralDefinition ?combinationURI ."
715 + " ?combinationURI a mmo:StructuralDefinition ; %n"
716 + " mmo:hasTripleStateA ?tripleStateA ; %n"
717 + " mmo:hasTripleStateB ?tripleStateB ; %n"
718 + " mmo:isConflicting ?conflict ; %n"
719 + " mmo:automaticResolutionState ?automaticResolutionState . %n"
720 + "} } %n", Config.sdg_graph, uriSDG);
721
722
723 ResultSet resultSetDifferences = TripleStoreInterfaceSingleton.get().executeSelectQuery(queryDifferingSD);
724 while (resultSetDifferences.hasNext()) {
725 QuerySolution qs = resultSetDifferences.next();
726
727 String currentDifferenceCombinationURI = qs.getResource("?combinationURI").toString();
728 String currentTripleStateA = qs.getResource("?tripleStateA").toString();
729 String currentTripleStateB = qs.getResource("?tripleStateB").toString();
730
731 String currentConflictState = qs.getLiteral("?conflict").toString();
732
733 if (currentConflictState.equals("true^^http://www.w3.org/2001/XMLSchema#boolean")) {
734 currentConflictState = "\"true\"^^<http://www.w3.org/2001/XMLSchema#boolean>";
735 } else {
736 currentConflictState = "\"false\"^^<http://www.w3.org/2001/XMLSchema#boolean>";
737 }
738 String currentAutomaticResolutionState = qs.getResource("?automaticResolutionState").toString();
739
740 String querySelectPart = "SELECT ?s ?p ?o %s %s %n";
741 String sparqlQueryRevisionA = null;
742 String sparqlQueryRevisionB = null;
743
744
745 if (currentTripleStateA.equals(MergeTripleStateEnum.ADDED.getSdRepresentation())) {
746
747 querySelectPart = String.format(querySelectPart, "?revisionA", "%s");
748 sparqlQueryRevisionA = String.format(sparqlTemplateRevisionA, MergeTripleStateEnum.ADDED.getDgRepresentation());
749 } else if (currentTripleStateA.equals(MergeTripleStateEnum.DELETED.getSdRepresentation())) {
750
751 querySelectPart = String.format(querySelectPart, "?revisionA", "%s");
752 sparqlQueryRevisionA = String.format(sparqlTemplateRevisionA, MergeTripleStateEnum.DELETED.getDgRepresentation());
753 } else if (currentTripleStateA.equals(MergeTripleStateEnum.ORIGINAL.getSdRepresentation())) {
754
755 querySelectPart = String.format(querySelectPart, "?revisionA", "%s");
756 sparqlQueryRevisionA = String.format(sparqlTemplateRevisionA, MergeTripleStateEnum.ORIGINAL.getDgRepresentation());
757 } else if (currentTripleStateA.equals(MergeTripleStateEnum.NOTINCLUDED.getSdRepresentation())) {
758
759 querySelectPart = String.format(querySelectPart, "", "%s");
760 sparqlQueryRevisionA = sparqlTemplateNotExistsRevisionA;
761 }
762
763
764 if (currentTripleStateB.equals(MergeTripleStateEnum.ADDED.getSdRepresentation())) {
765
766 querySelectPart = String.format(querySelectPart, "?revisionB");
767 sparqlQueryRevisionB = String.format(sparqlTemplateRevisionB, MergeTripleStateEnum.ADDED.getDgRepresentation());
768 } else if (currentTripleStateB.equals(MergeTripleStateEnum.DELETED.getSdRepresentation())) {
769
770 querySelectPart = String.format(querySelectPart, "?revisionB");
771 sparqlQueryRevisionB = String.format(sparqlTemplateRevisionB, MergeTripleStateEnum.DELETED.getDgRepresentation());
772 } else if (currentTripleStateB.equals(MergeTripleStateEnum.ORIGINAL.getSdRepresentation())) {
773
774 querySelectPart = String.format(querySelectPart, "?revisionB");
775 sparqlQueryRevisionB = String.format(sparqlTemplateRevisionB, MergeTripleStateEnum.ORIGINAL.getDgRepresentation());
776 } else if (currentTripleStateB.equals(MergeTripleStateEnum.NOTINCLUDED.getSdRepresentation())) {
777
778 querySelectPart = String.format(querySelectPart, "");
779 sparqlQueryRevisionB = sparqlTemplateNotExistsRevisionB;
780 }
781
782
783 String query = String.format(
784 Config.prefixes
785 + "%s"
786 + "WHERE { %n"
787 + "%s"
788 + "%s"
789 + "} %n", querySelectPart, sparqlQueryRevisionA, sparqlQueryRevisionB);
790
791
792 ResultSet resultSetTriples = TripleStoreInterfaceSingleton.get().executeSelectQuery(query);
793 while (resultSetTriples.hasNext()) {
794 QuerySolution qsQuery = resultSetTriples.next();
795
796 String subject = qsQuery.getResource("?s").toString();
797 String predicate = qsQuery.getResource("?p").toString();
798
799
800 String object = "";
801 if (qsQuery.get("?o").isLiteral()) {
802 object = "\"" + qsQuery.getLiteral("?o").toString() + "\"";
803 } else {
804 object = "<" + qsQuery.getResource("?o").toString() + ">";
805 }
806
807
808 String referencesAB = ". %n";
809 if (!currentTripleStateA.equals(MergeTripleStateEnum.NOTINCLUDED.getSdRepresentation()) && !currentTripleStateB.equals(MergeTripleStateEnum.NOTINCLUDED.getSdRepresentation())) {
810 referencesAB = String.format(
811 " mmo:referencesA <%s> ; %n"
812 + " mmo:referencesB <%s> %n", qsQuery.getResource("?revisionA").toString(),
813 qsQuery.getResource("?revisionB").toString());
814 } else if (currentTripleStateA.equals(MergeTripleStateEnum.NOTINCLUDED.getSdRepresentation()) && !currentTripleStateB.equals(MergeTripleStateEnum.NOTINCLUDED.getSdRepresentation())) {
815 referencesAB = String.format(
816 " mmo:referencesB <%s> %n", qsQuery.getResource("?revisionB").toString());
817 } else if (!currentTripleStateA.equals(MergeTripleStateEnum.NOTINCLUDED.getSdRepresentation()) && currentTripleStateB.equals(MergeTripleStateEnum.NOTINCLUDED.getSdRepresentation())) {
818 referencesAB = String.format(
819 " mmo:referencesA <%s> %n", qsQuery.getResource("?revisionA").toString());
820 }
821
822 String queryTriple = Config.prefixes + String.format(
823 "INSERT DATA { GRAPH <%s> {%n"
824 + " <%s> a mmo:DifferenceGroup ; %n"
825 + " mmo:hasTripleStateA <%s> ; %n"
826 + " mmo:hasTripleStateB <%s> ; %n"
827 + " mmo:isConflicting %s ; %n"
828 + " mmo:automaticResolutionState <%s> ; %n"
829 + " mmo:hasDifference [ %n"
830 + " a mmo:Difference ; %n"
831 + " mmo:hasTriple [ %n"
832 + " rdf:subject <%s> ; %n"
833 + " rdf:predicate <%s> ; %n"
834 + " rdf:object %s %n"
835 + " ] ; %n"
836 + "%s"
837 + " ] . %n"
838 + "} }", graphNameDifferenceTripleModel,
839 currentDifferenceCombinationURI,
840 currentTripleStateA,
841 currentTripleStateB,
842 currentConflictState,
843 currentAutomaticResolutionState,
844 subject,
845 predicate,
846 object,
847 referencesAB);
848
849 TripleStoreInterfaceSingleton.get().executeUpdateQuery(queryTriple);
850 }
851 }
852 }
853
854 }