in taverna-prov/src/main/java/org/apache/taverna/prov/W3ProvenanceExport.java [255:431]
public void exportAsW3Prov() throws IOException {
Path provFile = DataBundles.getWorkflowRunProvenance(bundle);
// TODO: Make this thread safe using contexts?
GregorianCalendar startedProvExportAt = new GregorianCalendar();
runURI = URI.create(uriGenerator.makeWFInstanceURI(getWorkflowRunId()));
URI provFileUri = toURI(provFile);
Individual bundle = provModel.createBundle(provFileUri);
// Mini-provenance about this provenance trace. Unkown URI for
// agent/activity
Individual storeProvenance = provModel.createActivity(provFileUri
.resolve("#taverna-prov-export"));
storeProvenance.setLabel(
"taverna-prov export of workflow run provenance", EN);
provModel.setStartedAtTime(storeProvenance, startedProvExportAt);
// The agent is an execution of the Taverna software (e.g. also an
// Activity)
Individual tavernaAgent = provModel.createTavernaEngine(provFileUri
.resolve("#taverna-engine"));
Individual plan = provModel
.createPlan(getTavernaVersion());
plan.setLabel(applicationConfig.getTitle(), EN);
provModel.setWasAssociatedWith(storeProvenance, tavernaAgent, plan);
provModel.setWasGeneratedBy(bundle, storeProvenance);
Individual wfProcess = provModel.createWorkflowRun(runURI);
bundle.setPropertyValue(FOAF.primaryTopic, wfProcess);
DataflowInvocation dataflowInvocation = provenanceAccess
.getDataflowInvocation(getWorkflowRunId());
// TODO: Should we go through all of getDataflowInvocations() in order
// to find
// the plans etc. for the nested workflow executions and also cover
// empty
// nested workflow runs?
String workflowName = provenanceAccess
.getWorkflowNameByWorkflowID(dataflowInvocation.getWorkflowId());
label(wfProcess, "Workflow run of " + workflowName);
provModel.setWasInformedBy(storeProvenance, wfProcess);
String wfUri = uriGenerator.makeWorkflowURI(dataflowInvocation
.getWorkflowId());
Individual wfPlan = provModel.createWorkflow(URI.create(wfUri));
provModel.setWasEnactedBy(wfProcess, tavernaAgent, wfPlan);
provModel.setDescribedByWorkflow(wfProcess, wfPlan);
provModel.setStartedAtTime(wfProcess,
timestampToLiteral(dataflowInvocation.getInvocationStarted()));
provModel.setEndedAtTime(wfProcess,
timestampToLiteral(dataflowInvocation.getInvocationEnded()));
// Workflow inputs and outputs
storeEntitities(dataflowInvocation.getInputsDataBindingId(), wfProcess,
Direction.INPUTS, true);
// FIXME: These entities come out as "generated" by multiple processes
storeEntitities(dataflowInvocation.getOutputsDataBindingId(),
wfProcess, Direction.OUTPUTS, true);
List<ProcessorEnactment> processorEnactments = provenanceAccess
.getProcessorEnactments(getWorkflowRunId());
// This will also include processor enactments in nested workflows
for (ProcessorEnactment pe : processorEnactments) {
String parentId = pe.getParentProcessorEnactmentId();
URI parentURI;
if (parentId == null) {
// Top-level workflow
parentURI = runURI;
} else {
// inside nested wf - this will be parent processenactment
parentURI = URI.create(uriGenerator.makeProcessExecution(
pe.getWorkflowRunId(),
pe.getParentProcessorEnactmentId()));
// TODO: Find plan for nested workflow!
// String wfUri = uriGenerator.makeWorkflowURI(nestedWfId);
// Individual wfPlan =
// provModel.createWorkflow(URI.create(wfUri));
// provModel.setDescribedByWorkflow(wfProcess, wfPlan);
// provModel.setWasEnactedBy(wfProcess, tavernaAgent, wfPlan);
}
URI processURI = URI.create(uriGenerator.makeProcessExecution(
pe.getWorkflowRunId(), pe.getProcessEnactmentId()));
Individual process = provModel.createProcessRun(processURI);
Individual parentProcess = provModel.createWorkflowRun(parentURI);
provModel.setWasPartOfWorkflowRun(process, parentProcess);
provModel.setStartedAtTime(process,
timestampToLiteral(pe.getEnactmentStarted()));
provModel.setEndedAtTime(process,
timestampToLiteral(pe.getEnactmentEnded()));
ProvenanceProcessor provenanceProcessor = provenanceAccess
.getProvenanceProcessor(pe.getProcessorId());
URI processorURI = URI.create(uriGenerator.makeProcessorURI(
provenanceProcessor.getProcessorName(),
provenanceProcessor.getWorkflowId()));
label(process,
"Processor execution "
+ provenanceProcessor.getProcessorName());
// The facade identifier is a bit too techie!
// + " ("
// + pe.getProcessIdentifier() + ")");
Individual procPlan = provModel.createProcess(processorURI);
label(procPlan,
"Processor " + provenanceProcessor.getProcessorName());
provModel.setWasEnactedBy(process, tavernaAgent, procPlan);
provModel.setDescribedByProcess(process, procPlan);
URI parentWfUri = URI.create(uriGenerator
.makeWorkflowURI(provenanceProcessor.getWorkflowId()));
Individual parentWf = provModel.createWorkflow(parentWfUri);
provModel.addSubProcess(parentWf, procPlan);
// TODO: How to link together iterations on a single processor and
// the collections
// they are iterating over and creating?
// Need 'virtual' ProcessExecution for iteration?
// TODO: Activity/service details from definition?
// Inputs and outputs
storeEntitities(pe.getInitialInputsDataBindingId(), process,
Direction.INPUTS, false);
storeEntitities(pe.getFinalOutputsDataBindingId(), process,
Direction.OUTPUTS, false);
}
storeFileReferences();
provModel.setEndedAtTime(storeProvenance, new GregorianCalendar());
// provModel.model.write(outStream, "TURTLE",
// provFileUri.toASCIIString());
OntModel model = provModel.model;
try (OutputStream outStream = Files.newOutputStream(provFile)) {
WriterGraphRIOT writer = RDFDataMgr
.createGraphWriter(RDFFormat.TURTLE_BLOCKS);
writer.write(outStream, model.getBaseModel().getGraph(),
RiotLib.prefixMap(model.getGraph()),
provFileUri.toString(), new Context());
} finally {
// Avoid registering the RIOT readers/writers from ARQ, as that
// won't
// work within Raven or OSGi
provModel.resetJena();
logger.warn("Reset Jena readers and writers");
}
byte[] dataflow = getDataflow(dataflowInvocation);
try {
WorkflowBundle wfBundle = wfBundleIO.readBundle(
new ByteArrayInputStream(dataflow),
T2FlowReader.APPLICATION_VND_TAVERNA_T2FLOW_XML);
writeBundle(wfBundle);
} catch (ReaderException e) {
logger.warn("Could not write bundle", e);
}
}