1 package de.tud.plt.r43ples.core;
2
3 import de.tud.plt.r43ples.exception.InternalErrorException;
4 import de.tud.plt.r43ples.exception.QueryErrorException;
5 import de.tud.plt.r43ples.existentobjects.*;
6 import de.tud.plt.r43ples.management.Config;
7 import de.tud.plt.r43ples.management.R43plesRequest;
8 import de.tud.plt.r43ples.iohelper.Helper;
9 import de.tud.plt.r43ples.optimization.PathCalculationFabric;
10 import de.tud.plt.r43ples.optimization.PathCalculationInterface;
11 import org.apache.logging.log4j.LogManager;
12 import org.apache.logging.log4j.Logger;
13
14 import java.util.ArrayList;
15 import java.util.Iterator;
16 import java.util.regex.Matcher;
17 import java.util.regex.Pattern;
18
19
20
21
22
23
24 public class PickCommitDraft extends CommitDraft {
25
26
27 private Logger logger = LogManager.getLogger(PickCommitDraft.class);
28
29
30 private final int patternModifier = Pattern.DOTALL + Pattern.MULTILINE + Pattern.CASE_INSENSITIVE;
31
32 private final Pattern patternPickQuery = Pattern.compile(
33 "PICK\\s*GRAPH\\s*<(?<graph>[^>]*?)>\\s*REVISION\\s*\"(?<startRevisionIdentifier>[^\"]*?)\"\\s*(TO\\s*REVISION\\s*\"(?<endRevisionIdentifier>[^\"]*?)\"\\s*)?INTO\\s*BRANCH\\s*\"(?<targetBranchIdentifier>[^\"]*?)\"\"",
34 patternModifier);
35
36
37 private String startRevisionIdentifier;
38
39 private String endRevisionIdentifier;
40
41 private String targetBranchIdentifier;
42
43 private String graphName;
44
45 private RevisionGraph revisionGraph;
46
47
48 private boolean isCreatedWithRequest;
49
50
51
52 private PathCalculationInterface pathCalculationInterface;
53
54
55
56
57
58
59
60
61 public PickCommitDraft(R43plesRequest request) throws InternalErrorException {
62 super(request);
63
64 this.extractRequestInformation();
65 this.isCreatedWithRequest = true;
66 this.pathCalculationInterface = PathCalculationFabric.getInstance(this.revisionGraph);
67 }
68
69
70
71
72
73
74
75
76
77
78
79
80
81 protected PickCommitDraft(String graphName, String startRevisionIdentifier, String endRevisionIdentifier, String targetBranchIdentifier, String user, String message) throws InternalErrorException {
82 super(null);
83
84 this.setUser(user);
85 this.setMessage(message);
86
87 this.graphName = graphName;
88 this.revisionGraph = new RevisionGraph(graphName);
89 this.startRevisionIdentifier = startRevisionIdentifier;
90 this.endRevisionIdentifier = endRevisionIdentifier;
91 this.targetBranchIdentifier = targetBranchIdentifier;
92 this.pathCalculationInterface = PathCalculationFabric.getInstance(this.revisionGraph);
93
94 this.isCreatedWithRequest = false;
95 }
96
97
98
99
100
101
102 private void extractRequestInformation() throws InternalErrorException {
103 Matcher m = patternPickQuery.matcher(getRequest().query_sparql);
104
105 boolean foundEntry = false;
106
107 while (m.find()) {
108 foundEntry = true;
109
110 graphName = m.group("graph");
111 revisionGraph = new RevisionGraph(graphName);
112
113 startRevisionIdentifier = m.group("startRevisionIdentifier");
114 endRevisionIdentifier = m.group("endRevisionIdentifier");
115 targetBranchIdentifier = m.group("targetBranchIdentifier");
116
117 logger.debug("graph: " + graphName);
118 logger.debug("startRevisionIdentifier: " + startRevisionIdentifier);
119 logger.debug("endRevisionIdentifier: " + endRevisionIdentifier);
120 logger.debug("targetBranchIdentifier: " + targetBranchIdentifier);
121 }
122 if (!foundEntry) {
123 throw new QueryErrorException("Error in query: " + getRequest().query_sparql);
124 }
125 }
126
127
128
129
130
131
132
133
134 protected PickCommit createCommitInTripleStore() throws InternalErrorException {
135
136 if (!getUriCalculator().checkNamedGraphExistence(graphName)) {
137 logger.warn("Graph <" + graphName + "> does not exist.");
138 throw new InternalErrorException("Graph <" + graphName + "> does not exist.");
139 }
140
141
142 if (!(revisionGraph.hasBranch(targetBranchIdentifier))) {
143 throw new InternalErrorException("No terminal nodes were used");
144 }
145
146 ArrayList<Revision> usedSourceRevisions = new ArrayList<>();
147 ArrayList<Revision> generatedRevisions = new ArrayList<>();
148
149 Branch usedTargetBranch = revisionGraph.getBranch(targetBranchIdentifier, true);
150 Revision usedTargetRevision = new Revision(revisionGraph, revisionGraph.getRevisionUri(targetBranchIdentifier), false);
151 Path path = null;
152 Revision startRevision = new Revision(revisionGraph, startRevisionIdentifier, true);
153 Revision endRevision;
154 if (endRevisionIdentifier != null) {
155 endRevision = new Revision(revisionGraph, endRevisionIdentifier, true);
156 path = pathCalculationInterface.getPathBetweenStartAndTargetRevision(endRevision, startRevision);
157 }
158
159 String commitURI = getUriCalculator().getNewPickCommitURI(revisionGraph, startRevisionIdentifier, endRevisionIdentifier, targetBranchIdentifier, usedTargetRevision.getRevisionIdentifier());
160
161
162 Revision generatedRevision = null;
163 if ((path == null) || (path.getRevisionPath().size() == 1)) {
164 generatedRevision = copyRevisionToTargetBranch(startRevision, usedTargetBranch, commitURI);
165 usedSourceRevisions.add(startRevision);
166 generatedRevisions.add(generatedRevision);
167
168
169 moveBranchReference(revisionGraph.getRevisionGraphUri(), usedTargetBranch.getReferenceURI(), usedTargetRevision.getRevisionURI(), generatedRevision.getRevisionURI());
170
171
172 usedTargetBranch = revisionGraph.getBranch(targetBranchIdentifier, true);
173 } else {
174 Iterator<Revision> iteRev = path.getRevisionPath().iterator();
175 while(iteRev.hasNext()) {
176 Revision currentRevision = iteRev.next();
177 generatedRevision = copyRevisionToTargetBranch(currentRevision, usedTargetBranch, commitURI);
178 usedSourceRevisions.add(currentRevision);
179 generatedRevisions.add(generatedRevision);
180
181
182 moveBranchReference(revisionGraph.getRevisionGraphUri(), usedTargetBranch.getReferenceURI(), usedTargetRevision.getRevisionURI(), generatedRevision.getRevisionURI());
183
184
185 usedTargetBranch = revisionGraph.getBranch(targetBranchIdentifier, true);
186 }
187 }
188
189 return addMetaInformation(usedTargetRevision, usedTargetBranch, commitURI, usedSourceRevisions, generatedRevisions);
190 }
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205 private PickCommit addMetaInformation(Revision usedTargetRevision, Branch usedTargetBranch, String commitURI, ArrayList<Revision> usedSourceRevisions, ArrayList<Revision> generatedRevisions) throws InternalErrorException {
206
207 String personUri = Helper.getUserURI(getUser());
208
209
210 StringBuilder queryContent = new StringBuilder(1000);
211 queryContent.append(String.format(
212 "<%s> a rmo:PickCommit, rmo:MergeCommit, rmo:Commit; %n"
213 + " rmo:wasAssociatedWith <%s> ; %n"
214 + " rmo:commitMessage \"%s\" ; %n"
215 + " rmo:timeStamp \"%s\"^^xsd:dateTime ; %n"
216 + " rmo:usedTargetRevision <%s> ; %n"
217 + " rmo:usedTargetBranch <%s> ; %n",
218 commitURI, personUri, getMessage(), getTimeStamp(),
219 usedTargetRevision.getRevisionURI(), usedTargetBranch.getReferenceURI()));
220
221 String query = Config.prefixes
222 + String.format("INSERT DATA { GRAPH <%s> { %s } }", revisionGraph.getRevisionGraphUri(),
223 queryContent.toString());
224
225 getTripleStoreInterface().executeUpdateQuery(query);
226
227 return new PickCommit(revisionGraph, commitURI, getUser(), getTimeStamp(), getMessage(), usedSourceRevisions, usedTargetRevision, usedTargetBranch, generatedRevisions);
228 }
229
230
231
232
233
234
235
236
237
238
239 private Revision copyRevisionToTargetBranch(Revision revisionToCopy, Branch targetBranch, String commitURI) throws InternalErrorException {
240
241 String addSetContent = revisionToCopy.getChangeSet().getAddSetContent();
242 String deleteSetContent = revisionToCopy.getChangeSet().getDeleteSetContent();
243
244 RevisionDraft revisionDraft = new RevisionDraft(getUriCalculator(), revisionGraph, targetBranch, addSetContent, deleteSetContent, false);
245 Revision generatedRevision = revisionDraft.createInTripleStore();
246
247
248 StringBuilder queryContentInsert = new StringBuilder(1000);
249 queryContentInsert.append(String.format(
250 "<%1$s> rmo:wasQuotedFrom <%2$s> . "
251 + "<%3$s> prov:generated <%1$s> ; "
252 + " rmo:hasChangeSet <%4$s> ;"
253 + " rmo:usedSourceRevision <%2$s> .",
254 generatedRevision.getRevisionURI(), revisionToCopy.getRevisionURI(), commitURI, generatedRevision.getChangeSet().getChangeSetURI()));
255
256 String query = Config.prefixes + String.format(""
257 + "INSERT DATA { GRAPH <%1$s> { %2$s } }",
258 revisionGraph.getRevisionGraphUri(), queryContentInsert.toString());
259 getTripleStoreInterface().executeUpdateQuery(query);
260
261 return generatedRevision;
262 }
263
264 }