/* * This file is part of the OSMembrane project. * More informations under www.osmembrane.de * * The project is licensed under the GNU GENERAL PUBLIC LICENSE 3.0. * for more details about the license see http://www.osmembrane.de/license/ * * Source: $HeadURL$ ($Revision$) * Last changed: $Date$ */ package de.osmembrane.tools; import java.awt.event.ActionEvent; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; import javax.swing.Action; import de.osmembrane.Application; import de.osmembrane.controller.ActionRegistry; import de.osmembrane.exceptions.ControlledException; import de.osmembrane.exceptions.ExceptionSeverity; import de.osmembrane.view.interfaces.IExecutionStateDialog; /** * Executor for a pipeline * * @author jakob_jarosch */ public class PipelineExecutor extends Thread implements WindowListener { private String osmosisPath; private File workingDirectory; private List<String> parameters; private IExecutionStateDialog dialog; private Class<? extends Action> callbackEvent; private int executionState = -1; /** * Initialize the pipeline executor. * * @throws IllegalArgumentException * when the osmosis executable is not runnable. */ public PipelineExecutor(String osmosisPath, String workingDirectory, List<String> parameters, IExecutionStateDialog dialog) { setPath(osmosisPath); this.workingDirectory = new File(workingDirectory); this.parameters = parameters; this.dialog = dialog; dialog.addWindowListener(this); dialog.setState(I18N.getInstance().getString( "Tools.PipelineExecutor.ParametersSet")); dialog.setProgress(5); dialog.setCloseButtonCaption(I18N.getInstance() .getString("View.Cancel")); } /** * Sets a call back action which is called after completing of the * execution. * * @param event */ public void setCallbackAction(Class<? extends Action> event) { this.callbackEvent = event; } @Override public void run() { dialog.setState(I18N.getInstance().getString( "Tools.PipelineExecutor.StartingOsmosis")); dialog.setProgress(10); List<String> cmdLine = new ArrayList<String>(parameters.size() + 1); cmdLine.add(osmosisPath); cmdLine.addAll(parameters); try { ProcessBuilder processBuilder = new ProcessBuilder(cmdLine); Process process = processBuilder.directory(workingDirectory) .redirectErrorStream(true).start(); final BufferedReader reader = new BufferedReader( new InputStreamReader(process.getInputStream())); dialog.setState(I18N.getInstance().getString( "Tools.PipelineExecutor.RunningOsmosis")); dialog.setProgress(10); String line = null; do { try { ReadThread thread = new ReadThread(reader); thread.start(); thread.join(); line = thread.getLine(); } catch (InterruptedException e) { interrupt(); line = null; } if (line != null) { dialog.addOutputLine(line); } } while (line != null && !isInterrupted()); if (!isInterrupted()) { int exitValue = -255; try { exitValue = process.waitFor(); if (exitValue == 0) { dialog.setState(I18N.getInstance().getString( "Tools.PipelineExecutor.Finished")); dialog.setCloseButtonCaption(I18N.getInstance() .getString("View.OK")); dialog.setProgress(100); } else { dialog.setState(I18N.getInstance().getString( "Tools.PipelineExecutor.Failed")); dialog.setCloseButtonCaption(I18N.getInstance() .getString("View.Close")); } executionState = exitValue; } catch (InterruptedException e) { interrupt(); } } else { process.destroy(); reader.close(); } } catch (IOException e) { dialog.setState(I18N.getInstance().getString( "Tools.PipelineExecutor.IOExecption")); dialog.setProgress(0); Application.handleException(new ControlledException(this, ExceptionSeverity.WARNING, e, I18N.getInstance().getString( "Tools.PipelineExecutor.IOExecption"))); } } /** * Sets the osmosisPath and validates it. * * @param osmosisPath */ private void setPath(String osmosisPath) { if (osmosisPath == null) { throw new IllegalArgumentException(); } File f = new File(osmosisPath); if (!f.isFile() || !f.canExecute() || !f.canRead()) { throw new IllegalArgumentException(); } this.osmosisPath = osmosisPath; } /** * The Windows-closed action of the dialog in the view. */ @Override public void windowClosing(WindowEvent e) { dialog.removeWindowListener(this); if (this.isAlive()) { this.interrupt(); } else { if (callbackEvent != null && executionState == 0) { ActionRegistry.getInstance().get(callbackEvent) .actionPerformed(new ActionEvent(this, 0, "finished")); } } } @Override public void windowClosed(WindowEvent e) { } @Override public void windowOpened(WindowEvent e) { } @Override public void windowIconified(WindowEvent e) { } @Override public void windowDeiconified(WindowEvent e) { } @Override public void windowActivated(WindowEvent e) { } @Override public void windowDeactivated(WindowEvent e) { } } /** * ReadThread which is able to be interrupted while reading a line. * * @author jakob_jarosch */ class ReadThread extends Thread { private BufferedReader reader; private String line; public ReadThread(BufferedReader reader) { this.reader = reader; } @Override public void run() { line = null; try { line = reader.readLine(); } catch (IOException e) { line = null; } } public String getLine() { return line; } }