Java tutorial
/* Part of the KnowARC Janitor Use-case processor for taverna * written 2007-2010 by Hajo Nils Krabbenhoeft and Steffen Moeller * University of Luebeck, Institute for Neuro- and Bioinformatics * University of Luebeck, Institute for Dermatolgy * * This package is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This package is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this package; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package de.uni_luebeck.inb.knowarc.usecases.invocation; import java.io.BufferedWriter; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.MalformedURLException; import java.net.URL; import java.util.HashMap; import java.util.List; import java.util.Set; import org.apache.commons.io.IOUtils; import net.sf.taverna.t2.invocation.InvocationContext; import net.sf.taverna.t2.reference.ExternalReferenceSPI; import net.sf.taverna.t2.reference.Identified; import net.sf.taverna.t2.reference.IdentifiedList; import net.sf.taverna.t2.reference.ReferenceService; import net.sf.taverna.t2.reference.ReferenceServiceException; import net.sf.taverna.t2.reference.ReferenceSet; import net.sf.taverna.t2.reference.T2Reference; import net.sf.taverna.t2.reference.impl.external.object.InlineByteArrayReferenceBuilder; import net.sf.taverna.t2.reference.impl.external.object.InlineStringReferenceBuilder; import de.uni_luebeck.inb.knowarc.usecases.ScriptInput; import de.uni_luebeck.inb.knowarc.usecases.ScriptInputStatic; import de.uni_luebeck.inb.knowarc.usecases.ScriptInputUser; import de.uni_luebeck.inb.knowarc.usecases.UseCaseDescription; /** * An abstraction of various forms to bring job using the software that is * referenced as a use case towards their execution. * * @author Hajo Nils Krabbenhoeft with some contribution by * @author Steffen Moeller */ public abstract class UseCaseInvocation { private String runId; protected static String getActualOsCommand(String osCommand, String pathToOriginal, String targetName, String pathTarget) { String actualOsCommand = osCommand; actualOsCommand = actualOsCommand.replace("%%PATH_TO_ORIGINAL%%", pathToOriginal); actualOsCommand = actualOsCommand.replace("%%TARGET_NAME%%", targetName); actualOsCommand = actualOsCommand.replace("%%PATH_TO_TARGET%%", pathTarget); return actualOsCommand; } protected UseCaseDescription usecase; protected final HashMap<String, String> tags = new HashMap<String, String>(); protected int nTempFiles = 0; private static int submissionID = 0; protected static InlineByteArrayReferenceBuilder inlineByteArrayReferenceBuilder = new InlineByteArrayReferenceBuilder(); protected static InlineStringReferenceBuilder inlineStringReferenceBuilder = new InlineStringReferenceBuilder(); private InvocationContext invocationContext; private boolean retrieveData; /* * get the class of the data we expect for a given input */ @SuppressWarnings("unchecked") public Class getType(String inputName) { if (!usecase.getInputs().containsKey(inputName)) return null; ScriptInputUser input = (ScriptInputUser) usecase.getInputs().get(inputName); if (input.isList()) { if (input.isBinary()) return List.class; else return List.class; } else { if (input.isBinary()) return byte[].class; else return String.class; } } /* * get a list of all the input port names */ public Set<String> getInputs() { return usecase.getInputs().keySet(); } /* * get a id, incremented with each job. thus, this should be thread-wide * unique */ public synchronized int getSubmissionID() { return submissionID++; } /* * set the data for the input port with given name */ @SuppressWarnings("unchecked") public void setInput(String inputName, ReferenceService referenceService, T2Reference t2Reference) throws InvocationException { if (t2Reference == null) { throw new InvocationException("No input specified for " + inputName); } ScriptInputUser input = (ScriptInputUser) usecase.getInputs().get(inputName); if (input.isList()) { IdentifiedList<T2Reference> listOfReferences = (IdentifiedList<T2Reference>) referenceService .getListService().getList(t2Reference); if (!input.isConcatenate()) { // this is a list input (not concatenated) // so write every element to its own temporary file // and create a filelist file // we need to write the list elements to temporary files ScriptInputUser listElementTemp = new ScriptInputUser(); listElementTemp.setBinary(input.isBinary()); listElementTemp.setTempFile(true); String lineEndChar = "\n"; if (!input.isFile() && !input.isTempFile()) { lineEndChar = " "; } String listFileContent = ""; String filenamesFileContent = ""; // create a list of all temp file names for (T2Reference cur : listOfReferences) { String tmp = setOneInput(referenceService, cur, listElementTemp); listFileContent += tmp + lineEndChar; int ind = tmp.lastIndexOf('/'); if (ind == -1) { ind = tmp.lastIndexOf('\\'); } if (ind != -1) { tmp = tmp.substring(ind + 1); } filenamesFileContent += tmp + lineEndChar; } // how do we want the listfile to be stored? ScriptInputUser listFile = new ScriptInputUser(); listFile.setBinary(false); // since its a list file listFile.setFile(input.isFile()); listFile.setTempFile(input.isTempFile()); listFile.setTag(input.getTag()); T2Reference listFileContentReference = referenceService.register(listFileContent, 0, true, invocationContext); tags.put(listFile.getTag(), setOneInput(referenceService, listFileContentReference, listFile)); listFile.setTag(input.getTag() + "_NAMES"); T2Reference filenamesFileContentReference = referenceService.register(filenamesFileContent, 0, true, null); tags.put(listFile.getTag(), setOneInput(referenceService, filenamesFileContentReference, listFile)); } else { try { // first, concatenate all data if (input.isBinary()) { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); BufferedWriter outputWriter = new BufferedWriter(new OutputStreamWriter(outputStream)); for (T2Reference cur : listOfReferences) { InputStreamReader inputReader = new InputStreamReader( getAsStream(referenceService, cur)); IOUtils.copyLarge(inputReader, outputWriter); inputReader.close(); } outputWriter.close(); T2Reference binaryReference = referenceService.register(outputStream.toByteArray(), 0, true, invocationContext); tags.put(input.getTag(), setOneInput(referenceService, binaryReference, input)); } else { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); BufferedWriter outputWriter = new BufferedWriter(new OutputStreamWriter(outputStream)); for (T2Reference cur : listOfReferences) { InputStreamReader inputReader = new InputStreamReader( getAsStream(referenceService, cur)); IOUtils.copyLarge(inputReader, outputWriter); outputWriter.write(" "); inputReader.close(); } outputWriter.close(); T2Reference binaryReference = referenceService.register(outputStream.toByteArray(), 0, true, invocationContext); tags.put(input.getTag(), setOneInput(referenceService, binaryReference, input)); } } catch (IOException e) { throw new InvocationException(e); } } } else { tags.put(input.getTag(), setOneInput(referenceService, t2Reference, input)); } } /* * submit a grid job and wait for it to finish, then get the result as * on-demand downloads or directly as data (in case of local execution) */ public HashMap<String, Object> Submit(ReferenceService referenceService) throws InvocationException { submit_generate_job(referenceService); return submit_wait_fetch_results(referenceService); } /* * just submit the job. useful if you want to wait for it to finish later on * * Can the statics be made more static? */ public void submit_generate_job(ReferenceService referenceService) throws InvocationException { for (ScriptInputStatic input : usecase.getStatic_inputs()) { T2Reference ref; if (input.getUrl() != null) { // Does this work OK with binary try { ref = referenceService.register(new URL(input.getUrl()), 0, true, null); } catch (ReferenceServiceException e) { throw new InvocationException(e); } catch (MalformedURLException e) { throw new InvocationException(e); } } else { ref = referenceService.register((String) input.getContent(), 0, true, null); } tags.put(input.getTag(), setOneInput(referenceService, ref, input)); } submit_generate_job_inner(); } protected abstract void submit_generate_job_inner() throws InvocationException; /* * wait for a submitted job to finish and fetch the results */ public abstract HashMap<String, Object> submit_wait_fetch_results(ReferenceService referenceService) throws InvocationException; public abstract String setOneInput(ReferenceService referenceService, T2Reference t2Reference, ScriptInput input) throws InvocationException; protected InputStream getAsStream(ReferenceService referenceService, T2Reference t2Reference) { Identified identified = referenceService.resolveIdentifier(t2Reference, null, null); if (identified instanceof ReferenceSet) { ExternalReferenceSPI ref = ((ReferenceSet) identified).getExternalReferences().iterator().next(); return ref.openStream(invocationContext); } return null; } public void setContext(InvocationContext context) { this.invocationContext = context; } public InvocationContext getContext() { return this.invocationContext; } public abstract void setStdIn(ReferenceService referenceService, T2Reference t2Reference); public abstract void rememberRun(String runId); /** * @return the runId */ protected String getRunId() { return runId; } /** * @param runId the runId to set */ protected void setRunId(String runId) { this.runId = runId; } /** * @return the retrieveData */ protected boolean isRetrieveData() { return retrieveData; } /** * @param retrieveData the retrieveData to set */ protected void setRetrieveData(boolean retrieveData) { this.retrieveData = retrieveData; } }