package org.apache.taverna.scufl2.rdfxml; /* * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * */ import static java.lang.Boolean.TRUE; import static java.util.logging.Level.FINE; import static java.util.logging.Level.WARNING; import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI; import static javax.xml.bind.Marshaller.JAXB_FORMATTED_OUTPUT; import java.io.IOException; import java.io.OutputStream; import java.net.URI; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Stack; import java.util.logging.Logger; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBElement; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import org.apache.taverna.scufl2.api.activity.Activity; import org.apache.taverna.scufl2.api.annotation.Annotation; import org.apache.taverna.scufl2.api.common.Typed; import org.apache.taverna.scufl2.api.common.URITools; import org.apache.taverna.scufl2.api.common.Visitor; import org.apache.taverna.scufl2.api.common.WorkflowBean; import org.apache.taverna.scufl2.api.configurations.Configuration; import org.apache.taverna.scufl2.api.container.WorkflowBundle; import org.apache.taverna.scufl2.api.core.BlockingControlLink; import org.apache.taverna.scufl2.api.core.DataLink; import org.apache.taverna.scufl2.api.core.Processor; import org.apache.taverna.scufl2.api.core.Workflow; import org.apache.taverna.scufl2.api.io.WriterException; import org.apache.taverna.scufl2.api.iterationstrategy.CrossProduct; import org.apache.taverna.scufl2.api.iterationstrategy.DotProduct; import org.apache.taverna.scufl2.api.iterationstrategy.IterationStrategyStack; import org.apache.taverna.scufl2.api.iterationstrategy.IterationStrategyTopNode; import org.apache.taverna.scufl2.api.iterationstrategy.PortNode; import org.apache.taverna.scufl2.api.port.InputActivityPort; import org.apache.taverna.scufl2.api.port.InputProcessorPort; import org.apache.taverna.scufl2.api.port.InputWorkflowPort; import org.apache.taverna.scufl2.api.port.OutputActivityPort; import org.apache.taverna.scufl2.api.port.OutputProcessorPort; import org.apache.taverna.scufl2.api.port.OutputWorkflowPort; import org.apache.taverna.scufl2.api.profiles.ProcessorBinding; import org.apache.taverna.scufl2.api.profiles.ProcessorInputPortBinding; import org.apache.taverna.scufl2.api.profiles.ProcessorOutputPortBinding; import org.apache.taverna.scufl2.api.profiles.Profile; import org.apache.taverna.scufl2.rdfxml.impl.NamespacePrefixMapperJAXB_RI; import org.apache.taverna.scufl2.ucfpackage.UCFPackage; import org.apache.taverna.scufl2.xml.rdf.RDF; import org.apache.taverna.scufl2.xml.rdf.Resource; import org.apache.taverna.scufl2.xml.rdf.Type; import org.apache.taverna.scufl2.xml.rdfs.SeeAlso; import org.xml.sax.SAXException; import org.apache.taverna.scufl2.xml.Blocking; import org.apache.taverna.scufl2.xml.Control; import org.apache.taverna.scufl2.xml.DataLink.MergePosition; import org.apache.taverna.scufl2.xml.DataLinkEntry; import org.apache.taverna.scufl2.xml.GranularPortDepth; import org.apache.taverna.scufl2.xml.IterationStrategyStack.IterationStrategies; import org.apache.taverna.scufl2.xml.ObjectFactory; import org.apache.taverna.scufl2.xml.PortDepth; import org.apache.taverna.scufl2.xml.PortNode.DesiredDepth; import org.apache.taverna.scufl2.xml.ProcessorBinding.ActivityPosition; import org.apache.taverna.scufl2.xml.ProcessorBinding.InputPortBinding; import org.apache.taverna.scufl2.xml.ProcessorBinding.OutputPortBinding; import org.apache.taverna.scufl2.xml.ProductOf; import org.apache.taverna.scufl2.xml.ProfileDocument; import org.apache.taverna.scufl2.xml.SeeAlsoType; import org.apache.taverna.scufl2.xml.WorkflowBundleDocument; import org.apache.taverna.scufl2.xml.WorkflowDocument; public class RDFXMLSerializer { private static final String DOT_RDF = ".rdf"; protected static final URI OA = URI.create("http://www.w3.org/ns/oa#"); protected static final URI PAV = URI.create("http://purl.org/pav/"); private static boolean warnedOnce = false; public class ProfileSerialisationVisitor implements Visitor { private org.apache.taverna.scufl2.xml.Activity activity; private final ProfileDocument doc; private org.apache.taverna.scufl2.xml.Profile profileElem; private Profile profile; private org.apache.taverna.scufl2.xml.ProcessorBinding processorBindingElem; public ProfileSerialisationVisitor(ProfileDocument doc) { this.doc = doc; } private void activity(Activity node) { activity = objectFactory.createActivity(); activity.setAbout(uri(node)); activity.setType(type(node)); activity.setName(node.getName()); doc.getAny().add(activity); } private void configuration(Configuration node) { org.apache.taverna.scufl2.xml.Configuration configuration = objectFactory .createConfiguration(); configuration.setConfigure(resource(uri(node.getConfigures()))); configuration.setName(node.getName()); configuration.setType(type(node)); URI configUri = uriTools.relativeUriForBean(node, profile); String jsonPath = configUri.toString().replaceFirst("/$", ".json"); URI profilePath = uriTools.relativeUriForBean(profile, profile.getParent()); String bundlePath = profilePath + jsonPath; UCFPackage bundle = profile.getParent().getResources(); try { bundle.addResource(node.getJsonAsString(), bundlePath, "application/json"); } catch (IOException e) { logger.log(WARNING, "Can't save JSON to " + bundlePath, e); } configuration.setAbout(configUri.toString()); SeeAlso seeAlso = rdfsObjectFactory.createSeeAlso(); seeAlso.setResource(jsonPath); configuration.setSeeAlso(seeAlso); // TODO: No way in API to mark non-activated configurations profileElem.getActivateConfiguration().add(resource(uri(node))); doc.getAny().add(configuration); } private GranularPortDepth granularPortDepth(Integer integer) { if (integer == null) return null; GranularPortDepth p = objectFactory.createGranularPortDepth(); p.setValue(integer); p.setDatatype(p.getDatatype()); return p; } private void inputActivityPort(InputActivityPort node) { org.apache.taverna.scufl2.xml.InputActivityPort inputActivityPort = objectFactory .createInputActivityPort(); inputActivityPort.setAbout(uri(node)); inputActivityPort.setName(node.getName()); inputActivityPort.setPortDepth(portDepth(node.getDepth())); org.apache.taverna.scufl2.xml.Activity.InputActivityPort wrapper = objectFactory .createActivityInputActivityPort(); wrapper.setInputActivityPort(inputActivityPort); activity.getInputActivityPort().add(wrapper); } private void outputActivityPort(OutputActivityPort node) { org.apache.taverna.scufl2.xml.OutputActivityPort outputActivityPort = objectFactory .createOutputActivityPort(); outputActivityPort.setAbout(uri(node)); outputActivityPort.setName(node.getName()); outputActivityPort.setPortDepth(portDepth(node.getDepth())); outputActivityPort.setGranularPortDepth(granularPortDepth(node .getGranularDepth())); org.apache.taverna.scufl2.xml.Activity.OutputActivityPort wrapper = objectFactory .createActivityOutputActivityPort(); wrapper.setOutputActivityPort(outputActivityPort); activity.getOutputActivityPort().add(wrapper); } private PortDepth portDepth(Integer integer) { if (integer == null) return null; PortDepth p = objectFactory.createPortDepth(); p.setValue(integer); p.setDatatype(p.getDatatype()); return p; } private void processorBinding(ProcessorBinding node) { processorBindingElem = objectFactory.createProcessorBinding(); processorBindingElem.setAbout(uri(node)); processorBindingElem.setName(node.getName()); processorBindingElem.setBindActivity(resource(uri(node .getBoundActivity()))); processorBindingElem.setBindProcessor(resource(uri(node .getBoundProcessor()))); if (node.getActivityPosition() != null) { ActivityPosition value = new ActivityPosition(); value.setDatatype(value.getDatatype()); value.setValue(node.getActivityPosition()); processorBindingElem.setActivityPosition(value); } profileElem.getProcessorBinding().add(resource(uri(node))); doc.getAny().add(processorBindingElem); } private void processorInputPortBinding(ProcessorInputPortBinding node) { org.apache.taverna.scufl2.xml.InputPortBinding inputBinding = objectFactory .createInputPortBinding(); inputBinding.setAbout(uri(node)); inputBinding.setBindInputActivityPort(resource(uri(node .getBoundActivityPort()))); inputBinding.setBindInputProcessorPort(resource(uri(node .getBoundProcessorPort()))); InputPortBinding b = objectFactory .createProcessorBindingInputPortBinding(); b.setInputPortBinding(inputBinding); processorBindingElem.getInputPortBinding().add(b); } private void processorOutputPortBinding(ProcessorOutputPortBinding node) { org.apache.taverna.scufl2.xml.OutputPortBinding outputBinding = objectFactory .createOutputPortBinding(); outputBinding.setAbout(uri(node)); outputBinding.setBindOutputActivityPort(resource(uri(node .getBoundActivityPort()))); outputBinding.setBindOutputProcessorPort(resource(uri(node .getBoundProcessorPort()))); OutputPortBinding b = objectFactory .createProcessorBindingOutputPortBinding(); b.setOutputPortBinding(outputBinding); processorBindingElem.getOutputPortBinding().add(b); } private void profile(Profile node) { profile = node; profileElem = objectFactory.createProfile(); profileElem.setAbout(uri(node)); profileElem.setName(node.getName()); doc.getAny().add(profileElem); } private String uri(WorkflowBean node) { return uriTools.relativeUriForBean(node, profile).toASCIIString(); } @Override public boolean visit(WorkflowBean node) { if (node instanceof Profile) profile((Profile) node); else if (node instanceof Activity) activity((Activity) node); else if (node instanceof InputActivityPort) inputActivityPort((InputActivityPort) node); else if (node instanceof OutputActivityPort) outputActivityPort((OutputActivityPort) node); else if (node instanceof ProcessorBinding) processorBinding((ProcessorBinding) node); else if (node instanceof ProcessorInputPortBinding) processorInputPortBinding((ProcessorInputPortBinding) node); else if (node instanceof ProcessorOutputPortBinding) processorOutputPortBinding((ProcessorOutputPortBinding) node); else if (node instanceof Configuration) configuration((Configuration) node); else throw new IllegalStateException("Unexpected node " + node); return true; } @Override public boolean visitEnter(WorkflowBean node) { return visit(node); } @Override public boolean visitLeave(WorkflowBean node) { return true; } } public class WorkflowSerialisationVisitor implements Visitor { private final org.apache.taverna.scufl2.xml.Workflow workflow; private org.apache.taverna.scufl2.xml.Processor proc; private Workflow wf; @SuppressWarnings("unused") private org.apache.taverna.scufl2.xml.DispatchStack dispatchStack; private org.apache.taverna.scufl2.xml.IterationStrategyStack iterationStrategyStack; private IterationStrategies iterationStrategies; private Stack<List<Object>> productStack; public WorkflowSerialisationVisitor( org.apache.taverna.scufl2.xml.Workflow workflow) { this.workflow = workflow; } private GranularPortDepth makeGranularPortDepth(Integer granularDepth) { if (granularDepth == null) return null; GranularPortDepth portDepth = objectFactory .createGranularPortDepth(); portDepth.setValue(granularDepth); portDepth.setDatatype(portDepth.getDatatype()); return portDepth; } private PortDepth makePortDepth(Integer depth) { if (depth == null) return null; PortDepth portDepth = objectFactory.createPortDepth(); portDepth.setValue(depth); portDepth.setDatatype(portDepth.getDatatype()); return portDepth; } private Resource makeResource(URI uri) { Resource resource = rdfObjectFactory.createResource(); resource.setResource(uri.toASCIIString()); return resource; } @Override public boolean visit(WorkflowBean node) { if (node instanceof Workflow) { wf = (Workflow) node; workflow.setAbout(""); workflow.setName(wf.getName()); if (wf.getIdentifier() != null) { Resource wfId = rdfObjectFactory.createResource(); wfId.setResource(wf.getIdentifier().toASCIIString()); workflow.setWorkflowIdentifier(wfId); } } URI uri = uriTools.relativeUriForBean(node, wf); if (node instanceof InputWorkflowPort) { InputWorkflowPort ip = (InputWorkflowPort) node; org.apache.taverna.scufl2.xml.Workflow.InputWorkflowPort inP = objectFactory .createWorkflowInputWorkflowPort(); org.apache.taverna.scufl2.xml.InputWorkflowPort inPort = objectFactory .createInputWorkflowPort(); inP.setInputWorkflowPort(inPort); inPort.setName(ip.getName()); URI portURI = uriTools.relativeUriForBean(ip, ip.getParent()); inPort.setAbout(portURI.toASCIIString()); PortDepth portDepth = makePortDepth(ip.getDepth()); inPort.setPortDepth(portDepth); workflow.getInputWorkflowPort().add(inP); } if (node instanceof OutputWorkflowPort) { OutputWorkflowPort op = (OutputWorkflowPort) node; org.apache.taverna.scufl2.xml.Workflow.OutputWorkflowPort inP = objectFactory .createWorkflowOutputWorkflowPort(); org.apache.taverna.scufl2.xml.OutputWorkflowPort outPort = objectFactory .createOutputWorkflowPort(); inP.setOutputWorkflowPort(outPort); outPort.setName(op.getName()); URI portURI = uriTools.relativeUriForBean(op, op.getParent()); outPort.setAbout(portURI.toASCIIString()); workflow.getOutputWorkflowPort().add(inP); } if (node instanceof Processor) { Processor processor = (Processor) node; org.apache.taverna.scufl2.xml.Workflow.Processor wfProc = objectFactory .createWorkflowProcessor(); proc = objectFactory.createProcessor(); wfProc.setProcessor(proc); proc.setName(processor.getName()); URI procUri = uriTools.relativeUriForBean(processor, wf); proc.setAbout(procUri.toASCIIString()); wfProc.setProcessor(proc); workflow.getProcessor().add(wfProc); } if (node instanceof InputProcessorPort) { InputProcessorPort inPort = (InputProcessorPort) node; org.apache.taverna.scufl2.xml.InputProcessorPort port = objectFactory .createInputProcessorPort(); port.setAbout(uri.toASCIIString()); port.setName(inPort.getName()); port.setPortDepth(makePortDepth(inPort.getDepth())); org.apache.taverna.scufl2.xml.Processor.InputProcessorPort inputProcessorPort = objectFactory .createProcessorInputProcessorPort(); inputProcessorPort.setInputProcessorPort(port); proc.getInputProcessorPort().add(inputProcessorPort); } if (node instanceof OutputProcessorPort) { org.apache.taverna.scufl2.xml.OutputProcessorPort port; OutputProcessorPort outPort = (OutputProcessorPort) node; port = objectFactory.createOutputProcessorPort(); port.setAbout(uri.toASCIIString()); port.setName(outPort.getName()); port.setPortDepth(makePortDepth(outPort.getDepth())); port.setGranularPortDepth(makeGranularPortDepth(outPort .getGranularDepth())); org.apache.taverna.scufl2.xml.Processor.OutputProcessorPort outputProcessorPort = objectFactory .createProcessorOutputProcessorPort(); outputProcessorPort.setOutputProcessorPort(port); proc.getOutputProcessorPort().add(outputProcessorPort); } if (node instanceof IterationStrategyStack) { iterationStrategyStack = objectFactory .createIterationStrategyStack(); iterationStrategyStack.setAbout(uri.toASCIIString()); org.apache.taverna.scufl2.xml.Processor.IterationStrategyStack processorIterationStrategyStack = objectFactory .createProcessorIterationStrategyStack(); processorIterationStrategyStack .setIterationStrategyStack(iterationStrategyStack); proc.setIterationStrategyStack(processorIterationStrategyStack); productStack = new Stack<List<Object>>(); } if (node instanceof IterationStrategyTopNode && productStack.isEmpty()) { iterationStrategies = objectFactory .createIterationStrategyStackIterationStrategies(); iterationStrategyStack .setIterationStrategies(iterationStrategies); iterationStrategies.setParseType(iterationStrategies .getParseType()); List<Object> dotProductOrCrossProduct = iterationStrategies .getDotProductOrCrossProduct(); productStack.add(dotProductOrCrossProduct); } if (node instanceof CrossProduct) { org.apache.taverna.scufl2.xml.CrossProduct crossProduct = objectFactory .createCrossProduct(); crossProduct.setAbout(uri.toASCIIString()); productStack.peek().add(crossProduct); ProductOf productOf = objectFactory.createProductOf(); productOf.setParseType(productOf.getParseType()); crossProduct.setProductOf(productOf); productStack.add(crossProduct.getProductOf().getCrossProductOrDotProductOrPortNode()); } if (node instanceof DotProduct) { org.apache.taverna.scufl2.xml.DotProduct dotProduct = objectFactory .createDotProduct(); dotProduct.setAbout(uri.toASCIIString()); productStack.peek().add(dotProduct); ProductOf productOf = objectFactory.createProductOf(); productOf.setParseType(productOf.getParseType()); dotProduct.setProductOf(productOf); productStack.add(dotProduct.getProductOf() .getCrossProductOrDotProductOrPortNode()); } if (node instanceof PortNode) { PortNode portNode = (PortNode) node; InputProcessorPort inPort = portNode.getInputProcessorPort(); URI portUri = uriTools.relativeUriForBean(inPort, wf); org.apache.taverna.scufl2.xml.PortNode port = objectFactory.createPortNode(); port.setAbout(uri.toASCIIString()); if (portNode.getDesiredDepth() != null) { DesiredDepth value = objectFactory.createPortNodeDesiredDepth(); value.setDatatype(value.getDatatype()); value.setValue(portNode.getDesiredDepth()); port.setDesiredDepth(value); } port.setIterateOverInputPort(makeResource(portUri)); productStack.peek().add(port); } if (node instanceof DataLink) { DataLink dataLink = (DataLink) node; org.apache.taverna.scufl2.xml.DataLink link = objectFactory .createDataLink(); link.setAbout(uri.toASCIIString()); URI fromUri = uriTools.relativeUriForBean( dataLink.getReceivesFrom(), wf); URI toUri = uriTools.relativeUriForBean(dataLink.getSendsTo(), wf); link.setReceiveFrom(makeResource(fromUri)); link.setSendTo(makeResource(toUri)); if (dataLink.getMergePosition() != null) { MergePosition value = objectFactory.createDataLinkMergePosition(); value.setValue(dataLink .getMergePosition()); value.setDatatype(value.getDatatype()); link.setMergePosition(value); } DataLinkEntry linkEntry = objectFactory.createDataLinkEntry(); linkEntry.setDataLink(link); workflow.getDatalink().add(linkEntry); } if (node instanceof BlockingControlLink) { BlockingControlLink controlLink = (BlockingControlLink) node; URI blockUri = uriTools.relativeUriForBean( controlLink.getBlock(), wf); URI untilUri = uriTools.relativeUriForBean( controlLink.getUntilFinished(), wf); Blocking blocking = objectFactory.createBlocking(); blocking.setAbout(uri.toASCIIString()); blocking.setBlock(makeResource(blockUri)); blocking.setUntilFinished(makeResource(untilUri)); Control control = objectFactory.createControl(); control.setBlocking(blocking); workflow.getControl().add(control); } // TODO: Datalinks return true; } @Override public boolean visitEnter(WorkflowBean node) { return visit(node); } @Override public boolean visitLeave(WorkflowBean node) { if (node instanceof IterationStrategyTopNode) // Actually for any Cross/Dot product productStack.pop(); return true; } } protected synchronized static JAXBContext getJAxbContextStatic() throws JAXBException { if (jaxbContextStatic == null) { Class<?>[] packages = { ObjectFactory.class, org.apache.taverna.scufl2.xml.rdf.ObjectFactory.class, org.apache.taverna.scufl2.xml.rdfs.ObjectFactory.class }; jaxbContextStatic = JAXBContext.newInstance(packages); } return jaxbContextStatic; } public void annotation(final Annotation ann) { URI wfBundleURI = uriTools.uriForBean(wfBundle); URI annUri = uriTools.uriForBean(ann); URI bodyURI = ann.getBody(); if (bodyURI == null || bodyURI.isAbsolute()) // Workaround with separate file for the annotation alone bodyURI = annUri.resolve(uriTools.validFilename(ann.getName()) + DOT_RDF); URI pathUri = uriTools.relativePath(wfBundleURI, bodyURI); if (ann.getBody() == null || ann.getBody().equals(wfBundleURI.resolve(pathUri))) // Set the relative path ann.setBody(pathUri); // TODO: Add annotation to RO manifest // // Miniature OA description for now // // See http://openannotation.org/spec/core/20130205/ // final PropertyResource annProv = new PropertyResource(); // annProv.setResourceURI(annUri); // annProv.setTypeURI(OA.resolve("#Annotation")); // // if (ann.getAnnotatedAt() != null) { // annProv.addProperty(OA.resolve("#annotedAt"), // new PropertyLiteral(ann.getAnnotatedAt())); // } // if (ann.getSerializedAt() != null) { // annProv.addProperty(OA.resolve("#serializedAt"), // new PropertyLiteral(ann.getSerializedAt())); // } // // if (ann.getAnnotatedBy() != null) { // annProv.addPropertyReference(OA.resolve("#annotatedBy"), // ann.getAnnotatedBy()); // } // if (ann.getSerializedBy() != null) { // annProv.addPropertyReference(OA.resolve("#serializedBy"), // ann.getSerializedBy()); // } // // if (ann.getBody() != null) { // annProv.addPropertyReference(OA.resolve("#hasBody"), ann.getBody()); // } else if (! ann.getBodyStatements().isEmpty()){ // // FIXME: Hack - Our body is also the annotation! // annProv.addPropertyReference(OA.resolve("#hasBody"), pathUri); // } // // // CHECK: should this be a relative reference instead? // annProv.addPropertyReference(OA.resolve("#hasTarget"), // uriTools.uriForBean(ann.getTarget())); // // Serialize the metadata // // // try { // /* // * TODO: Serialize manually with nicer indentation/namespaces etc., // * as done for our other RDF/XML documents // */ // wfBundle.getResources() // .addResource(visitor.getDoc(), pathUri.toASCIIString(), APPLICATION_RDF_XML); // } catch (IOException e) { // logger.log(Level.WARNING, "Can't write annotation to " + pathUri, e); // } } private ObjectFactory objectFactory = new ObjectFactory(); private org.apache.taverna.scufl2.xml.rdfs.ObjectFactory rdfsObjectFactory = new org.apache.taverna.scufl2.xml.rdfs.ObjectFactory(); private org.apache.taverna.scufl2.xml.rdf.ObjectFactory rdfObjectFactory = new org.apache.taverna.scufl2.xml.rdf.ObjectFactory(); private URITools uriTools = new URITools(); private boolean usingSchema = false; private WorkflowBundle wfBundle; private JAXBContext jaxbContext; private Map<WorkflowBean, URI> seeAlsoUris = new HashMap<>(); private static JAXBContext jaxbContextStatic; private static Logger logger = Logger.getLogger(RDFXMLSerializer.class .getCanonicalName()); public RDFXMLSerializer() { } public RDFXMLSerializer(WorkflowBundle wfBundle) { setWfBundle(wfBundle); } public JAXBContext getJaxbContext() throws JAXBException { if (jaxbContext == null) return getJAxbContextStatic(); return jaxbContext; } public Marshaller getMarshaller() { String schemaPath = "xsd/scufl2.xsd"; Marshaller marshaller; try { marshaller = getJaxbContext().createMarshaller(); if (isUsingSchema()) { SchemaFactory schemaFactory = SchemaFactory .newInstance(W3C_XML_SCHEMA_NS_URI); Schema schema = schemaFactory.newSchema(getClass().getResource( schemaPath)); // FIXME: re-enable schema marshaller.setSchema(schema); } marshaller.setProperty(JAXB_FORMATTED_OUTPUT, TRUE); marshaller .setProperty( "jaxb.schemaLocation", "http://ns.taverna.org.uk/2010/scufl2# http://ns.taverna.org.uk/2010/scufl2/scufl2.xsd " + "http://www.w3.org/1999/02/22-rdf-syntax-ns# http://ns.taverna.org.uk/2010/scufl2/rdf.xsd"); } catch (JAXBException e) { throw new IllegalStateException(e); } catch (SAXException e) { throw new IllegalStateException("Could not load schema " + schemaPath, e); } setPrefixMapper(marshaller); return marshaller; } public WorkflowBundle getWfBundle() { return wfBundle; } public boolean isUsingSchema() { return usingSchema; } protected ProfileDocument makeProfile(Profile pf, URI path) { ProfileDocument doc = objectFactory.createProfileDocument(); objectFactory.createProfile(); pf.accept(new ProfileSerialisationVisitor(doc) { }); return doc; } protected org.apache.taverna.scufl2.xml.Workflow makeWorkflow( Workflow wf, URI documentPath) { org.apache.taverna.scufl2.xml.Workflow workflow = objectFactory .createWorkflow(); wf.accept(new WorkflowSerialisationVisitor(workflow) { }); return workflow; } protected org.apache.taverna.scufl2.xml.WorkflowBundle makeWorkflowBundleElem() { org.apache.taverna.scufl2.xml.WorkflowBundle bundle = objectFactory .createWorkflowBundle(); // FIXME: Support other URIs bundle.setAbout(""); bundle.setName(wfBundle.getName()); if (wfBundle.getGlobalBaseURI() != null) { Resource globalBaseURI = rdfObjectFactory.createResource(); globalBaseURI.setResource(wfBundle.getGlobalBaseURI().toASCIIString()); bundle.setGlobalBaseURI(globalBaseURI); } for (Workflow wf : wfBundle.getWorkflows()) { org.apache.taverna.scufl2.xml.WorkflowBundle.Workflow wfElem = objectFactory .createWorkflowBundleWorkflow(); SeeAlsoType seeAlsoElem = objectFactory.createSeeAlsoType(); seeAlsoElem.setAbout(uriTools.relativeUriForBean(wf, wfBundle) .toASCIIString()); if (seeAlsoUris.containsKey(wf)) { SeeAlso seeAlso = rdfsObjectFactory.createSeeAlso(); seeAlso.setResource(seeAlsoUris.get(wf).toASCIIString()); seeAlsoElem.setSeeAlso(seeAlso); } else logger.warning("Can't find bundle URI for workflow document " + wf.getName()); wfElem.setWorkflow(seeAlsoElem); bundle.getWorkflow().add(wfElem); if (wfBundle.getMainWorkflow() == wf) { Resource mainWorkflow = rdfObjectFactory.createResource(); mainWorkflow.setResource(seeAlsoElem.getAbout()); bundle.setMainWorkflow(mainWorkflow); } } for (Profile pf : wfBundle.getProfiles()) { org.apache.taverna.scufl2.xml.WorkflowBundle.Profile wfElem = objectFactory .createWorkflowBundleProfile(); SeeAlsoType seeAlsoElem = objectFactory.createSeeAlsoType(); seeAlsoElem.setAbout(uriTools.relativeUriForBean(pf, wfBundle) .toASCIIString()); if (seeAlsoUris.containsKey(pf)) { SeeAlso seeAlso = rdfsObjectFactory.createSeeAlso(); seeAlso.setResource(seeAlsoUris.get(pf).toASCIIString()); seeAlsoElem.setSeeAlso(seeAlso); } else logger.warning("Can't find bundle URI for profile document " + pf.getName()); wfElem.setProfile(seeAlsoElem); bundle.getProfile().add(wfElem); if (wfBundle.getMainProfile() == pf) { Resource mainProfile = rdfObjectFactory.createResource(); mainProfile.setResource(seeAlsoElem.getAbout()); bundle.setMainProfile(mainProfile); } } for (Annotation ann : wfBundle.getAnnotations()) annotation(ann); return bundle; } public void profileDoc(OutputStream outputStream, Profile pf, URI path) throws JAXBException, WriterException { ProfileDocument doc = makeProfile(pf, path); URI wfUri = uriTools.relativeUriForBean(pf, wfBundle); doc.setBase(uriTools.relativePath(path, wfUri).toASCIIString()); JAXBElement<RDF> element = rdfObjectFactory.createRDF(doc); getMarshaller().marshal(element, outputStream); seeAlsoUris.put(pf, path); } private Resource resource(String uri) { Resource r = rdfObjectFactory.createResource(); r.setResource(uri); return r; } public void setJaxbContext(JAXBContext jaxbContext) { this.jaxbContext = jaxbContext; } protected void setPrefixMapper(Marshaller marshaller) { boolean setPrefixMapper = false; try { /* * This only works with JAXB RI, in which case we can set the * namespace prefix mapper */ Class.forName("com.sun.xml.bind.marshaller.NamespacePrefixMapper"); marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper", new NamespacePrefixMapperJAXB_RI()); /* * Note: A similar mapper for the built-in java * (com.sun.xml.bind.internal.namespacePrefixMapper) is no longer * included here, as it will not (easily) compile with Maven. */ setPrefixMapper = true; } catch (Exception e) { logger.log(FINE, "Can't find NamespacePrefixMapper", e); } if (!setPrefixMapper && ! warnedOnce) { logger.info("Could not set prefix mapper (missing or incompatible JAXB) " + "- will use prefixes ns0, ns1, .."); warnedOnce = true; } } public void setUsingSchema(boolean usingSchema) { this.usingSchema = usingSchema; } public void setWfBundle(WorkflowBundle wfBundle) { this.wfBundle = wfBundle; } private Type type(Typed typed) { if (typed.getType() == null) return null; Type t = rdfObjectFactory.createType(); t.setResource(typed.getType().toASCIIString()); return t; } public void workflowBundleDoc(OutputStream outputStream, URI path) throws JAXBException, WriterException { org.apache.taverna.scufl2.xml.WorkflowBundle bundle = makeWorkflowBundleElem(); WorkflowBundleDocument doc = objectFactory .createWorkflowBundleDocument(); doc.getAny().add(bundle); doc.setBase(path.relativize(URI.create("./")).toASCIIString()); JAXBElement<RDF> element = rdfObjectFactory.createRDF(doc); getMarshaller().marshal(element, outputStream); seeAlsoUris.put(wfBundle, path); } public void workflowDoc(OutputStream outputStream, Workflow wf, URI path) throws JAXBException, WriterException { org.apache.taverna.scufl2.xml.Workflow wfElem = makeWorkflow(wf, path); WorkflowDocument doc = objectFactory.createWorkflowDocument(); doc.getAny().add(wfElem); URI wfUri = uriTools.relativeUriForBean(wf, wfBundle); doc.setBase(uriTools.relativePath(path, wfUri).toASCIIString()); JAXBElement<RDF> element = rdfObjectFactory.createRDF(doc); getMarshaller().marshal(element, outputStream); seeAlsoUris.put(wf, path); } }