blob: cd06115cec3a0d5b56270a8d008f7cdeced70845 [file] [log] [blame]
/*
* Copyright (C) 2012 The University of Manchester
*
* See the file "LICENSE.txt" for license terms.
*/
package org.taverna.server.master.soap;
import static javax.xml.bind.annotation.XmlAccessType.NONE;
import static org.apache.commons.io.IOUtils.closeQuietly;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlMimeType;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
import org.taverna.server.master.common.Workflow;
import uk.org.taverna.scufl2.api.io.ReaderException;
import uk.org.taverna.scufl2.api.io.WorkflowBundleIO;
import uk.org.taverna.scufl2.api.io.WriterException;
/**
* An MTOM-capable description of how to transfer the contents of a file.
*
* @author Donal Fellows
*/
@XmlType(name = "WorkflowReference")
@XmlAccessorType(NONE)
public class WrappedWorkflow {
@XmlMimeType("application/octet-stream")
// JAXB bug: must be this
public DataHandler workflowData;
Workflow workflow;
/**
* Initialize the contents of this descriptor from the given file and
* content type.
*
* @param workflow
* The workflow that is to be reported.
*/
public void setWorkflow(Workflow workflow) {
workflowData = new DataHandler(new WorkflowSource(workflow));
}
@XmlTransient
public Workflow getWorkflow() throws IOException {
if (workflow != null)
return workflow;
try {
return new Workflow(new WorkflowBundleIO().readBundle(
workflowData.getInputStream(), null));
} catch (ReaderException e) {
throw new IOException("problem converting to scufl2 bundle", e);
}
}
}
/**
* A data source that knows how to deliver a workflow.
*
* @author Donal Fellows
*/
class WorkflowSource implements DataSource {
WorkflowSource(Workflow workflow) {
this.wf = workflow;
this.io = new WorkflowBundleIO();
}
Workflow wf;
final WorkflowBundleIO io;
@Override
public String getContentType() {
return wf.getPreferredContentType().getContentType();
}
@Override
public String getName() {
switch (wf.getPreferredContentType()) {
case SCUFL2:
return "workflow.scufl2";
case T2FLOW:
return "workflow.t2flow";
default:
return "workflow";
}
}
@Override
public InputStream getInputStream() throws IOException {
PipedInputStream is = new PipedInputStream();
final OutputStream os = new PipedOutputStream(is);
new Worker() {
@Override
public void doWork() throws WriterException, IOException {
io.writeBundle(wf.getScufl2Workflow(), os, wf
.getPreferredContentType().getContentType());
}
@Override
public void doneWork() {
closeQuietly(os);
}
};
return is;
}
@Override
public OutputStream getOutputStream() throws IOException {
final PipedInputStream is = new PipedInputStream();
OutputStream os = new PipedOutputStream(is);
new Worker() {
@Override
public void doWork() throws IOException, ReaderException {
wf = new Workflow(io.readBundle(is, null));
}
@Override
public void doneWork() {
closeQuietly(is);
}
};
return os;
}
static abstract class Worker extends Thread {
public Worker() {
setDaemon(true);
start();
}
public abstract void doWork() throws Exception;
public abstract void doneWork();
@Override
public void run() {
try {
doWork();
} catch (Exception e) {
// do nothing.
} finally {
doneWork();
}
}
}
}