KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > suberic > pooka > ExternalLauncher


1 package net.suberic.pooka;
2
3 import javax.activation.*;
4 import java.io.*;
5 import java.util.StringTokenizer JavaDoc;
6
7 /**
8  * This class is a generic class which will allow an external program
9  * to start up and access a file.
10  */

11 public class ExternalLauncher implements CommandObject, Runnable JavaDoc {
12
13   private String JavaDoc verb;
14   private DataHandler dh;
15
16   // for, err, showing progress in downloading the temporary file.
17
private net.suberic.util.swing.ProgressDialog mDialog;
18
19   private File mTmpFile = null;
20
21   public ExternalLauncher() {
22   };
23
24   /**
25    * This sets the CommandContext to the given command and DataHandler.
26    * Note that for this implementation, the verb is expected to bet the
27    * external command which is run, with %s representing the name of
28    * the temporary file.
29    *
30    * As specified in javax.activation.CommandObject.
31    */

32   public void setCommandContext(java.lang.String JavaDoc newVerb,
33                                 DataHandler newDh)
34     throws java.io.IOException JavaDoc {
35     verb = newVerb;
36     dh = newDh;
37   }
38
39   /**
40    * Sets a ProgressDialog for watching the downloading of the temporary
41    * file.
42    */

43   public void setProgressDialog(net.suberic.util.swing.ProgressDialog pDialog) {
44     mDialog = pDialog;
45   }
46
47   /**
48    * Gets the ProgressDialog for watching the downloading of the temporary
49    * file.
50    */

51   public net.suberic.util.swing.ProgressDialog getProgressDialog() {
52     return mDialog;
53   }
54
55   /**
56    * This starts the run() method in a separate Thread. It is implemented
57    * this way so as to present the same interface as a CommandObject which
58    * extends Window.
59    */

60   public void show() {
61     Thread JavaDoc t = new Thread JavaDoc(this, "External Viewer");
62     t.start();
63   }
64
65   /**
66    * This is the main method for the ExternalLaucher. It creates a
67    * temporary file from the DataHandler and then uses the verb command,
68    * along with the wrappers specified by ExternalLauncher.fileHandler
69    * and ExternalLauncher.cmdWrapper, to access the file itself.
70    */

71   public void run() {
72     try {
73       String JavaDoc extension = ".tmp";
74       String JavaDoc 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 JavaDoc fileHandler = Pooka.getProperty("ExternalLauncher.fileHandler." + java.io.File.separator, null);
114         String JavaDoc wrapper = Pooka.getProperty("ExternalLauncher.cmdWrapper." + java.io.File.separator, null);
115         String JavaDoc fileName = mTmpFile.getAbsolutePath();
116
117         String JavaDoc parsedVerb;
118         String JavaDoc[] cmdArray;
119
120         String JavaDoc 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 JavaDoc tok = new StringTokenizer JavaDoc(wrapper);
128           cmdArray = new String JavaDoc[tok.countTokens()];
129           for (int i = 0; tok.hasMoreTokens(); i++) {
130             String JavaDoc 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 JavaDoc p = Runtime.getRuntime().exec(cmdArray);
150
151           long startTime = System.currentTimeMillis();
152
153           try {
154             p.waitFor();
155           } catch (InterruptedException JavaDoc 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 JavaDoc nfe) {
169               // just use the default.
170
}
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 JavaDoc processIoe) {
179           Pooka.getUIFactory().showError("Error running process " + processIoe.getMessage());
180           processIoe.printStackTrace();
181         }
182       } // if ! cancelled
183
} catch (java.io.IOException JavaDoc ioe) {
184       Pooka.getUIFactory().showError("Error opening temp file " + ioe.getMessage());
185       ioe.printStackTrace();
186     }
187   }
188
189   /**
190    * Shows an error.
191    */

192   public void showError(String JavaDoc command, Process JavaDoc p) {
193
194     // build up the error message.
195
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 JavaDoc 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 JavaDoc errorMessage = errorWriter.toString();
221       Pooka.getUIFactory().showError(errorMessage);
222     } catch (IOException ioe) {
223       // shouldn't happen, but...
224
Pooka.getUIFactory().showError(Pooka.getProperty("ExternalLauncher.error.failedToRun", "Failed executing command:"));
225     }
226   }
227
228   /**
229    * This method subsitutes all occurances of key with value in String
230    * original.
231    */

232   public static String JavaDoc substituteString(String JavaDoc original, String JavaDoc key, String JavaDoc value) {
233     // you know, i'm already doing this for the replyIntro; maybe i
234
// should generalize these both a bit...
235

236     StringBuffer JavaDoc modifiedString = new StringBuffer JavaDoc(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   /**
247    * This parses a command string into a command array.
248    */

249   public String JavaDoc[] parseCommandString(String JavaDoc cmdString) {
250     StringTokenizer JavaDoc tok = new StringTokenizer JavaDoc(cmdString);
251     String JavaDoc[] cmdArray = new String JavaDoc[tok.countTokens()];
252     for (int i = 0; tok.hasMoreTokens(); i++) {
253       String JavaDoc 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 JavaDoc e) {}
264     if (mDialog != null)
265       mDialog.dispose();
266   }
267
268 }
269
Popular Tags