From: <mwl...@us...> - 2008-01-31 21:07:34
|
Revision: 612 http://cishell.svn.sourceforge.net/cishell/?rev=612&view=rev Author: mwlinnem Date: 2008-01-31 13:07:23 -0800 (Thu, 31 Jan 2008) Log Message: ----------- Static Executables are now Progress Trackable. They only support the cancel operation, however (currently executed by highlighting the algorithm and click "Remove From List". Probably should have a separate more obvious cancel button). Modified Paths: -------------- trunk/templates/org.cishell.templates/src/org/cishell/templates/staticexecutable/StaticExecutableAlgorithmFactory.java trunk/templates/org.cishell.templates/src/org/cishell/templates/staticexecutable/StaticExecutableRunner.java Modified: trunk/templates/org.cishell.templates/src/org/cishell/templates/staticexecutable/StaticExecutableAlgorithmFactory.java =================================================================== --- trunk/templates/org.cishell.templates/src/org/cishell/templates/staticexecutable/StaticExecutableAlgorithmFactory.java 2008-01-30 22:32:46 UTC (rev 611) +++ trunk/templates/org.cishell.templates/src/org/cishell/templates/staticexecutable/StaticExecutableAlgorithmFactory.java 2008-01-31 21:07:23 UTC (rev 612) @@ -29,6 +29,8 @@ import org.cishell.framework.CIShellContext; import org.cishell.framework.algorithm.Algorithm; import org.cishell.framework.algorithm.AlgorithmFactory; +import org.cishell.framework.algorithm.ProgressMonitor; +import org.cishell.framework.algorithm.ProgressTrackable; import org.cishell.framework.data.Data; import org.osgi.framework.BundleContext; import org.osgi.service.component.ComponentContext; @@ -73,7 +75,7 @@ return provider; } - private class StaticExecutableAlgorithm implements Algorithm { + private class StaticExecutableAlgorithm implements Algorithm, ProgressTrackable { private String ALGORITHM; private String ALGORITHM_MACOSX_PPC; private String MACOSX; @@ -87,7 +89,10 @@ CIShellContext context; LogService logger; - public StaticExecutableAlgorithm(Data[] data, Dictionary parameters, CIShellContext context) { + private ProgressMonitor monitor; + + public StaticExecutableAlgorithm(Data[] data, Dictionary parameters, CIShellContext context) + { this.data = data; this.parameters = parameters; this.context = context; @@ -112,7 +117,7 @@ serviceProps.put("Algorithm-Directory", algName); StaticExecutableRunner runner = - new StaticExecutableRunner(bContext, context, serviceProps, parameters, data); + new StaticExecutableRunner(bContext, context, serviceProps, parameters, data, monitor); copyFiles(runner.getTempDirectory()); @@ -234,5 +239,13 @@ } return props; } + + public ProgressMonitor getProgressMonitor() { + return this.monitor; + } + + public void setProgressMonitor(ProgressMonitor monitor) { + this.monitor = monitor; + } } } Modified: trunk/templates/org.cishell.templates/src/org/cishell/templates/staticexecutable/StaticExecutableRunner.java =================================================================== --- trunk/templates/org.cishell.templates/src/org/cishell/templates/staticexecutable/StaticExecutableRunner.java 2008-01-30 22:32:46 UTC (rev 611) +++ trunk/templates/org.cishell.templates/src/org/cishell/templates/staticexecutable/StaticExecutableRunner.java 2008-01-31 21:07:23 UTC (rev 612) @@ -32,6 +32,7 @@ import org.cishell.framework.CIShellContext; import org.cishell.framework.algorithm.Algorithm; import org.cishell.framework.algorithm.AlgorithmProperty; +import org.cishell.framework.algorithm.ProgressMonitor; import org.cishell.framework.data.BasicData; import org.cishell.framework.data.Data; import org.cishell.framework.data.DataProperty; @@ -52,13 +53,21 @@ protected Properties props; protected CIShellContext ciContext; + protected ProgressMonitor monitor; + + protected Boolean processRunning = new Boolean(true); + protected Boolean killedOnPurpose = new Boolean(false); + - public StaticExecutableRunner(BundleContext bContext, CIShellContext ciContext, Properties props, Dictionary parameters, Data[] data) throws IOException { + public StaticExecutableRunner(BundleContext bContext, CIShellContext ciContext, Properties props, + Dictionary parameters, Data[] data, ProgressMonitor monitor) throws IOException { this.ciContext = ciContext; this.props = props; this.parameters = parameters; this.data = data; + this.monitor = monitor; + guiBuilder = (GUIBuilderService)ciContext.getService(GUIBuilderService.class.getName()); @@ -73,7 +82,8 @@ */ public Data[] execute() { try { - String algDir = tempDir + File.separator + props.getProperty("Algorithm-Directory") + File.separator; + String algDir = tempDir + File.separator + props.getProperty("Algorithm-Directory") + + File.separator; chmod(algDir); File[] output = execute(getTemplate(algDir), algDir); @@ -176,29 +186,57 @@ process.getOutputStream().close(); + this.processRunning = new Boolean(true); + + //start thread to consume stdout of process + new Thread(new Runnable() { public void run() { logStream(LogService.LOG_INFO, process.getInputStream()); } }).start(); + //start thread to consume stderr of process + new Thread(new Runnable() { public void run() { logStream(LogService.LOG_ERROR, process.getErrorStream()); } }).start(); + //if we have a monitor... + if (this.monitor != null) { + this.monitor.start(ProgressMonitor.CANCELLABLE, -1); + + //start thread that checks if the user wants to cancel the process + + new Thread(new Runnable() { + public void run() { + checkForCancellation(process); + } + }).start(); + } + process.waitFor(); - //successfully ran? - if (process.exitValue() != 0) { + + this.processRunning = new Boolean(false); + + if (this.monitor != null) { + + this.monitor.done(); + } + + //if the process failed unexpectedly... + if (process.exitValue() != 0 && this.killedOnPurpose.booleanValue() != true) { //display the error message using gui builder guiBuilder.showError("Algorithm Could Not Finish Execution", "Sorry, the algorithm could not finish execution.", "Please check the console window for the error log messages and report the bug.\n" +"Thank you."); } - //get the outputted files + //get the files output from the process + String[] afterFiles = dir.list(); Arrays.sort(beforeFiles); @@ -245,6 +283,21 @@ e.printStackTrace(); } } + + protected void checkForCancellation(Process process) { + while (StaticExecutableRunner.this.processRunning.booleanValue()) { + if (StaticExecutableRunner.this.monitor.isCanceled()) { + StaticExecutableRunner.this.killedOnPurpose = new Boolean(true); + process.destroy(); + } else { + } + + try { + Thread.sleep(100); + } catch (InterruptedException e) { + } + } + } protected String[] getTemplate(String algDir) { String template = "" + props.getProperty("template"); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bh...@us...> - 2008-03-27 15:38:30
|
Revision: 727 http://cishell.svn.sourceforge.net/cishell/?rev=727&view=rev Author: bh2 Date: 2008-03-27 08:38:15 -0700 (Thu, 27 Mar 2008) Log Message: ----------- made static executable runner not swallow Exception Modified Paths: -------------- trunk/templates/org.cishell.templates/src/org/cishell/templates/staticexecutable/StaticExecutableAlgorithmFactory.java trunk/templates/org.cishell.templates/src/org/cishell/templates/staticexecutable/StaticExecutableRunner.java Modified: trunk/templates/org.cishell.templates/src/org/cishell/templates/staticexecutable/StaticExecutableAlgorithmFactory.java =================================================================== --- trunk/templates/org.cishell.templates/src/org/cishell/templates/staticexecutable/StaticExecutableAlgorithmFactory.java 2008-03-27 14:50:53 UTC (rev 726) +++ trunk/templates/org.cishell.templates/src/org/cishell/templates/staticexecutable/StaticExecutableAlgorithmFactory.java 2008-03-27 15:38:15 UTC (rev 727) @@ -28,6 +28,7 @@ import org.cishell.framework.CIShellContext; import org.cishell.framework.algorithm.Algorithm; +import org.cishell.framework.algorithm.AlgorithmExecutionException; import org.cishell.framework.algorithm.AlgorithmFactory; import org.cishell.framework.algorithm.ProgressMonitor; import org.cishell.framework.algorithm.ProgressTrackable; @@ -108,7 +109,7 @@ ALGORITHM_DEFAULT = ALGORITHM + "default/"; } - public Data[] execute() { + public Data[] execute() throws AlgorithmExecutionException { try { Properties serviceProps = getProperties("/"+algName+"/service.properties"); Properties configProps = getProperties("/"+algName+"/config.properties"); @@ -122,13 +123,12 @@ copyFiles(runner.getTempDirectory()); return runner.execute(); - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException(e); + } catch (IOException e) { + throw new AlgorithmExecutionException(e.getMessage(), e); } } - private void copyFiles(File dir) throws IOException { + private void copyFiles(File dir) throws IOException, AlgorithmExecutionException { Enumeration e = bContext.getBundle().getEntryPaths("/"+algName); Set entries = new HashSet(); @@ -173,7 +173,7 @@ } if (path == null) { - throw new RuntimeException("Unable to find compatible executable"); + throw new AlgorithmExecutionException("Unable to find compatible executable"); } else { //logger.log(LogService.LOG_DEBUG, "base path: "+path+ // "\n\t"+dir.getAbsolutePath() + "\n\n"); Modified: trunk/templates/org.cishell.templates/src/org/cishell/templates/staticexecutable/StaticExecutableRunner.java =================================================================== --- trunk/templates/org.cishell.templates/src/org/cishell/templates/staticexecutable/StaticExecutableRunner.java 2008-03-27 14:50:53 UTC (rev 726) +++ trunk/templates/org.cishell.templates/src/org/cishell/templates/staticexecutable/StaticExecutableRunner.java 2008-03-27 15:38:15 UTC (rev 727) @@ -30,6 +30,7 @@ import org.cishell.framework.CIShellContext; import org.cishell.framework.algorithm.Algorithm; +import org.cishell.framework.algorithm.AlgorithmExecutionException; import org.cishell.framework.algorithm.AlgorithmProperty; import org.cishell.framework.algorithm.ProgressMonitor; import org.cishell.framework.data.BasicData; @@ -76,19 +77,14 @@ /** * @see org.cishell.framework.algorithm.Algorithm#execute() */ - public Data[] execute() { - try { - String algDir = tempDir + File.separator - + props.getProperty("Algorithm-Directory") + File.separator; + public Data[] execute() throws AlgorithmExecutionException { + String algDir = tempDir + File.separator + + props.getProperty("Algorithm-Directory") + File.separator; - chmod(algDir); - File[] output = execute(getTemplate(algDir), algDir); + chmod(algDir); + File[] output = execute(getTemplate(algDir), algDir); - return toData(output); - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException(e); - } + return toData(output); } protected Data[] toData(File[] files) { @@ -164,7 +160,7 @@ return data; } - protected void chmod(String baseDir) { + protected void chmod(String baseDir) throws AlgorithmExecutionException { // FIXME: Surely java has a way to do this!!!! if (new File("/bin/chmod").exists()) { try { @@ -172,21 +168,27 @@ Runtime.getRuntime().exec("/bin/chmod +x " + executable) .waitFor(); } catch (IOException e) { - e.printStackTrace(); + throw new AlgorithmExecutionException(e); } catch (InterruptedException e) { - e.printStackTrace(); + throw new AlgorithmExecutionException(e); } } } - protected File[] execute(String[] cmdarray, String baseDir) - throws Exception { + protected File[] execute(String[] cmdarray, String baseDir) + throws AlgorithmExecutionException { File dir = new File(baseDir); String[] beforeFiles = dir.list(); - final Process process = Runtime.getRuntime().exec(cmdarray, null, - new File(baseDir)); - process.getOutputStream().close(); + Process process = null; + try { + process = Runtime.getRuntime().exec(cmdarray, null, + new File(baseDir)); + process.getOutputStream().close(); + } catch (IOException e1) { + throw new AlgorithmExecutionException(e1.getMessage(),e1); + } + monitor.start(ProgressMonitor.CANCELLABLE, -1); InputStream in = process.getInputStream(); @@ -265,7 +267,7 @@ } protected StringBuffer logStream(int logLevel, InputStream is, - StringBuffer buffer) { + StringBuffer buffer) throws AlgorithmExecutionException { try { int available = is.available(); if (available > 0) { @@ -278,7 +280,7 @@ } catch (EOFException e) { //normal operation } catch (IOException e) { - e.printStackTrace(); + throw new AlgorithmExecutionException("Error when processing the algorithm's screen output",e); } return buffer; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mwl...@us...> - 2008-07-08 21:24:01
|
Revision: 786 http://cishell.svn.sourceforge.net/cishell/?rev=786&view=rev Author: mwlinnem Date: 2008-07-08 14:23:28 -0700 (Tue, 08 Jul 2008) Log Message: ----------- Medium sized refactoring. Modified Paths: -------------- trunk/templates/org.cishell.templates/src/org/cishell/templates/staticexecutable/StaticExecutableAlgorithmFactory.java trunk/templates/org.cishell.templates/src/org/cishell/templates/staticexecutable/StaticExecutableRunner.java Modified: trunk/templates/org.cishell.templates/src/org/cishell/templates/staticexecutable/StaticExecutableAlgorithmFactory.java =================================================================== --- trunk/templates/org.cishell.templates/src/org/cishell/templates/staticexecutable/StaticExecutableAlgorithmFactory.java 2008-07-08 18:50:58 UTC (rev 785) +++ trunk/templates/org.cishell.templates/src/org/cishell/templates/staticexecutable/StaticExecutableAlgorithmFactory.java 2008-07-08 21:23:28 UTC (rev 786) @@ -31,13 +31,7 @@ MetaTypeProvider provider; public StaticExecutableAlgorithmFactory() {} - - //pretty sure this isn't used by anything, but I fear deleting it. - public StaticExecutableAlgorithmFactory(String algName, BundleContext bContext) { - this.algName = algName; - this.bContext = bContext; - } - + protected void activate(ComponentContext ctxt) { bContext = ctxt.getBundleContext(); algName = (String)ctxt.getProperties().get("Algorithm-Directory"); @@ -61,4 +55,11 @@ public MetaTypeProvider createParameters(Data[] data) { return provider; } + + //pretty sure this isn't used by anything, but I fear deleting it. + public StaticExecutableAlgorithmFactory(String algName, BundleContext bContext) { + this.algName = algName; + this.bContext = bContext; + } + } Modified: trunk/templates/org.cishell.templates/src/org/cishell/templates/staticexecutable/StaticExecutableRunner.java =================================================================== --- trunk/templates/org.cishell.templates/src/org/cishell/templates/staticexecutable/StaticExecutableRunner.java 2008-07-08 18:50:58 UTC (rev 785) +++ trunk/templates/org.cishell.templates/src/org/cishell/templates/staticexecutable/StaticExecutableRunner.java 2008-07-08 21:23:28 UTC (rev 786) @@ -15,18 +15,25 @@ import java.io.EOFException; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.net.URL; +import java.nio.channels.Channels; +import java.nio.channels.FileChannel; +import java.nio.channels.ReadableByteChannel; import java.util.ArrayList; import java.util.Arrays; import java.util.Dictionary; import java.util.Enumeration; import java.util.HashMap; +import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; +import java.util.Set; import org.cishell.framework.CIShellContext; import org.cishell.framework.algorithm.Algorithm; @@ -45,124 +52,140 @@ * @author Bruce Herr (bh...@bh...) */ public class StaticExecutableRunner implements Algorithm { - protected final String tempDir; + private String ALGORITHM; + private String ALGORITHM_MACOSX_PPC; + private String MACOSX; + private String ALGORITHM_WIN32; + private String WIN32; + private String ALGORITHM_LINUX_X86; + private String LINUX; + private String ALGORITHM_DEFAULT; + + protected final String algDirPath; + protected final String tempDirPath; protected final Data[] data; protected Dictionary parameters; protected Properties props; protected CIShellContext ciContext; protected ProgressMonitor monitor; + protected BundleContext bContext; + protected String algName; - public StaticExecutableRunner(BundleContext bContext, - CIShellContext ciContext, Properties props, Dictionary parameters, - Data[] data, ProgressMonitor monitor) throws IOException { + public StaticExecutableRunner(BundleContext bContext, CIShellContext ciContext, Properties props, + Dictionary parameters, Data[] data, ProgressMonitor monitor, String algName) throws IOException { + + // assign normal member-variables + + this.bContext = bContext; this.ciContext = ciContext; this.props = props; this.parameters = parameters; this.data = data; this.monitor = monitor; - if (monitor == null) - this.monitor = ProgressMonitor.NULL_MONITOR; - if (data == null) - data = new Data[0]; - if (parameters == null) - parameters = new Hashtable(); + this.algName = algName; - tempDir = makeTempDirectory(); + // determine directory paths for each platform, based on algName + + ALGORITHM = algName + "/"; + ALGORITHM_MACOSX_PPC = ALGORITHM + "macosx.ppc/"; + MACOSX = "macosx"; + ALGORITHM_WIN32 = ALGORITHM + "win32/"; + WIN32 = "win32"; + ALGORITHM_LINUX_X86 = ALGORITHM + "linux.x86/"; + LINUX = "linux"; + ALGORITHM_DEFAULT = ALGORITHM + "default/"; + + // if a constructor variable was null, use a null object version of it if possible + + if (monitor == null) this.monitor = ProgressMonitor.NULL_MONITOR; + if (data == null) data = new Data[0]; + if (parameters == null) parameters = new Hashtable(); + + // make a temporary directory to run the executable in + + tempDirPath = makeTempDirectory(); + + algDirPath = tempDirPath + File.separator + props.getProperty("Algorithm-Directory") + File.separator; + } /** * @see org.cishell.framework.algorithm.Algorithm#execute() */ public Data[] execute() throws AlgorithmExecutionException { - String algDir = tempDir + File.separator - + props.getProperty("Algorithm-Directory") + File.separator; + copyFilesUsedByExecutableIntoDir(getTempDirectory()); + makeDirExecutable(algDirPath); + + String[] commandLineArguments = createCommandLineArguments(algDirPath, data, parameters); + + File[] rawOutput = executeProgram(commandLineArguments, algDirPath); - chmod(algDir); - File[] output = execute(getTemplate(algDir), algDir); - - return toData(output); + return formatAsData(rawOutput); } - protected Data[] toData(File[] files) { - String outData = (String) props.get(AlgorithmProperty.OUT_DATA); + private void copyFilesUsedByExecutableIntoDir(File dir) throws AlgorithmExecutionException { + try { + Enumeration e = bContext.getBundle().getEntryPaths("/" + algName); - // if out data is null then it returns no data - if (("" + outData).trim().equalsIgnoreCase(AlgorithmProperty.NULL_DATA)) { - return null; - } + Set entries = new HashSet(); - String[] formats = outData.split(","); + while (e != null && e.hasMoreElements()) { + String entryPath = (String) e.nextElement(); + // logger.log(LogService.LOG_DEBUG, "entry: " + entryPath + "\n\n"); + if (entryPath.endsWith("/")) { + entries.add(entryPath); + } + } - Map nameToFileMap = new HashMap(); - for (int i = 0; i < files.length; i++) { - nameToFileMap.put(files[i].getName(), files[i]); - } + dir = new File(dir.getPath() + File.separator + algName); + dir.mkdirs(); - Data[] data = null; - if (formats.length > files.length) { - data = new Data[formats.length]; - } else { - data = new Data[files.length]; - } + String os = bContext.getProperty("osgi.os"); + String arch = bContext.getProperty("osgi.arch"); - for (int i = 0; i < data.length; i++) { - String file = props.getProperty("outFile[" + i + "]", null); + String path = null; - if (i < formats.length) { - File f = (File) nameToFileMap.remove(file); + // take the default, if there + if (entries.contains(ALGORITHM_DEFAULT)) { + String default_path = ALGORITHM_DEFAULT; + // logger.log(LogService.LOG_DEBUG, "base path: "+default_path+ + // "\n\t"+dir.getAbsolutePath() + "\n\n"); + copyDir(dir, default_path, 0); + } - if (f != null) { - data[i] = new BasicData(f, formats[i]); + // but override with platform idiosyncracies + if (os.equals(WIN32) && entries.contains(ALGORITHM_WIN32)) { + path = ALGORITHM_WIN32; + } else if (os.equals(MACOSX) && entries.contains(ALGORITHM_MACOSX_PPC)) { + path = ALGORITHM_MACOSX_PPC; + } else if (os.equals(LINUX) && entries.contains(ALGORITHM_LINUX_X86)) { + path = ALGORITHM_LINUX_X86; + } - String label = props.getProperty( - "outFile[" + i + "].label", f.getName()); - data[i].getMetadata().put(DataProperty.LABEL, label); + String platform_path = ALGORITHM + os + "." + arch + "/"; + // and always override anything with an exact match + if (entries.contains(platform_path)) { + path = platform_path; + } - String type = props.getProperty("outFile[" + i + "].type", - DataProperty.OTHER_TYPE); - type = type.trim(); - if (type.equalsIgnoreCase(DataProperty.MATRIX_TYPE)) { - type = DataProperty.MATRIX_TYPE; - } else if (type.equalsIgnoreCase(DataProperty.NETWORK_TYPE)) { - type = DataProperty.NETWORK_TYPE; - } else if (type.equalsIgnoreCase(DataProperty.TREE_TYPE)) { - type = DataProperty.TREE_TYPE; - } else if (type.equalsIgnoreCase(DataProperty.TEXT_TYPE)) { - type = DataProperty.TEXT_TYPE; - } else if (type.equalsIgnoreCase(DataProperty.PLOT_TYPE)) { - type = DataProperty.PLOT_TYPE; - } else if (type.equalsIgnoreCase(DataProperty.TABLE_TYPE)) { - type = DataProperty.TABLE_TYPE; - }else { - type = DataProperty.OTHER_TYPE; - } - - data[i].getMetadata().put(DataProperty.TYPE, type); - } + if (path == null) { + throw new AlgorithmExecutionException("Unable to find compatible executable"); } else { - Iterator iter = nameToFileMap.values().iterator(); - while (iter.hasNext()) { - File f = (File) iter.next(); - - data[i] = new BasicData(f, "file:text/plain"); - data[i].getMetadata().put(DataProperty.LABEL, f.getName()); - - i++; - } - break; + // logger.log(LogService.LOG_DEBUG, "base path: "+path+ + // "\n\t"+dir.getAbsolutePath() + "\n\n"); + copyDir(dir, path, 0); } + } catch (IOException e) { + throw new AlgorithmExecutionException(e.getMessage(), e); } - - return data; } - protected void chmod(String baseDir) throws AlgorithmExecutionException { + protected void makeDirExecutable(String baseDir) throws AlgorithmExecutionException { // FIXME: Surely java has a way to do this!!!! if (new File("/bin/chmod").exists()) { try { String executable = baseDir + props.getProperty("executable"); - Runtime.getRuntime().exec("/bin/chmod +x " + executable) - .waitFor(); + Runtime.getRuntime().exec("/bin/chmod +x " + executable).waitFor(); } catch (IOException e) { throw new AlgorithmExecutionException(e); } catch (InterruptedException e) { @@ -171,31 +194,36 @@ } } - protected File[] execute(String[] cmdarray, String baseDir) - throws AlgorithmExecutionException { - File dir = new File(baseDir); - String[] beforeFiles = dir.list(); + protected File[] executeProgram(String[] cmdarray, String baseDirPath) throws AlgorithmExecutionException { + //remember which files were in the directory before we ran the program + File baseDir = new File(baseDirPath); + String[] beforeFiles = baseDir.list(); + //create and run the executing process Process process = null; try { - process = Runtime.getRuntime().exec(cmdarray, null, - new File(baseDir)); + process = Runtime.getRuntime().exec(cmdarray, null, new File(baseDirPath)); process.getOutputStream().close(); } catch (IOException e1) { - throw new AlgorithmExecutionException(e1.getMessage(),e1); + throw new AlgorithmExecutionException(e1.getMessage(), e1); } + + //monitor the process, printing its stdout and stderr to console monitor.start(ProgressMonitor.CANCELLABLE, -1); - + InputStream in = process.getInputStream(); StringBuffer in_buffer = new StringBuffer(); - + InputStream err = process.getErrorStream(); StringBuffer err_buffer = new StringBuffer(); Integer exitValue = null; boolean killedOnPurpose = false; + //while the process is still running... while (!killedOnPurpose && exitValue == null) { + //print its output, and watch to see if it has finished/died. + in_buffer = logStream(LogService.LOG_INFO, in, in_buffer); err_buffer = logStream(LogService.LOG_ERROR, err, err_buffer); @@ -223,13 +251,15 @@ // if the process failed unexpectedly... if (process.exitValue() != 0 && !killedOnPurpose) { - throw new AlgorithmExecutionException( - "Algorithm exited unexpectedly (exit value: "+process.exitValue()+ - "). Please check the console window for any error messages."); + throw new AlgorithmExecutionException("Algorithm exited unexpectedly (exit value: " + process.exitValue() + + "). Please check the console window for any error messages."); } - // get the files output from the process - String[] afterFiles = dir.list(); + //look at the files in the directory now, and compare to before we ran the program. + //any file that is in the directory now, but wasn't before, is an output file. + //return all the output files. + + String[] afterFiles = baseDir.list(); Arrays.sort(beforeFiles); Arrays.sort(afterFiles); @@ -239,41 +269,111 @@ int beforeIndex = 0; int afterIndex = 0; - while (beforeIndex < beforeFiles.length - && afterIndex < afterFiles.length) { + while (beforeIndex < beforeFiles.length && afterIndex < afterFiles.length) { if (beforeFiles[beforeIndex].equals(afterFiles[afterIndex])) { beforeIndex++; afterIndex++; } else { - outputs.add(new File(baseDir + afterFiles[afterIndex])); + outputs.add(new File(baseDirPath + afterFiles[afterIndex])); afterIndex++; } } // get any remaining new files while (afterIndex < afterFiles.length) { - outputs.add(new File(baseDir + afterFiles[afterIndex])); + outputs.add(new File(baseDirPath + afterFiles[afterIndex])); afterIndex++; } return (File[]) outputs.toArray(new File[] {}); } - protected StringBuffer logStream(int logLevel, InputStream is, - StringBuffer buffer) throws AlgorithmExecutionException { + protected Data[] formatAsData(File[] files) { + String outData = (String) props.get(AlgorithmProperty.OUT_DATA); + + // if out data is null then it returns no data + if (("" + outData).trim().equalsIgnoreCase(AlgorithmProperty.NULL_DATA)) { + return null; + } + + String[] formats = outData.split(","); + + Map nameToFileMap = new HashMap(); + for (int i = 0; i < files.length; i++) { + nameToFileMap.put(files[i].getName(), files[i]); + } + + Data[] data = null; + if (formats.length > files.length) { + data = new Data[formats.length]; + } else { + data = new Data[files.length]; + } + + for (int i = 0; i < data.length; i++) { + String file = props.getProperty("outFile[" + i + "]", null); + + if (i < formats.length) { + File f = (File) nameToFileMap.remove(file); + + if (f != null) { + data[i] = new BasicData(f, formats[i]); + + String label = props.getProperty("outFile[" + i + "].label", f.getName()); + data[i].getMetadata().put(DataProperty.LABEL, label); + + String type = props.getProperty("outFile[" + i + "].type", DataProperty.OTHER_TYPE); + type = type.trim(); + if (type.equalsIgnoreCase(DataProperty.MATRIX_TYPE)) { + type = DataProperty.MATRIX_TYPE; + } else if (type.equalsIgnoreCase(DataProperty.NETWORK_TYPE)) { + type = DataProperty.NETWORK_TYPE; + } else if (type.equalsIgnoreCase(DataProperty.TREE_TYPE)) { + type = DataProperty.TREE_TYPE; + } else if (type.equalsIgnoreCase(DataProperty.TEXT_TYPE)) { + type = DataProperty.TEXT_TYPE; + } else if (type.equalsIgnoreCase(DataProperty.PLOT_TYPE)) { + type = DataProperty.PLOT_TYPE; + } else if (type.equalsIgnoreCase(DataProperty.TABLE_TYPE)) { + type = DataProperty.TABLE_TYPE; + } else { + type = DataProperty.OTHER_TYPE; + } + + data[i].getMetadata().put(DataProperty.TYPE, type); + } + } else { + Iterator iter = nameToFileMap.values().iterator(); + while (iter.hasNext()) { + File f = (File) iter.next(); + + data[i] = new BasicData(f, "file:text/plain"); + data[i].getMetadata().put(DataProperty.LABEL, f.getName()); + + i++; + } + break; + } + } + + return data; + } + + protected StringBuffer logStream(int logLevel, InputStream is, StringBuffer buffer) + throws AlgorithmExecutionException { try { int available = is.available(); if (available > 0) { byte[] b = new byte[available]; is.read(b); buffer.append(new String(b)); - + buffer = log(logLevel, buffer); } } catch (EOFException e) { - //normal operation + // normal operation } catch (IOException e) { - throw new AlgorithmExecutionException("Error when processing the algorithm's screen output",e); + throw new AlgorithmExecutionException("Error when processing the algorithm's screen output", e); } return buffer; @@ -281,8 +381,7 @@ protected StringBuffer log(int logLevel, StringBuffer buffer) { if (buffer.indexOf("\n") != -1) { // any new newlines to output? - LogService log = (LogService) ciContext.getService(LogService.class - .getName()); + LogService log = (LogService) ciContext.getService(LogService.class.getName()); int lastGoodIndex = 0; int fromIndex = 0; @@ -294,14 +393,14 @@ String message = buffer.substring(fromIndex, toIndex); if (log == null) { - // This will probably never come up, but if it does + // This will probably never come up, but if it does // we'll still get some output. System.out.println(message); } else { log.log(logLevel, message); } - fromIndex = toIndex+1; - lastGoodIndex = toIndex+1; + fromIndex = toIndex + 1; + lastGoodIndex = toIndex + 1; } else { fromIndex = -1; } @@ -315,12 +414,12 @@ return buffer; } - protected String[] getTemplate(String algDir) { + protected String[] createCommandLineArguments(String algDir, Data[] data, Dictionary parameters) { String template = "" + props.getProperty("template"); String[] cmdarray = template.split("\\s"); for (int i = 0; i < cmdarray.length; i++) { - cmdarray[i] = substiteVars(cmdarray[i]); + cmdarray[i] = substituteVars(cmdarray[i], data, parameters); } // TODO: Expanded later to support .cmd and other extensions @@ -334,9 +433,11 @@ return cmdarray; } - protected String substiteVars(String str) { - str = str.replaceAll("\\$\\{executable\\}", props - .getProperty("executable")); + // replaces place-holder variables in the template with the actual arguments the executable needs to work. + // (real names of files instead of inFile[i], for instance) + // (also, real values like "6" or "dog" instead of placeholders for parameters) + protected String substituteVars(String str, Data[] data, Dictionary parameters) { + str = str.replaceAll("\\$\\{executable\\}", props.getProperty("executable")); for (int i = 0; i < data.length; i++) { String file = ((File) data[i].getData()).getAbsolutePath(); @@ -356,8 +457,7 @@ String key = (String) i.nextElement(); Object value = parameters.get(key); - if (value == null) - value = ""; + if (value == null) value = ""; str = str.replaceAll("\\$\\{" + key + "\\}", value.toString()); } @@ -366,17 +466,63 @@ } public File getTempDirectory() { - return new File(tempDir); + return new File(tempDirPath); } protected String makeTempDirectory() throws IOException { File sessionDir = Activator.getTempDirectory(); - File dir = File.createTempFile("StaticExecutableRunner-", "", - sessionDir); + File dir = File.createTempFile("StaticExecutableRunner-", "", sessionDir); dir.delete(); dir.mkdirs(); return dir.getAbsolutePath(); } + + private void copyDir(File dir, String dirPath, int depth) throws IOException { + Enumeration e = bContext.getBundle().getEntryPaths(dirPath); + + // dirPath = dirPath.replace('/', File.separatorChar); + + while (e != null && e.hasMoreElements()) { + String path = (String) e.nextElement(); + + if (path.endsWith("/")) { + String dirName = getName(path); + + File subDirectory = new File(dir.getPath() + File.separator + dirName); + subDirectory.mkdirs(); + // logger.log(LogService.LOG_DEBUG, "path: " + depth + " "+path+ + // "\n\t"+subDirectory.getAbsolutePath() + "\n\n"); + copyDir(subDirectory, path, depth + 1); + } else { + copyFile(dir, path); + } + } + } + + private void copyFile(File dir, String path) throws IOException { + URL entry = bContext.getBundle().getEntry(path); + + // path = path.replace('/', File.separatorChar); + String file = getName(path); + FileOutputStream outStream = new FileOutputStream(dir.getPath() + File.separator + file); + + ReadableByteChannel in = Channels.newChannel(entry.openStream()); + FileChannel out = outStream.getChannel(); + out.transferFrom(in, 0, Integer.MAX_VALUE); + + in.close(); + out.close(); + } + + private String getName(String path) { + if (path.lastIndexOf('/') == path.length() - 1) { + path = path.substring(0, path.length() - 1); + } + + path = path.substring(path.lastIndexOf('/') + 1, path.length()); + + return path; + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |