1 package org.openprovenance.rdf;
2
3 import javax.xml.bind.JAXBException;
4 import javax.xml.bind.JAXBElement;
5
6 import java.io.ByteArrayOutputStream;
7 import java.io.ByteArrayInputStream;
8 import java.io.IOException;
9 import java.io.File;
10 import java.io.FileInputStream;
11 import java.io.InputStream;
12
13 import java.util.List;
14 import java.util.LinkedList;
15 import java.util.Collection;
16 import java.util.Collections;
17 import java.util.Set;
18 import java.util.HashMap;
19 import java.util.HashSet;
20
21
22 import org.openprovenance.model.OPMGraph;
23 import org.openprovenance.model.Edge;
24 import org.openprovenance.model.Overlaps;
25 import org.openprovenance.model.Account;
26 import org.openprovenance.model.AccountRef;
27 import org.openprovenance.model.Property;
28 import org.openprovenance.model.Processes;
29 import org.openprovenance.model.Node;
30 import org.openprovenance.model.Agent;
31 import org.openprovenance.model.Process;
32 import org.openprovenance.model.Role;
33 import org.openprovenance.model.Artifact;
34 import org.openprovenance.model.Used;
35 import org.openprovenance.model.EmbeddedAnnotation;
36 import org.openprovenance.model.WasGeneratedBy;
37 import org.openprovenance.model.WasTriggeredBy;
38 import org.openprovenance.model.WasDerivedFrom;
39 import org.openprovenance.model.WasControlledBy;
40 import org.openprovenance.model.OPMUtilities;
41 import org.openprovenance.model.OPMFactory;
42 import org.openprovenance.model.OPMSerialiser;
43
44 import org.tupeloproject.kernel.SubjectFacade;
45 import org.tupeloproject.provenance.ProvenanceAccount;
46 import org.tupeloproject.provenance.ProvenanceRole;
47 import org.tupeloproject.provenance.ProvenanceAgent;
48 import org.tupeloproject.provenance.ProvenanceProcess;
49 import org.tupeloproject.provenance.ProvenanceArtifact;
50 import org.tupeloproject.provenance.ProvenanceUsedArc;
51 import org.tupeloproject.provenance.ProvenanceGeneratedArc;
52 import org.tupeloproject.provenance.ProvenanceTriggeredArc;
53 import org.tupeloproject.provenance.ProvenanceDerivedArc;
54 import org.tupeloproject.provenance.ProvenanceControlledArc;
55 import org.tupeloproject.provenance.impl.ProvenanceContextFacade;
56 import org.tupeloproject.provenance.impl.RdfProvenanceElement;
57 import org.tupeloproject.provenance.impl.RdfProvenanceAccount;
58 import org.tupeloproject.provenance.impl.RdfProvenanceRole;
59 import org.tupeloproject.provenance.impl.RdfProvenanceArc;
60 import org.tupeloproject.rdf.Resource;
61 import org.tupeloproject.rdf.Triple;
62 import org.tupeloproject.rdf.xml.RdfXml;
63 import org.tupeloproject.kernel.Context;
64 import org.tupeloproject.kernel.UnionContext;
65 import org.tupeloproject.kernel.impl.ResourceContext;
66 import org.tupeloproject.kernel.impl.MemoryContext;
67 import org.tupeloproject.kernel.impl.FileContext;
68 import org.tupeloproject.kernel.impl.BasicLocalContext;
69 import org.tupeloproject.util.Xml;
70 import org.tupeloproject.kernel.OperatorException;
71
72
73 /***
74 TODO: support for graph-level annotations
75 */
76
77 public class OPMRdf2Xml {
78
79 static String NULL_ACCOUNT=OPMXml2Rdf.NULL_ACCOUNT;
80
81
82
83 OPMUtilities u=new OPMUtilities();
84 OPMFactory pFactory=OPMFactory.getFactory();
85
86 public OPMGraph convert (String filename) throws OperatorException, IOException {
87 return convert(new FileInputStream(new File(filename)));
88 }
89
90 public OPMGraph convert (InputStream in) throws OperatorException, IOException {
91 return convert(RdfXml.parse(in));
92 }
93
94 HashMap<String,Account> accountTable=new HashMap();
95 HashMap<String,Process> processTable=new HashMap();
96 HashMap<String,Artifact> artifactTable=new HashMap();
97 HashMap<String,Agent> agentTable=new HashMap();
98
99 Set<ProvenanceUsedArc> usedArcs=new HashSet();
100 Set<ProvenanceGeneratedArc> generatedArcs=new HashSet();
101 Set<ProvenanceTriggeredArc> triggeredArcs=new HashSet();
102 Set<ProvenanceControlledArc> controlledArcs=new HashSet();
103 Set<ProvenanceDerivedArc> derivedArcs=new HashSet();
104
105 Resource hasAnnotation=Resource.uriRef(OPMXml2Rdf.OPM_HAS_ANNOTATION);
106 Resource hasAccount=Resource.uriRef(OPMXml2Rdf.OPM_HAS_ACCOUNT);
107
108 public OPMGraph convert (Set<Triple> triples) throws OperatorException, IOException {
109
110 Collection<Account> accounts=new LinkedList();
111 Collection<Overlaps> overlaps=new LinkedList();
112 Collection<Process> processes=new LinkedList();
113 Collection<Artifact> artifacts=new LinkedList();
114 Collection<Agent> agents=new LinkedList();
115 Collection<Object> edges=new LinkedList();
116
117 OPMGraph graph=pFactory.newOPMGraph(accounts,
118 overlaps,
119 processes,
120 artifacts,
121 agents,
122 edges);
123
124
125 MemoryContext mc = new MemoryContext();
126
127
128 ResourceContext rc = new ResourceContext("http://example.org/data/","/provenanceExample/");
129 Context context = new UnionContext();
130 context.addChild(mc);
131 context.addChild(rc);
132
133 mc.addTriples(triples);
134
135
136 ProvenanceContextFacade pcf = new ProvenanceContextFacade(mc);
137
138 Collection<Resource> done=new LinkedList();
139
140
141 for (Triple triple: triples) {
142
143 Resource subject=triple.getSubject();
144 if (done.contains(subject)) continue;
145 done.add(subject);
146 RdfProvenanceElement element=pcf.getElement(subject);
147 if (element!=null) {
148
149
150
151
152 if (element instanceof ProvenanceArtifact) {
153 Artifact a=getArtifact((ProvenanceArtifact) element);
154 Collection<ProvenanceUsedArc> used=pcf.getUsedBy((ProvenanceArtifact) element);
155 if (used!=null) {
156 usedArcs.addAll(used);
157 }
158 Collection<ProvenanceGeneratedArc> generated=pcf.getGeneratedBy((ProvenanceArtifact) element);
159 if (generated!=null) {
160 generatedArcs.addAll(generated);
161 }
162 Collection<ProvenanceDerivedArc> derived=pcf.getDerivedFrom((ProvenanceArtifact) element);
163 if (derived!=null) {
164 derivedArcs.addAll(derived);
165 }
166
167
168 SubjectFacade sf=new SubjectFacade(subject, mc) ;
169 java.util.Set<Resource> annotations=sf.getObjects(hasAnnotation);
170 pFactory.addCompactAnnotation(a,convertAnnotations(annotations,pcf,mc));
171
172 }
173
174 if (element instanceof ProvenanceProcess) {
175 Process p=getProcess((ProvenanceProcess)element);
176
177 Collection<ProvenanceTriggeredArc> triggered=pcf.getTriggeredBy((ProvenanceProcess) element);
178 if (triggered!=null) {
179 triggeredArcs.addAll(triggered);
180 }
181
182 SubjectFacade sf=new SubjectFacade(subject, mc) ;
183 java.util.Set<Resource> annotations=sf.getObjects(hasAnnotation);
184 pFactory.addCompactAnnotation(p,convertAnnotations(annotations,pcf,mc));
185
186 }
187
188
189 if (element instanceof ProvenanceAgent) {
190 Agent ag=getAgent((ProvenanceAgent)element);
191
192 Collection<ProvenanceControlledArc> controlled=pcf.getControlled((ProvenanceAgent) element);
193 if (controlled!=null) {
194 controlledArcs.addAll(controlled);
195 }
196
197
198 SubjectFacade sf=new SubjectFacade(subject, mc) ;
199 java.util.Set<Resource> annotations=sf.getObjects(hasAnnotation);
200 pFactory.addCompactAnnotation(ag,convertAnnotations(annotations,pcf,mc));
201 }
202
203 if (element instanceof ProvenanceAccount) {
204 Account acc=getAccount((ProvenanceAccount)element);
205
206 SubjectFacade sf=new SubjectFacade(subject, mc) ;
207 java.util.Set<Resource> annotations=sf.getObjects(hasAnnotation);
208 pFactory.addCompactAnnotation(acc,convertAnnotations(annotations,pcf,mc));
209
210 }
211
212 } else {
213
214 }
215 }
216
217 populateGraph(graph,pcf,mc);
218
219 return graph;
220 }
221
222
223 public List<EmbeddedAnnotation> convertAnnotations(Set<Resource> annotations,
224 ProvenanceContextFacade pcf,
225 Context context)
226 throws org.tupeloproject.kernel.OperatorException {
227
228 List<EmbeddedAnnotation> embedded=new LinkedList();
229 for (Resource annotation: annotations) {
230 SubjectFacade af=new SubjectFacade(annotation, context) ;
231
232
233
234 java.util.Set<Resource> accounts=af.getObjects(hasAccount);
235 List<AccountRef> accRefs=new LinkedList();
236 for (Resource account: accounts) {
237 RdfProvenanceAccount rdfA=pcf.getAccount(account);
238 Account a=getAccount(rdfA);
239 accRefs.add(pFactory.newAccountRef(a));
240 }
241
242 String id=deUrify(annotation.getUri().toString());
243
244
245 Set<Triple> triples=af.getTriples();
246 List<Property> properties=new LinkedList();
247
248 List<JAXBElement<? extends EmbeddedAnnotation>> subAnnotations=new LinkedList();
249 for (Triple t: triples) {
250 Resource predicate=t.getPredicate();
251 String predicateUri=predicate.getUri().toString();
252
253 if ((!(predicateUri.equals(OPMXml2Rdf.OPM_HAS_ACCOUNT)))
254 &&
255 (!(predicateUri.equals("http://www.w3.org/1999/02/22-rdf-syntax-ns#type")))
256 &&
257 (!(predicateUri.equals(OPMXml2Rdf.OPM_HAS_ANNOTATION)))
258 ) {
259
260 Resource object=t.getObject();
261 Object o=object.asObject();
262 properties.add(pFactory.newProperty(predicateUri,o));
263 } else if (predicateUri.equals(OPMXml2Rdf.OPM_HAS_ANNOTATION)) {
264 System.out.println("*********************** Found annotation of annotation !");
265 Resource annotationOfAnnotation=t.getObject();
266 Set<Resource> rl=new HashSet();
267 rl.add(annotationOfAnnotation);
268 for (EmbeddedAnnotation ann: convertAnnotations(rl,pcf,context)) {
269 subAnnotations.add(pFactory.compactAnnotation(ann));
270 };
271 }
272 }
273
274 EmbeddedAnnotation e=pFactory.newEmbeddedAnnotation(id, properties, accRefs, null);
275 pFactory.addAnnotations(e,subAnnotations);
276 embedded.add(e);
277 }
278
279
280 return embedded;
281 }
282
283 void populateGraph(OPMGraph graph,
284 ProvenanceContextFacade pcf,
285 MemoryContext mc) throws org.tupeloproject.kernel.OperatorException {
286 Set<String> artifactUris=artifactTable.keySet();
287 for (String uri: artifactUris) {
288 graph.getArtifacts().getArtifact().add(artifactTable.get(uri));
289 }
290
291 Set<String> processUris=processTable.keySet();
292 for (String uri: processUris) {
293 graph.getProcesses().getProcess().add(processTable.get(uri));
294 }
295
296 Set<String> agentUris=agentTable.keySet();
297 for (String uri: agentUris) {
298 graph.getAgents().getAgent().add(agentTable.get(uri));
299 }
300
301 for (ProvenanceUsedArc used: usedArcs) {
302 ProvenanceArtifact pArtifact=used.getArtifact();
303 Artifact artifact=getArtifact(pArtifact);
304 ProvenanceProcess pProcess=used.getProcess();
305 Process process=getProcess(pProcess);
306 ProvenanceRole pRole=used.getRole();
307 Role role=pFactory.newRole(pRole.getName());
308 ProvenanceAccount pAccount=used.getAccount();
309 Account account=getAccount(pAccount);
310
311 Used u2=pFactory.newUsed(process,role,artifact,Collections.singleton(account));
312 graph.getCausalDependencies().getUsedOrWasGeneratedByOrWasTriggeredBy().add(u2);
313
314 RdfProvenanceArc rpa=(RdfProvenanceArc) used;
315 Resource subject=rpa.getSubject();
316 SubjectFacade sf=new SubjectFacade(subject, mc) ;
317 java.util.Set<Resource> annotations=sf.getObjects(hasAnnotation);
318 pFactory.addCompactAnnotation(u2,convertAnnotations(annotations,pcf,mc));
319
320 RdfProvenanceRole rdfRole=(RdfProvenanceRole) pRole;
321 Resource roleSubject=rdfRole.getSubject();
322 SubjectFacade roleSf=new SubjectFacade(roleSubject, mc) ;
323 java.util.Set<Resource> roleAnnotations=roleSf.getObjects(hasAnnotation);
324 pFactory.addCompactAnnotation(role,convertAnnotations(roleAnnotations,pcf,mc));
325
326
327
328 }
329
330
331 for (ProvenanceGeneratedArc generated: generatedArcs) {
332 ProvenanceArtifact pArtifact=generated.getArtifact();
333 Artifact artifact=getArtifact(pArtifact);
334 ProvenanceProcess pProcess=generated.getProcess();
335 Process process=getProcess(pProcess);
336 ProvenanceRole pRole=generated.getRole();
337 Role role=pFactory.newRole(pRole.getName());
338 ProvenanceAccount pAccount=generated.getAccount();
339 Account account=getAccount(pAccount);
340
341 WasGeneratedBy g2=pFactory.newWasGeneratedBy(artifact,role,process,Collections.singleton(account));
342 graph.getCausalDependencies().getUsedOrWasGeneratedByOrWasTriggeredBy().add(g2);
343
344 RdfProvenanceArc rpa=(RdfProvenanceArc) generated;
345 Resource subject=rpa.getSubject();
346 SubjectFacade sf=new SubjectFacade(subject, mc) ;
347 java.util.Set<Resource> annotations=sf.getObjects(hasAnnotation);
348 pFactory.addCompactAnnotation(g2,convertAnnotations(annotations,pcf,mc));
349
350
351
352 RdfProvenanceRole rdfRole=(RdfProvenanceRole) pRole;
353 Resource roleSubject=rdfRole.getSubject();
354 SubjectFacade roleSf=new SubjectFacade(roleSubject, mc) ;
355 java.util.Set<Resource> roleAnnotations=roleSf.getObjects(hasAnnotation);
356 pFactory.addCompactAnnotation(role,convertAnnotations(roleAnnotations,pcf,mc));
357
358
359
360 }
361
362
363 for (ProvenanceControlledArc controlled: controlledArcs) {
364 ProvenanceAgent pAgent=controlled.getAgent();
365 Agent agent=getAgent(pAgent);
366 ProvenanceProcess pProcess=controlled.getProcess();
367 Process process=getProcess(pProcess);
368 ProvenanceRole pRole=controlled.getRole();
369 Role role=pFactory.newRole(pRole.getName());
370 ProvenanceAccount pAccount=controlled.getAccount();
371 Account account=getAccount(pAccount);
372
373 WasControlledBy g2=pFactory.newWasControlledBy(process,role,agent,Collections.singleton(account));
374 graph.getCausalDependencies().getUsedOrWasGeneratedByOrWasTriggeredBy().add(g2);
375
376 RdfProvenanceRole rdfRole=(RdfProvenanceRole) pRole;
377 Resource roleSubject=rdfRole.getSubject();
378 SubjectFacade roleSf=new SubjectFacade(roleSubject, mc) ;
379 java.util.Set<Resource> roleAnnotations=roleSf.getObjects(hasAnnotation);
380 pFactory.addCompactAnnotation(role,convertAnnotations(roleAnnotations,pcf,mc));
381
382
383 }
384
385
386 for (ProvenanceDerivedArc derived: derivedArcs) {
387 ProvenanceArtifact pArtifact1=derived.getAntecedent();
388 Artifact artifact1=getArtifact(pArtifact1);
389 ProvenanceArtifact pArtifact2=derived.getConsequent();
390 Artifact artifact2=getArtifact(pArtifact2);
391 ProvenanceAccount pAccount=derived.getAccount();
392 Account account=getAccount(pAccount);
393
394 WasDerivedFrom d2=pFactory.newWasDerivedFrom(artifact2,artifact1,Collections.singleton(account));
395 graph.getCausalDependencies().getUsedOrWasGeneratedByOrWasTriggeredBy().add(d2);
396
397 RdfProvenanceArc rpa=(RdfProvenanceArc) derived;
398 Resource subject=rpa.getSubject();
399 SubjectFacade sf=new SubjectFacade(subject, mc) ;
400 java.util.Set<Resource> annotations=sf.getObjects(hasAnnotation);
401 pFactory.addCompactAnnotation(d2,convertAnnotations(annotations,pcf,mc));
402
403 }
404
405
406 for (ProvenanceTriggeredArc triggered: triggeredArcs) {
407 ProvenanceProcess pProcess1=triggered.getAntecedent();
408 Process process1=getProcess(pProcess1);
409 ProvenanceProcess pProcess2=triggered.getConsequent();
410 Process process2=getProcess(pProcess2);
411 ProvenanceAccount pAccount=triggered.getAccount();
412 Account account=getAccount(pAccount);
413
414 WasTriggeredBy t2=pFactory.newWasTriggeredBy(process2,process1,Collections.singleton(account));
415 graph.getCausalDependencies().getUsedOrWasGeneratedByOrWasTriggeredBy().add(t2);
416
417
418 RdfProvenanceArc rpa=(RdfProvenanceArc) triggered;
419 Resource subject=rpa.getSubject();
420 SubjectFacade sf=new SubjectFacade(subject, mc) ;
421 java.util.Set<Resource> annotations=sf.getObjects(hasAnnotation);
422 pFactory.addCompactAnnotation(t2,convertAnnotations(annotations,pcf,mc));
423
424
425 }
426
427 Set<String> accountNames=accountTable.keySet();
428 for (String name: accountNames) {
429 graph.getAccounts().getAccount().add(accountTable.get(name));
430 }
431
432
433
434 }
435
436 Account getAccount(ProvenanceAccount pa) {
437 String name=pa.getName();
438
439 Account acc=accountTable.get(name);
440 if (acc==null) {
441 Account a=pFactory.newAccount(name);
442 accountTable.put(name,a);
443 return a;
444 } else {
445 return acc;
446 }
447 }
448
449 Agent getAgent(ProvenanceAgent pa) {
450 String name=pa.getName();
451 String uri=((RdfProvenanceElement)pa).getSubject().getUri().toString();
452 String id=deUrify(uri);
453
454 Agent ag=agentTable.get(uri);
455 if (ag==null) {
456 Agent a=pFactory.newAgent(id, null);
457 agentTable.put(uri,a);
458 return a;
459 } else {
460 return ag;
461 }
462 }
463
464 Artifact getArtifact(ProvenanceArtifact pa) {
465 String name=pa.getName();
466 String uri=((RdfProvenanceElement)pa).getSubject().getUri().toString();
467 String id=deUrify(uri);
468
469 Artifact a=artifactTable.get(uri);
470 if (a==null) {
471 Artifact a2=pFactory.newArtifact(id, null);
472 artifactTable.put(uri,a2);
473 return a2;
474 } else {
475 return a;
476 }
477 }
478
479
480 Process getProcess(ProvenanceProcess pa) {
481 String name=pa.getName();
482 String uri=((RdfProvenanceElement)pa).getSubject().getUri().toString();
483 String id=deUrify(uri);
484
485 Process p=processTable.get(uri);
486 if (p==null) {
487 Process a=pFactory.newProcess(id, null);
488 processTable.put(uri,a);
489 return a;
490 } else {
491 return p;
492 }
493 }
494
495
496
497
498 public String deUrify(String id) {
499 if (id.startsWith(OPMXml2Rdf.URI_PREFIX)) {
500 return id.substring(OPMXml2Rdf.URI_PREFIX.length(),id.length());
501 } else {
502 return id;
503 }
504
505 }
506
507
508 public void convert (String inFilename, String outFilename) throws OperatorException, IOException, JAXBException {
509 OPMGraph graph=convert(inFilename);
510
511 OPMSerialiser serial=OPMSerialiser.getThreadOPMSerialiser();
512 serial.serialiseOPMGraph(new File(outFilename),graph,true);
513
514 }
515
516 public static void main(String [] args) throws OperatorException, IOException, JAXBException {
517 if ((args==null) || (args.length!=2)) {
518 System.out.println("Usage: opmrdf2xml fileIn fileOut");
519 return;
520 }
521 OPMRdf2Xml converter=new OPMRdf2Xml();
522 converter.convert(args[0],args[1]);
523 }
524
525
526 }