[MOBY-guts] biomoby commit
Paul Gordon
gordonp at dev.open-bio.org
Mon Aug 17 21:28:20 UTC 2009
gordonp
Mon Aug 17 17:28:20 EDT 2009
Update of /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/util
In directory dev.open-bio.org:/tmp/cvs-serv26153/src/main/ca/ucalgary/seahawk/util
Modified Files:
DataRecorder.java
Log Message:
Start of Taverna2 workflow export (not yet complete)
moby-live/Java/src/main/ca/ucalgary/seahawk/util DataRecorder.java,1.1,1.2
===================================================================
RCS file: /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/util/DataRecorder.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/util/DataRecorder.java 2007/06/08 14:04:27 1.1
+++ /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/util/DataRecorder.java 2009/08/17 21:28:20 1.2
@@ -1,19 +1,27 @@
package ca.ucalgary.seahawk.util;
import org.biomoby.client.MobyRequestEvent;
+import org.biomoby.registry.meta.*;
import org.biomoby.shared.*;
import org.biomoby.shared.data.*;
import org.w3c.dom.*;
import javax.xml.parsers.*;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.*;
import java.io.*;
import java.net.URL;
+import java.text.SimpleDateFormat;
import java.util.*;
public class DataRecorder{
public static final int TAVERNA15 = 167;
+ public static final int T2FLOW = 169;
+ public static final String T2FLOW_NS = "http://taverna.sf.net/2008/xml/t2flow";
+ public static final String T2FLOW_DISPATCHXML = "ca/ucalgary/seahawk/resources/t2flowDispatchStack.xml";
public static final String PI_TARGET = "seahawk";
public static final String TEMP_FILE_PREFIX = "seahawk";
public static final String SERVICEID_ATTR = "service";
@@ -21,9 +29,12 @@
private static final String INPUT_SUFFIX = ".in.xml";
private Central mobyCentral;
+ private Map<String,Integer> namesUsed; // keep count of workflow element name usage so as not to duplicate an ID
private Map<URL,URL> outputURL2InputURL;
private Map<Integer,URL> requestID2InputURL;
private DocumentBuilder docBuilder;
+ private static Element dispatchStack = null;
+ private static Transformer nullTransformer = null;
public DataRecorder(Central mobyCtr) throws Exception{
if(mobyCtr == null){
@@ -32,6 +43,7 @@
mobyCentral = mobyCtr;
docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ namesUsed = new HashMap<String,Integer>();
outputURL2InputURL = new HashMap<URL,URL>();
requestID2InputURL = new HashMap<Integer,URL>();
}
@@ -81,9 +93,9 @@
* @param format the format to write the workflow in (current DataRecorder.TAVERNA15)
*/
public void exportWorkflow(URL endpointDocument, OutputStream outputStream, int format) throws Exception{
- if(format != TAVERNA15){
+ if(format != TAVERNA15 && format != T2FLOW){
throw new IllegalArgumentException("The export format for the workflow was " +
- "not DataRecorder.TAVERNA15 as expected, found " + format);
+ "not DataRecorder.TAVERNA15 nor DataRecorder.T2FLOW as expected, found " + format);
}
if(outputStream == null){
throw new IllegalArgumentException("The output stream for workflow exporting was null, aborting export");
@@ -101,17 +113,20 @@
throw new IOException("Could not open workflow endpoint document provided as input to workflow exporter: " + ioe);
}
- outputSCUFLHeader(outputStream);
-
- //TODO: Do an iterative traceback
-
- outputSCUFLFooter(outputStream);
+ if(format == TAVERNA15){
+ outputSCUFLHeader(outputStream);
+ //TODO: Do an iterative traceback
+ outputSCUFLFooter(outputStream);
+ }
+ else{
+ //TODO: Do an iterative traceback
+ }
}
- public void exportWorkflow(URL[] documentHistory, OutputStream outputStream, int format) throws Exception{
- if(format != TAVERNA15){
+ public void exportWorkflow(URL[] documentHistory, OutputStream outputStream, String workflowName, int format) throws Exception{
+ if(format != TAVERNA15 && format != T2FLOW){
throw new IllegalArgumentException("The export format for the workflow was " +
- "not DataRecorder.TAVERNA15 as expected, found " + format);
+ "not DataRecorder.TAVERNA15 nor DataRecorder.T2FLOW as expected, found " + format);
}
if(outputStream == null){
throw new IllegalArgumentException("The output stream for workflow exporting was null, aborting export");
@@ -120,6 +135,360 @@
throw new IllegalArgumentException("The URL endpoint to export was null, aborting workflow export");
}
+ if(format == TAVERNA15){
+ exportSCUFL(documentHistory, outputStream);
+ }
+ else{
+ exportT2Flow(documentHistory, outputStream, workflowName);
+ }
+ }
+
+ // Taverna 2.0+ format
+ private synchronized void exportT2Flow(URL[] documentHistory, OutputStream outputStream, String workflowName)
+ throws Exception{
+ Document doc = docBuilder.newDocument();
+ Element root = doc.createElementNS(T2FLOW_NS, "workflow");
+ doc.appendChild(root);
+ root.setAttribute("version", "1");
+ root.setAttribute("producedBy", "Seahawk 1.0");
+
+ Element dataflow = doc.createElementNS(T2FLOW_NS, "dataflow");
+ dataflow.setAttribute("id", java.util.UUID.randomUUID().toString());
+ dataflow.setAttribute("role", "top");
+ root.appendChild(dataflow);
+
+ Element name = doc.createElementNS(T2FLOW_NS, "name");
+ name.appendChild(doc.createTextNode(workflowName));
+ dataflow.appendChild(name);
+
+ // set up the main sections, details to be filled in later
+ Element inputPorts = doc.createElementNS(T2FLOW_NS, "inputPorts");
+ dataflow.appendChild(inputPorts);
+ Element outputPorts = doc.createElementNS(T2FLOW_NS, "outputPorts");
+ dataflow.appendChild(outputPorts);
+ Element processors = doc.createElementNS(T2FLOW_NS, "processors");
+ dataflow.appendChild(processors);
+ // no "conditions" tag applicable yet, skipping
+ Element datalinks = doc.createElementNS(T2FLOW_NS, "datalinks");
+ dataflow.appendChild(datalinks);
+
+ namesUsed.clear(); // internal Taverna label table
+
+ for(int i = 0; i < documentHistory.length; i++){
+ //MobyService service = getService(srcURL);
+ //inputPorts.appendChild(createPortElement());
+ // add processor
+ //processors.appendChild(createProcessorElement());
+ // add datalink
+ //datalinks.appendChild(createDataLinkElement());
+ //outputPorts.appendChild(createPortElement());
+ }
+
+ // Serialize the DOM
+ getTransformer().transform(new DOMSource(root), new StreamResult(outputStream));
+ }
+
+ private Element createDataLinkElement(MobyService service1, MobyPrimaryData outParam,
+ MobyService service2, MobyPrimaryData inParam,
+ Document doc){
+ Element datalink = doc.createElementNS(T2FLOW_NS, "datalink");
+
+ Element sink = doc.createElementNS(T2FLOW_NS, "sink");
+ sink.setAttribute("type", "processor");
+ datalink.appendChild(sink);
+
+ Element processor = doc.createElementNS(T2FLOW_NS, "processor");
+ processor.appendChild(doc.createTextNode(getProcessorName(service2)));
+ sink.appendChild(processor);
+
+ Element port = doc.createElementNS(T2FLOW_NS, "port");
+ port.appendChild(doc.createTextNode(getPortName(inParam)));
+ sink.appendChild(port);
+
+ Element src = doc.createElementNS(T2FLOW_NS, "source");
+ src.setAttribute("type", "processor");
+ datalink.appendChild(src);
+
+ Element processorSrc = doc.createElementNS(T2FLOW_NS, "processor");
+ processorSrc.appendChild(doc.createTextNode(getProcessorName(service1)));
+ src.appendChild(processorSrc);
+
+ Element portSrc = doc.createElementNS(T2FLOW_NS, "port");
+ portSrc.appendChild(doc.createTextNode(getPortName(outParam)));
+ src.appendChild(portSrc);
+
+ return datalink;
+ }
+
+ private synchronized Transformer getTransformer() throws Exception{
+ if(nullTransformer == null){
+ nullTransformer = TransformerFactory.newInstance().newTransformer();
+ }
+ return nullTransformer;
+ }
+
+ //Ensures a unique name for the processor (same Moby service may be called more than once)
+ private String getProcessorName(MobyService service){
+ String preferredName = service.getName();
+ if(namesUsed.containsKey(preferredName)){
+ namesUsed.put(preferredName, namesUsed.get(preferredName).intValue()+1); //increment
+ preferredName += namesUsed.get(preferredName);
+ }
+ else{
+ namesUsed.put(preferredName, 1); // will be auto-boxed to Integer
+ }
+ return preferredName;
+ }
+
+ //todo: mobyData('Object') or dataType(articleName)
+ private String getPortName(MobyPrimaryData data){
+ return null;
+ }
+
+ // Turn a Moby service call into a Taverna processor
+ private Element createProcessorElement(MobyService service, MobyDataJob sampleInput, Document doc)
+ throws Exception{
+ Element processor = doc.createElementNS(T2FLOW_NS, "processor");
+ Element name = doc.createElementNS(T2FLOW_NS, "name");
+ name.appendChild(doc.createTextNode(getProcessorName(service)));
+ processor.appendChild(name);
+
+ Element inputPorts = doc.createElementNS(T2FLOW_NS, "inputPorts");
+ processor.appendChild(inputPorts);
+ for(MobyPrimaryData inParam: service.getPrimaryInputs()){
+ Element port = doc.createElementNS(T2FLOW_NS, "port");
+ inputPorts.appendChild(port);
+
+ Element portName = doc.createElementNS(T2FLOW_NS, "name");
+ portName.appendChild(doc.createTextNode(getPortName(inParam)));
+ port.appendChild(portName);
+
+ Element depth = doc.createElementNS(T2FLOW_NS, "depth");
+ depth.appendChild(doc.createTextNode("0"));
+ port.appendChild(depth);
+ }
+
+ Element outputPorts = doc.createElementNS(T2FLOW_NS, "outputPorts");
+ for(MobyPrimaryData outParam: service.getPrimaryOutputs()){
+ Element port = doc.createElementNS(T2FLOW_NS, "port");
+ outputPorts.appendChild(port);
+
+ Element portName = doc.createElementNS(T2FLOW_NS, "name");
+ portName.appendChild(doc.createTextNode(getPortName(outParam)));
+ port.appendChild(portName);
+
+ Element depth = doc.createElementNS(T2FLOW_NS, "depth");
+ depth.appendChild(doc.createTextNode("0"));
+ port.appendChild(depth);
+
+ Element granularDepth = doc.createElementNS(T2FLOW_NS, "granularDepth");
+ granularDepth.appendChild(doc.createTextNode("0"));
+ port.appendChild(granularDepth);
+ }
+
+ processor.appendChild(doc.createElementNS(T2FLOW_NS, "annotations"));
+
+ Element activities = doc.createElementNS(T2FLOW_NS, "activities");
+ processor.appendChild(activities);
+ Element activity = doc.createElementNS(T2FLOW_NS, "activity");
+ activities.appendChild(activity);
+ Element raven = doc.createElementNS(T2FLOW_NS, "raven");
+ Element group = doc.createElementNS(T2FLOW_NS, "group");
+ group.appendChild(doc.createTextNode("net.sf.taverna.t2.activities"));
+ raven.appendChild(group);
+ Element artifact = doc.createElementNS(T2FLOW_NS, "artifact");
+ artifact.appendChild(doc.createTextNode("biomoby-activity"));
+ raven.appendChild(artifact);
+ Element version = doc.createElementNS(T2FLOW_NS, "version");
+ version.appendChild(doc.createTextNode("0.8"));
+ raven.appendChild(version);
+
+ Element clas = doc.createElementNS(T2FLOW_NS, "class");
+ activity.appendChild(clas);
+ clas.appendChild(doc.createTextNode("net.sf.taverna.t2.activities.biomoby.BiomobyActivity"));
+
+ Element inputMap = doc.createElementNS(T2FLOW_NS, "inputMap");
+ activity.appendChild(inputMap);
+ for(MobyPrimaryData inParam: service.getPrimaryInputs()){
+ Element map = doc.createElementNS(T2FLOW_NS, "map");
+ map.setAttribute("from", getPortName(inParam)); //identity map
+ map.setAttribute("to", getPortName(inParam)); //identity map
+ inputMap.appendChild(map);
+ }
+ Element outputMap = doc.createElementNS(T2FLOW_NS, "outputMap");
+ activity.appendChild(outputMap);
+ for(MobyPrimaryData outParam: service.getPrimaryOutputs()){
+ Element map = doc.createElementNS(T2FLOW_NS, "map");
+ map.setAttribute("from", getPortName(outParam)); //identity map
+ map.setAttribute("to", getPortName(outParam)); //identity map
+ outputMap.appendChild(map);
+ }
+
+ Element configBean = doc.createElementNS(T2FLOW_NS, "configBean");
+ configBean.setAttribute("encoding", "xstream");
+ activity.appendChild(configBean);
+ Element BiomobyActivityConfigurationBean =
+ doc.createElementNS("",
+ "net.sf.taverna.t2.activities.biomoby.BiomobyActivityConfigurationBean");
+ configBean.appendChild(BiomobyActivityConfigurationBean);
+
+ MobyServiceType serviceType = service.getServiceType();
+ String central = null; // url of Moby Central endpoint: check if the registry is dfined anywhere in the service
+ if(serviceType != null){
+ if(serviceType.getRegistry() != null){
+ central = serviceType.getRegistry().getEndpoint();
+ }
+ }
+ if(central == null){
+ for(MobyPrimaryData inParam: service.getPrimaryInputs()){
+ if(inParam.getDataType().getRegistry() != null){
+ central = inParam.getDataType().getRegistry().getEndpoint();
+ break;
+ }
+ }
+ }
+ if(central == null){ // must be the default registry in this case
+ central = (new RegistriesList()).get(Registries.DEFAULT_REGISTRY_SYNONYM).getEndpoint();
+ }
+ Element mobyEndpoint = doc.createElementNS("", "mobyEndpoint");
+ mobyEndpoint.appendChild(doc.createTextNode(central == null ? "" : central));
+ BiomobyActivityConfigurationBean.appendChild(mobyEndpoint);
+
+ Element serviceName = doc.createElementNS("", "serviceName");
+ serviceName.appendChild(doc.createTextNode(service.getName()));
+ BiomobyActivityConfigurationBean.appendChild(serviceName);
+
+ Element authorityName = doc.createElementNS("", "authorityName");
+ authorityName.appendChild(doc.createTextNode(service.getAuthority()));
+
+ BiomobyActivityConfigurationBean.appendChild(doc.createElementNS("", "category"));
+ BiomobyActivityConfigurationBean.appendChild(doc.createElementNS("", "serviceType"));
+
+ Element secondaries = doc.createElementNS("", "secondaries");
+ BiomobyActivityConfigurationBean.appendChild(secondaries);
+ for(MobySecondaryData secParam: service.getSecondaryInputs()){
+ Element entry = doc.createElementNS("", "entry");
+
+ Element stringName = doc.createElementNS("", "string");
+ stringName.appendChild(doc.createTextNode(secParam.getName()));
+ entry.appendChild(stringName);
+
+ // Did we override the default value for the secondary param in the example input?
+ Element stringValue = doc.createElementNS("", "string");
+ if(sampleInput.containsKey(secParam.getName())){
+ stringValue.appendChild(doc.createTextNode(((MobyDataSecondaryInstance) sampleInput.get(secParam.getName())).getValue()));
+ }
+ else{ // use the default defined in Moby Central
+ stringValue.appendChild(doc.createTextNode(secParam.getDefaultValue()));
+ }
+ entry.appendChild(stringValue);
+
+ secondaries.appendChild(entry);
+ }
+
+ // boiler-plate for all processors
+ processor.appendChild(getDispatchStack());
+
+ Element iterationStrategyStack = doc.createElementNS(T2FLOW_NS, "iterationStrategyStack");
+ processor.appendChild(iterationStrategyStack);
+ Element iteration = doc.createElementNS(T2FLOW_NS, "iteration");
+ iterationStrategyStack.appendChild(iteration);
+ Element strategy = doc.createElementNS(T2FLOW_NS, "strategy");
+ iteration.appendChild(strategy);
+ Element cross = doc.createElementNS(T2FLOW_NS, "cross");
+ strategy.appendChild(cross);
+ for(MobyPrimaryData inParam: service.getPrimaryInputs()){
+ Element portRef = doc.createElementNS(T2FLOW_NS, "port");
+ portRef.setAttribute("name", getPortName(inParam));
+ portRef.setAttribute("depth", "0");
+ cross.appendChild(portRef);
+ }
+
+ return processor;
+ }
+
+ // todo
+ private synchronized Element getDispatchStack() throws Exception{
+ // first call, load the xml from the resource
+ if(dispatchStack == null){
+ URL xmlURL = getClass().getClassLoader().getResource(T2FLOW_DISPATCHXML);
+ if(xmlURL == null){
+ throw new Exception("Cannot find resource " + T2FLOW_DISPATCHXML);
+ }
+ Document domDoc = docBuilder.parse(xmlURL.openStream());
+ dispatchStack = domDoc.getDocumentElement();
+ }
+ return dispatchStack;
+ }
+
+ // Describe a workflow input to Taverna
+ private Element createPortElement(String name, MobyDataInstance instance, MobyDataType dataType, Document doc){
+ Element port = doc.createElementNS(T2FLOW_NS, "port");
+ Element nameEl = doc.createElementNS(T2FLOW_NS, "name");
+ nameEl.appendChild(doc.createTextNode(name));
+ port.appendChild(nameEl);
+
+ Element depth = doc.createElementNS(T2FLOW_NS, "depth");
+ depth.appendChild(doc.createTextNode("0"));
+ port.appendChild(depth);
+
+ Element granularDepth = doc.createElementNS(T2FLOW_NS, "granularDepth");
+ granularDepth.appendChild(doc.createTextNode("0"));
+ port.appendChild(granularDepth);
+
+ Element annotations = doc.createElementNS(T2FLOW_NS, "annotations");
+ port.appendChild(annotations);
+
+ Element annotation_chain = doc.createElementNS(T2FLOW_NS, "annotation_chain");
+ annotation_chain.setAttribute("encoding", "xstream");
+
+ Element AnnotationChainImpl = doc.createElementNS("", "net.sf.taverna.t2.annotation.AnnotationChainImpl");
+ annotation_chain.appendChild(AnnotationChainImpl);
+
+ Element annotationAssertions = doc.createElementNS("", "annotationAssertions");
+ AnnotationChainImpl.appendChild(annotationAssertions);
+
+ Element AnnotationAssertionImpl = doc.createElementNS("", "net.sf.taverna.t2.annotation.AnnotationAssertionImpl");
+ Element annotation_chainExample = (Element) annotation_chain.cloneNode(true);
+ Element annotation_chainDesc = (Element) annotation_chain.cloneNode(true);
+ annotations.appendChild(annotation_chainExample);
+ annotations.appendChild(annotation_chainDesc);
+ Element AnnotationAssertionImplExample = (Element) annotation_chainExample.getFirstChild().getFirstChild().getFirstChild();
+ Element AnnotationAssertionImplDesc = (Element) annotation_chainDesc.getFirstChild().getFirstChild().getFirstChild();
+
+ Element annotationBeanExample = doc.createElementNS("", "annotationBean");
+ annotationBeanExample.setAttribute("class", "net.sf.taverna.t2.annotation.annotationbeans.ExampleValue");
+ AnnotationAssertionImplExample.appendChild(annotationBeanExample);
+
+ Element textExample = doc.createElementNS("", "text");
+ textExample.appendChild(doc.createTextNode(instance+" is an example input")); //todo: correct field
+ annotationBeanExample.appendChild(textExample);
+
+ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd' 'HH:mm:ss.SSS' GMT'");
+ dateFormat.setTimeZone(new SimpleTimeZone(0, "GMT"));
+ Element dateExample = doc.createElementNS("", "date");
+ dateExample.appendChild(doc.createTextNode(dateFormat.format(new Date()))); //now
+ AnnotationAssertionImplExample.appendChild(dateExample);
+
+ AnnotationAssertionImplExample.appendChild(doc.createElementNS("","creators")); //blank
+ AnnotationAssertionImplExample.appendChild(doc.createElementNS("","curationEventList")); //blank
+
+ Element annotationBeanDesc = doc.createElementNS("", "annotationBean");
+ annotationBeanDesc.setAttribute("class", "net.sf.taverna.t2.annotation.annotationbeans.FreeTextDescription");
+ AnnotationAssertionImplDesc.appendChild(annotationBeanDesc);
+
+ Element textDesc = doc.createElementNS("", "text");
+ textDesc.appendChild(doc.createTextNode(dataType.getDescription())); //todo: what if secondary?
+ annotationBeanDesc.appendChild(textDesc);
+
+ AnnotationAssertionImplDesc.appendChild(dateExample.cloneNode(true)); //reuse data from example tag
+ AnnotationAssertionImplDesc.appendChild(doc.createElementNS("","creators")); //blank
+ AnnotationAssertionImplDesc.appendChild(doc.createElementNS("","curationEventList")); //blank
+
+ return port;
+ }
+
+ private void exportSCUFL(URL[] documentHistory, OutputStream outputStream) throws Exception{
outputSCUFLHeader(outputStream);
// The first service to be called
int i = 0;
More information about the MOBY-guts
mailing list