public void exportAsW3Prov()

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);
        }

    }