1 package net.suberic.pooka; 2 3 import javax.activation.*; 4 import java.io.*; 5 import java.util.StringTokenizer ; 6 7 11 public class ExternalLauncher implements CommandObject, Runnable { 12 13 private String verb; 14 private DataHandler dh; 15 16 private net.suberic.util.swing.ProgressDialog mDialog; 18 19 private File mTmpFile = null; 20 21 public ExternalLauncher() { 22 }; 23 24 32 public void setCommandContext(java.lang.String newVerb, 33 DataHandler newDh) 34 throws java.io.IOException { 35 verb = newVerb; 36 dh = newDh; 37 } 38 39 43 public void setProgressDialog(net.suberic.util.swing.ProgressDialog pDialog) { 44 mDialog = pDialog; 45 } 46 47 51 public net.suberic.util.swing.ProgressDialog getProgressDialog() { 52 return mDialog; 53 } 54 55 60 public void show() { 61 Thread t = new Thread (this, "External Viewer"); 62 t.start(); 63 } 64 65 71 public void run() { 72 try { 73 String extension = ".tmp"; 74 String filename = dh.getName(); 75 if (filename == null) 76 filename = "unavailable"; 77 int dotLoc = filename.lastIndexOf('.'); 78 if (dotLoc > 0) { 79 extension = filename.substring(dotLoc); 80 } 81 mTmpFile = File.createTempFile("pooka_", extension); 82 83 boolean cancelled = false; 84 85 if (mDialog == null) { 86 FileOutputStream fos = new FileOutputStream(mTmpFile); 87 dh.writeTo(fos); 88 fos.close(); 89 } else { 90 mDialog.show(); 91 InputStream decodedIS = dh.getInputStream(); 92 BufferedOutputStream outStream = new BufferedOutputStream(new FileOutputStream(mTmpFile)); 93 int b=0; 94 byte[] buf = new byte[32768]; 95 96 b = decodedIS.read(buf); 97 while (b != -1 && ! cancelled) { 98 outStream.write(buf, 0, b); 99 mDialog.setValue(mDialog.getValue() + b); 100 if (mDialog.isCancelled()) 101 cancelled = true; 102 103 b = decodedIS.read(buf); 104 } 105 106 outStream.close(); 107 } 108 109 if (! cancelled) { 110 if (mDialog != null) 111 mDialog.dispose(); 112 113 String fileHandler = Pooka.getProperty("ExternalLauncher.fileHandler." + java.io.File.separator, null); 114 String wrapper = Pooka.getProperty("ExternalLauncher.cmdWrapper." + java.io.File.separator, null); 115 String fileName = mTmpFile.getAbsolutePath(); 116 117 String parsedVerb; 118 String [] cmdArray; 119 120 String origParsedCommand = substituteString(verb, "%s", fileName); 121 122 if (fileHandler != null && wrapper != null) { 123 124 parsedVerb = substituteString(fileHandler, "%v", verb); 125 parsedVerb = substituteString(parsedVerb, "%s", fileName); 126 127 StringTokenizer tok = new StringTokenizer (wrapper); 128 cmdArray = new String [tok.countTokens()]; 129 for (int i = 0; tok.hasMoreTokens(); i++) { 130 String currentString = tok.nextToken(); 131 if (currentString.equals("%v")) 132 cmdArray[i] = parsedVerb; 133 else 134 cmdArray[i]=currentString; 135 } 136 } else { 137 parsedVerb = substituteString(verb, "%s", fileName); 138 139 cmdArray = parseCommandString(parsedVerb); 140 141 mTmpFile.deleteOnExit(); 142 } 143 144 try { 145 if (Pooka.isDebug()) { 146 System.out.println("running external command " + parsedVerb); 147 } 148 149 Process p = Runtime.getRuntime().exec(cmdArray); 150 151 long startTime = System.currentTimeMillis(); 152 153 try { 154 p.waitFor(); 155 } catch (InterruptedException ie) { 156 } 157 158 int exitValue = p.exitValue(); 159 160 if (Pooka.isDebug()) { 161 System.out.println("finished external command " + parsedVerb); 162 } 163 164 if (exitValue != 0) { 165 long externalTimeoutMillis = 5000; 166 try { 167 externalTimeoutMillis = Long.parseLong(Pooka.getProperty("ExternalLauncher.externalTimeoutMillis", "5000")); 168 } catch (NumberFormatException nfe) { 169 } 171 if (System.currentTimeMillis() - startTime < externalTimeoutMillis) { 172 if (Pooka.isDebug()) 173 System.out.println("external command " + parsedVerb + ": exitValue is " + exitValue + " and timeout < externalTimeoutMillis; showing error."); 174 175 showError(origParsedCommand, p); 176 } 177 } 178 } catch (java.io.IOException processIoe) { 179 Pooka.getUIFactory().showError("Error running process " + processIoe.getMessage()); 180 processIoe.printStackTrace(); 181 } 182 } } catch (java.io.IOException ioe) { 184 Pooka.getUIFactory().showError("Error opening temp file " + ioe.getMessage()); 185 ioe.printStackTrace(); 186 } 187 } 188 189 192 public void showError(String command, Process p) { 193 194 try { 196 StringWriter errorWriter = new StringWriter(); 197 BufferedWriter bw = new BufferedWriter(errorWriter); 198 bw.write(Pooka.getProperty("ExternalLauncher.error.failedToRun", "Failed executing command:")); 199 bw.newLine(); 200 bw.write(command); 201 bw.newLine(); 202 bw.newLine(); 203 bw.write(Pooka.getProperty("ExternalLauncher.error.output", "Output:")); 204 bw.newLine(); 205 206 try { 207 InputStream errorStream = p.getErrorStream(); 208 BufferedReader br = new BufferedReader(new InputStreamReader(errorStream)); 209 for (String nextLine = br.readLine(); nextLine != null; nextLine = br.readLine()) { 210 bw.write(nextLine); 211 bw.newLine(); 212 } 213 } catch (IOException ioe) { 214 bw.write("Error not available"); 215 bw.newLine(); 216 } 217 bw.flush(); 218 bw.close(); 219 220 String errorMessage = errorWriter.toString(); 221 Pooka.getUIFactory().showError(errorMessage); 222 } catch (IOException ioe) { 223 Pooka.getUIFactory().showError(Pooka.getProperty("ExternalLauncher.error.failedToRun", "Failed executing command:")); 225 } 226 } 227 228 232 public static String substituteString(String original, String key, String value) { 233 236 StringBuffer modifiedString = new StringBuffer (original); 237 int current = original.lastIndexOf(key, original.length()); 238 while (current != -1) { 239 modifiedString.replace(current, current + key.length(), value); 240 current = original.substring(0, current).lastIndexOf(key, current); 241 } 242 243 return modifiedString.toString(); 244 } 245 246 249 public String [] parseCommandString(String cmdString) { 250 StringTokenizer tok = new StringTokenizer (cmdString); 251 String [] cmdArray = new String [tok.countTokens()]; 252 for (int i = 0; tok.hasMoreTokens(); i++) { 253 String currentString = tok.nextToken(); 254 cmdArray[i]=currentString; 255 } 256 257 return cmdArray; 258 } 259 260 public void cancelSave() { 261 try { 262 mTmpFile.delete(); 263 } catch (Exception e) {} 264 if (mDialog != null) 265 mDialog.dispose(); 266 } 267 268 } 269 | Popular Tags |