| 6 | 1 /** | 
|  | 2  * | 
|  | 3  * Copyright INRA-URGI 2009-2010 | 
|  | 4  * | 
|  | 5  * This software is governed by the CeCILL license under French law and | 
|  | 6  * abiding by the rules of distribution of free software. You can use, | 
|  | 7  * modify and/ or redistribute the software under the terms of the CeCILL | 
|  | 8  * license as circulated by CEA, CNRS and INRIA at the following URL | 
|  | 9  * "http://www.cecill.info". | 
|  | 10  * | 
|  | 11  * As a counterpart to the access to the source code and rights to copy, | 
|  | 12  * modify and redistribute granted by the license, users are provided only | 
|  | 13  * with a limited warranty and the software's author, the holder of the | 
|  | 14  * economic rights, and the successive licensors have only limited | 
|  | 15  * liability. | 
|  | 16  * | 
|  | 17  * In this respect, the user's attention is drawn to the risks associated | 
|  | 18  * with loading, using, modifying and/or developing or reproducing the | 
|  | 19  * software by the user in light of its specific status of free software, | 
|  | 20  * that may mean that it is complicated to manipulate, and that also | 
|  | 21  * therefore means that it is reserved for developers and experienced | 
|  | 22  * professionals having in-depth computer knowledge. Users are therefore | 
|  | 23  * encouraged to load and test the software's suitability as regards their | 
|  | 24  * requirements in conditions enabling the security of their systems and/or | 
|  | 25  * data to be ensured and, more generally, to use and operate it in the | 
|  | 26  * same conditions as regards security. | 
|  | 27  * | 
|  | 28  * The fact that you are presently reading this means that you have had | 
|  | 29  * knowledge of the CeCILL license and that you accept its terms. | 
|  | 30  * | 
|  | 31  */ | 
|  | 32 import java.util.*; | 
|  | 33 import java.io.*; | 
|  | 34 import javax.swing.SwingUtilities; | 
|  | 35 import javax.swing.*; | 
|  | 36 import java.util.concurrent.CountDownLatch; | 
|  | 37 | 
|  | 38 public class ProgramLauncher extends SwingWorker<Boolean, String>  { | 
|  | 39 | 
|  | 40   String[]     command; | 
|  | 41   JTextArea    logArea; | 
|  | 42   JLabel       messageField; | 
|  | 43   JProgressBar progressBar; | 
|  | 44   JLabel       etaField; | 
|  | 45   int          exitValue; | 
|  | 46 | 
|  | 47 | 
|  | 48   public ProgramLauncher (LinkedList <String> c, JTextArea la, JLabel mf, JProgressBar pb, JLabel ef) { | 
|  | 49     command       = new String[c.size()]; | 
|  | 50     logArea       = la; | 
|  | 51     messageField  = mf; | 
|  | 52     progressBar   = pb; | 
|  | 53     etaField      = ef; | 
|  | 54     exitValue     = -1; | 
|  | 55     c.toArray(command); | 
|  | 56   } | 
|  | 57 | 
|  | 58 | 
|  | 59   public ProgramLauncher (String[] c, JTextArea la, JLabel mf, JProgressBar pb, JLabel ef) { | 
|  | 60     command       = c; | 
|  | 61     logArea       = la; | 
|  | 62     messageField  = mf; | 
|  | 63     progressBar   = pb; | 
|  | 64     etaField      = ef; | 
|  | 65     exitValue     = -1; | 
|  | 66   } | 
|  | 67 | 
|  | 68 | 
|  | 69   @Override | 
|  | 70   public Boolean doInBackground() { | 
|  | 71     ProcessBuilder pb           = new ProcessBuilder(command); | 
|  | 72     Process process             = null; | 
|  | 73     BufferedReader outputReader = null; | 
|  | 74     pb                          = pb.redirectErrorStream(true); | 
|  | 75     Map<String, String> env     = pb.environment(); | 
|  | 76     env.put("PYTHONPATH", System.getProperty("user.dir") + java.io.File.separator + "Python"); | 
|  | 77     env.put("SMARTPATH", System.getProperty("user.dir") + java.io.File.separator + "Python"); | 
|  | 78     env.put("SMARTMYSQLPATH", Global.mysqlCommand); | 
|  | 79     env.put("SMARTRPATH", Global.rCommand); | 
|  | 80     String commandJoined = Arrays.toString(command); | 
|  | 81 | 
|  | 82     try { | 
|  | 83       publish("=== Starting command '" + commandJoined.trim() + "' ===\n"); | 
|  | 84       process = pb.start(); | 
|  | 85 | 
|  | 86       BufferedInputStream outputStream = new BufferedInputStream(process.getInputStream()); | 
|  | 87       InputStream is                   = process.getInputStream(); | 
|  | 88       InputStreamReader isr            = new InputStreamReader(is); | 
|  | 89       outputReader                     = new BufferedReader(isr); | 
|  | 90     } | 
|  | 91     catch (Exception exception) { | 
|  | 92       publish("!Process cannot be started (command is '" + commandJoined + "')!\n"); | 
|  | 93       exception.printStackTrace(); | 
|  | 94       return Boolean.FALSE; | 
|  | 95     } | 
|  | 96     if (outputReader == null) { | 
|  | 97       publish("!Problem in the output of the command!\n"); | 
|  | 98       return Boolean.FALSE; | 
|  | 99     } | 
|  | 100     else { | 
|  | 101       try { | 
|  | 102         String line; | 
|  | 103         while ((line = outputReader.readLine()) != null) { | 
|  | 104           publish(line + "\n"); | 
|  | 105         } | 
|  | 106       } | 
|  | 107       catch (IOException e) { | 
|  | 108         e.printStackTrace(); | 
|  | 109         publish("!Cannot get the output of the command!\n"); | 
|  | 110         return Boolean.FALSE; | 
|  | 111       } | 
|  | 112     } | 
|  | 113     try { | 
|  | 114       process.waitFor(); | 
|  | 115     } | 
|  | 116     catch (InterruptedException e) { | 
|  | 117       e.printStackTrace(); | 
|  | 118       publish("!Cannot wait for the end of the command!\n"); | 
|  | 119       return Boolean.FALSE; | 
|  | 120     } | 
|  | 121     try { | 
|  | 122       exitValue = process.exitValue(); | 
|  | 123       System.out.println(exitValue); | 
|  | 124     } | 
|  | 125     catch (IllegalThreadStateException e) { | 
|  | 126       e.printStackTrace(); | 
|  | 127       publish("!Cannot get the exit value of the command!\n"); | 
|  | 128       return Boolean.FALSE; | 
|  | 129     } | 
|  | 130     if (exitValue != 0) { | 
|  | 131       publish("!Problem during the execution of the command '" + commandJoined + "'!\n"); | 
|  | 132       return Boolean.FALSE; | 
|  | 133     } | 
|  | 134     publish("=== Ending command '" + commandJoined.trim() + "' ===\n"); | 
|  | 135     return Boolean.TRUE; | 
|  | 136   } | 
|  | 137 | 
|  | 138 | 
|  | 139   @Override | 
|  | 140   protected void process(List<String> chunks) { | 
|  | 141     String message = ""; | 
|  | 142     String text    = logArea.getText(); | 
|  | 143     for (String chunk: chunks) { | 
|  | 144       text += chunk; | 
|  | 145     } | 
|  | 146     for (String lineSeparatedByCarriageReturn: text.split("\n")) { | 
|  | 147       for (String line: lineSeparatedByCarriageReturn.split("\r")) { | 
|  | 148         boolean progressLine = false; | 
|  | 149         if (line.matches(".*\\[=*\\s*\\]\\s*\\d*/\\d*\\s*")) { | 
|  | 150           String[] ratioElements = line.split("\\]")[1].trim().split("/"); | 
|  | 151           int      current       = Integer.parseInt(ratioElements[0].trim()); | 
|  | 152           int      aim           = Integer.parseInt(ratioElements[1].trim()); | 
|  | 153           messageField.setText(line.split("\\[")[0].trim()); | 
|  | 154           progressBar.setValue(current * 100 / aim); | 
|  | 155           etaField.setText(""); | 
|  | 156           progressLine = true; | 
|  | 157         } | 
|  | 158         else if (line.matches(".*\\[=*\\s*\\]\\s*\\d*/\\d*\\s*ETA:\\s*.*")) { | 
|  | 159           String[] ratioElements = line.split("\\]")[1].split("E")[0].trim().split("/"); | 
|  | 160           int      current       = Integer.parseInt(ratioElements[0].trim()); | 
|  | 161           int      aim           = Integer.parseInt(ratioElements[1].trim()); | 
|  | 162           String   eta           = line.split("ETA:")[1].trim(); | 
|  | 163           messageField.setText(line.split("\\[")[0].trim()); | 
|  | 164           progressBar.setValue(current * 100 / aim); | 
|  | 165           etaField.setText("ETA: " + eta); | 
|  | 166           progressLine = true; | 
|  | 167         } | 
|  | 168         else if (line.matches(".*\\[=*\\s*\\]\\s*\\d*\\s*completed in.*")) { | 
|  | 169           String nbElements = line.split("\\]")[1].split("completed")[0].trim(); | 
|  | 170           String timeSpent  = line.split("completed in")[1].trim(); | 
|  | 171           message          += line.split("\\[")[0].trim() + ": " + nbElements + " elements completed in " + timeSpent + "\n"; | 
|  | 172           messageField.setText(line.split("\\[")[0].trim()); | 
|  | 173           progressLine = true; | 
|  | 174         } | 
|  | 175         if (! progressLine) { | 
|  | 176           message += line + "\n"; | 
|  | 177         } | 
|  | 178       } | 
|  | 179     } | 
|  | 180     String lines[]     = message.split("\n"); | 
|  | 181     String toBeWritten = ""; | 
|  | 182     for (int i = Math.max(0, lines.length - Global.logAreaSize); i < lines.length; i++) { | 
|  | 183       toBeWritten += lines[i] + "\n"; | 
|  | 184     } | 
|  | 185     logArea.setText(toBeWritten); | 
|  | 186   } | 
|  | 187 | 
|  | 188   public int getExitValue() { | 
|  | 189     return exitValue; | 
|  | 190   } | 
|  | 191 } |