| /* |
| * Copyright (C) 2011 The University of Manchester |
| * |
| * See the file "LICENSE" for license terms. |
| */ |
| package org.taverna.server.master.soap; |
| |
| import static java.lang.Math.min; |
| import static java.lang.System.arraycopy; |
| |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.OutputStream; |
| |
| import javax.activation.DataHandler; |
| import javax.activation.DataSource; |
| import javax.xml.bind.annotation.XmlElement; |
| import javax.xml.bind.annotation.XmlMimeType; |
| import javax.xml.bind.annotation.XmlType; |
| |
| import org.taverna.server.master.exceptions.FilesystemAccessException; |
| import org.taverna.server.master.interfaces.File; |
| |
| /** |
| * An MTOM-capable description of how to transfer the contents of a file. |
| * |
| * @author Donal Fellows |
| */ |
| @XmlType(name = "FileContents") |
| public class FileContents { |
| @XmlElement |
| public String name; |
| @XmlMimeType("application/octet-stream") // JAXB bug: must be this |
| public DataHandler fileData; |
| |
| /** |
| * Initialize the contents of this descriptor from the given file and |
| * content type. |
| * |
| * @param file |
| * The file that is to be reported. |
| * @param contentType |
| * The estimated content type of the file. |
| */ |
| public void setFile(File file, String contentType) { |
| name = file.getFullName(); |
| fileData = new DataHandler(new TavernaFileSource(file, contentType)); |
| } |
| |
| /** |
| * Write the content described by this class to the specified file. |
| * @param file The file to write to; must already exist. |
| * @throws IOException |
| * @throws FilesystemAccessException |
| */ |
| public void writeToFile(File file) throws IOException, |
| FilesystemAccessException { |
| try (InputStream is = fileData.getInputStream()) { |
| byte[] buf = new byte[65536]; |
| file.setContents(new byte[0]); |
| while (true) { |
| int len = is.read(buf); |
| if (len <= 0) |
| return; |
| if (len == buf.length) |
| file.appendContents(buf); |
| else { |
| byte[] shortbuf = new byte[len]; |
| arraycopy(buf, 0, shortbuf, 0, len); |
| file.appendContents(shortbuf); |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * A data source that knows how to communicate with the Taverna Server back-end. |
| * |
| * @author Donal Fellows |
| */ |
| class TavernaFileSource implements DataSource { |
| TavernaFileSource(File f, String type) { |
| this.f = f; |
| this.type = type; |
| } |
| |
| private final File f; |
| private final String type; |
| |
| @Override |
| public String getContentType() { |
| return type; |
| } |
| |
| @Override |
| public String getName() { |
| return f.getName(); |
| } |
| |
| @Override |
| public InputStream getInputStream() throws IOException { |
| final File f = this.f; |
| return new InputStream() { |
| private int idx; |
| |
| @Override |
| public int read(byte[] b, int off, int len) throws IOException { |
| byte[] r; |
| try { |
| r = f.getContents(idx, len); |
| } catch (FilesystemAccessException e) { |
| throw new IOException(e); |
| } |
| if (r == null) |
| return -1; |
| len = min(len, r.length); |
| arraycopy(r, 0, b, off, len); |
| idx += len; |
| return len; |
| } |
| |
| @Override |
| public int read() throws IOException { |
| byte[] r; |
| try { |
| r = f.getContents(idx, 1); |
| } catch (FilesystemAccessException e) { |
| throw new IOException(e); |
| } |
| if (r == null) |
| return -1; |
| idx++; |
| return r[0]; |
| } |
| }; |
| } |
| |
| @Override |
| public OutputStream getOutputStream() throws IOException { |
| final File f = this.f; |
| return new OutputStream() { |
| private boolean append = false; |
| |
| @Override |
| public void write(int b) throws IOException { |
| write(new byte[] { (byte) b }); |
| } |
| |
| @Override |
| public void write(byte[] b) throws IOException { |
| try { |
| if (append) |
| f.appendContents(b); |
| else |
| f.setContents(b); |
| append = true; |
| } catch (FilesystemAccessException e) { |
| throw new IOException(e); |
| } |
| } |
| |
| @Override |
| public void write(byte[] b, int off, int len) throws IOException { |
| byte[] ary = new byte[len]; |
| arraycopy(b, off, ary, 0, len); |
| write(ary); |
| } |
| }; |
| } |
| } |