Source code: com/flexstor/flexdbserver/services/io/Convert.java
1 /*
2 * Convert.java
3 *
4 * Copyright $Date: 2003/08/11 02:22:40 $ FLEXSTOR.net Inc.
5 *
6 * This work is licensed for use and distribution under license terms found at
7 * http://www.flexstor.org/license.html
8 *
9 */
10
11 package com.flexstor.flexdbserver.services.io;
12
13 import java.io.BufferedReader;
14 import java.io.IOException;
15 import java.io.InputStreamReader;
16 import java.util.StringTokenizer;
17
18 import com.flexstor.common.errorlogger.FlexError;
19 import com.flexstor.common.resources.Resources;
20
21 /**
22 *
23 *
24 */
25 public class Convert implements IIntervalTimer
26 {
27 // To get the version number from MKS
28 public final static String IDENTIFIER="$Id: Convert.java,v 1.3 2003/08/11 02:22:40 aleric Exp $";
29
30 // public static String sVersion = " Convert - 05/01/98(1)";
31
32 protected IntervalTimer refWatchdogTimer = null;
33 protected Process pr = null;
34 protected String sInputCommand = "";
35
36 protected String sFileSize = " ";
37 protected String sFormat = " ";
38 protected String sDPIX = " ";
39 protected String sDPIY = " ";
40 protected String sWidth = " ";
41 protected String sHeight = " ";
42 protected String sBitsPerPixel = " ";
43 protected String sColorMode = " ";
44
45 public Convert() {}
46
47 /**
48 * Obtain information about the file through the conversion software
49 * @param saCommandLine a String[] to be passed to the Runtime.exec(String[]) method.
50 * The first element is the array is the command and the rest are arguments to
51 * that command.
52 * @param nPlatform: 0 = DOS, 1 = Unix
53 * @param sTimeoutInterval How long this command will be allowed to run before the
54 * watchdog timer stop it
55 * @return true if sucessful, false otherwise
56 */
57 public boolean getImageInfo(String[] saCommandLine,
58 int nPlatform,
59 String sTimeOutInterval)
60 {
61 return executeConversion(saCommandLine, nPlatform, sTimeOutInterval);
62 } // getImageInfo
63
64 /**
65 * Do the actual image conversion creating the thumbnail.
66 * @param saCommandLine a String[] to be passed to the Runtime.exec(String[]) method.
67 * The first element is the array is the command and the rest are arguments to
68 * that command.
69 * @param nPlatform: 0 = DOS, 1 = Unix
70 * @param sTimeoutInterval How long this command will be allowed to run before the
71 * watchdog timer stop it
72 * @return true if sucessful, false otherwise
73 */
74 public boolean executeConversion(String[] saCommandLine,
75 int nPlatform,
76 String sTimeOutInterval)
77 {
78
79 sInputCommand = toString(saCommandLine);
80
81 // Create the watchdog timer in a separate thread
82 // Get the timer interval
83 // Default value is 360 seconds
84 int nInterval = 360;
85 if ((sTimeOutInterval != null) && (sTimeOutInterval.equals("") == false))
86 {
87 nInterval = Integer.parseInt(sTimeOutInterval);
88 }
89
90 refWatchdogTimer = new IntervalTimer(this, nInterval);
91
92 if (nPlatform == 1)
93 {
94 // unix version
95 return unixExecute(saCommandLine);
96 }
97
98 else
99 {
100 // DOS version
101 return dosExecute(saCommandLine);
102 }
103 } // executeConversion
104
105 /**
106 * Execute the conversion software in unix
107 * @param saCommandLine a String[] to be passed to the Runtime.exec(String[]) method.
108 * The first element is the array is the command and the rest are arguments to
109 * that command.
110 * @return true if sucessful, false otherwise
111 */
112 protected boolean unixExecute( String[] saCommandLine )
113 {
114 boolean bSuccess = true;
115
116 // Start the watchdog timer. If it times out it will call the timedOut() method
117 // which will destroy the external process
118 if (refWatchdogTimer != null)
119 {
120 refWatchdogTimer.start();
121 }
122
123 System.out.println("*** ALCHEMY START ****");
124
125 try
126 {
127 // Create and run the external conversion process
128 pr = Runtime.getRuntime().exec(saCommandLine);
129
130 // Initially we check for null to make sure that we got a valid process from the
131 // Runtime.exec(...) command.
132 // Then, we need to wait for the process to complete. Alchemy may take a relative long time
133 // to process some type of files. Not waiting for the process completion will cause and error
134 // when trying to retrieve its outputed information.
135 // However, if the operation takes longer than the time set by the watchdog timer, the watchdog
136 // will destroy the process, causing it to throw a InterruptedException and awaking the waiting
137 // thread. At this point we should check if the process is null and return unsucessfully if that
138 // is the case.
139 if ( pr != null )
140 // Wait for process completion
141 try
142 {
143 pr.waitFor();
144 // Stop the WatchdogTimer as we don't needed anymore
145 refWatchdogTimer.stopTimer();
146 }
147 catch ( InterruptedException ie ) {}
148
149 if (pr == null)
150 {
151 //"Error executing translator program: " + sCommandLine
152 // 5517=Convert
153 // 5515=Failure calling Alchemy conversion utility.
154 // 5513=Command Failed: %%1
155 // 5512=Check to make sure the Alchemy utility is installed and accessible.
156 String msg = Resources.get( 5515 ) + "\r\n" +
157 Resources.get( 5513, toString(saCommandLine) ) + "\r\n" +
158 Resources.get( 5512 );
159 new FlexError(FlexError.CRITICAL, Resources.get(5517), IDENTIFIER, msg);
160 return false;
161 }
162
163 // Get the output from the process
164 bSuccess = getOutput( new BufferedReader( new InputStreamReader(pr.getInputStream()) ) );
165
166 if ( !bSuccess )
167 {
168 // 5517=Convert
169 // 5513=Command Failed: %%1
170 new FlexError(FlexError.WARNING, Resources.get(5517), IDENTIFIER, 5513, new String[] { toString(saCommandLine) } );
171 }
172 } // try
173 catch(IOException e)
174 { //"Error executing translator program on file: " + sCommandLine
175 // 5517=Convert
176 // 5513=Command Failed: %%1
177 new FlexError(FlexError.CRITICAL, Resources.get(5517), IDENTIFIER, e, 5513, new String[] { toString(saCommandLine) });
178 return false;
179 }
180 finally
181 {
182 if ( pr != null )
183 {
184 pr.destroy();
185 pr = null;
186 }
187 }
188 return bSuccess;
189 } // unixExecute
190
191 /**
192 * Execute the conversion software in windows
193 * @param saCommandLine a String[] to be passed to the Runtime.exec(String[]) method.
194 * The first element is the array is the command and the rest are arguments to
195 * that command.
196 * @return true if sucessful, false otherwise
197 */
198 protected boolean dosExecute( String[] saCommandLine )
199 {
200 boolean bSuccess = true;
201
202 // Start the watchdog timer. If it times out it will call the timedOut() method
203 // which will destroy the external process
204 if (refWatchdogTimer != null)
205 {
206 refWatchdogTimer.start();
207 }
208
209 try
210 {
211 // Execute the translator program
212 pr = Runtime.getRuntime().exec(saCommandLine);
213
214 // Initially we check for null to make sure that we got a valid process from the
215 // Runtime.exec(...) command.
216 // Then, we need to wait for the process to complete. Alchemy may take a relative long time
217 // to process some type of files. Not waiting for the process completion will cause and error
218 // when trying to retrieve its outputed information.
219 // However, if the operation takes longer than the time set by the watchdog timer, the watchdog
220 // will destroy the process, causing it to throw a InterruptedException and awaking the waiting
221 // thread. At this point we should check if the process is null and return unsucessfully if that
222 // is the case.
223 if ( pr != null )
224 // Wait for process completion
225 try
226 {
227 pr.waitFor();
228 // Stop the WatchdogTimer as we don't needed anymore
229 refWatchdogTimer.stopTimer();
230 }
231 catch ( InterruptedException ie ) {}
232
233 if (pr == null)
234 {
235 //"Error executing translator program: " + sCommandLine
236 // 5517=Convert
237 // 5515=Failure calling Alchemy conversion utility.
238 // 5513=Command Failed: %%1
239 // 5512=Check to make sure the Alchemy utility is installed and accessible.
240 String msg = Resources.get( 5515 ) + "\r\n" +
241 Resources.get( 5513, toString(saCommandLine) ) + "\r\n" +
242 Resources.get( 5512 );
243 new FlexError(FlexError.CRITICAL, Resources.get(5517), IDENTIFIER, msg);
244 return false;
245 }
246
247 bSuccess = getOutput( new BufferedReader( new InputStreamReader(pr.getInputStream()) ) );
248
249 if ( !bSuccess )
250 {
251 // 5517=Convert
252 // 5513=Command Failed: %%1
253 new FlexError(FlexError.WARNING, Resources.get(5517), IDENTIFIER, 5513, new String[] { toString(saCommandLine) } );
254 }
255 } // exec try
256 catch(IOException e)
257 {
258 //"Error executing translator program on file: " + sCommandLine
259 // 5517=Convert
260 // 5513=Command Failed: %%1
261 new FlexError(FlexError.CRITICAL, Resources.get(5517), IDENTIFIER, e, 5513, new String[] { toString(saCommandLine) });
262 return false;
263 }
264 finally
265 {
266 if ( pr != null )
267 {
268 pr.destroy();
269 pr = null;
270 }
271 }
272 return bSuccess;
273 } // dosExecute
274
275 /**
276 * Creates a String[] with the command line for this conversion software.
277 * @param sTranslator The conversion command line program
278 * @param sInFile The input to the conversion software
279 * @param sOutFile The output from the conversion software
280 * @param sOptions The options for the conversion software
281 * @return A String[] where the first element is the sTranslator and the rest
282 * are the arguments to the translator program
283 */
284 public static String[] createCommand( String sTranslator, String sInFile, String sOutFile, String sOptions )
285 {
286 StringTokenizer st = new StringTokenizer(sOptions, " " );
287 int nOtherArgs = sOutFile == null ? 2 : 3; // All options plus sTranslator, sInFile and sOutFile (if not null)
288 String[] saProcess = new String[ st.countTokens() + nOtherArgs ];
289
290 saProcess[0] = sTranslator.trim(); // For some reason this is comming with a blank space before the translator,
291 // this causes the command to fail, so we should trim() it.
292 saProcess[1] = "\"" + sInFile + "\"";
293
294 int i = 2;
295
296 if ( sOutFile != null )
297 saProcess[i++] = "\"" + sOutFile + "\"";
298
299 while ( st.hasMoreTokens() )
300 saProcess[i++] = st.nextToken();
301
302 return saProcess;
303 }
304
305 /**
306 * Converts the String[] command line into a String commandLine
307 */
308 public String toString( String[] args )
309 {
310 StringBuffer sb = new StringBuffer();
311 for ( int i = 0; i < args.length; i++ )
312 {
313 sb.append( args[i] );
314 sb.append( " " );
315 }
316
317 return sb.toString();
318 }
319
320 private boolean getOutput( BufferedReader buf)
321 throws IOException
322 {
323 String sItem = "";
324 String sValue = "";
325 StringTokenizer st;
326 // Read the stream
327 try
328 {
329 String s = buf.readLine();
330 if ( buf == null || s == null )
331 return false;
332
333 System.out.println("Getting output from Alchemy");
334 while (s != null)
335 {
336 if (s.equals("") == false)
337 {
338 // Get some attributes
339 s = s.trim();
340 s = s.toUpperCase();
341
342 st = new StringTokenizer(s, ":");
343 if ( st.countTokens() == 2 )
344 {
345 sItem = st.nextToken();
346 sValue = st.nextToken();
347
348 if (sItem.equals("TYPE")) { sFormat = sValue.trim(); }
349 else if (sItem.equals("FILESIZE")) { sFileSize = sValue.trim(); }
350 else if((sItem.equals("DPIX")) ||
351 (sItem.equals("DPCX"))) { sDPIX = sValue.trim(); }
352 else if((sItem.equals("DPIY")) ||
353 (sItem.equals("DPCY"))) { sDPIY = sValue.trim(); }
354 else if(sItem.equals("WIDTH")) { sWidth = sValue.trim(); }
355 else if(sItem.equals("HEIGHT")) { sHeight = sValue.trim(); }
356 else if (sItem.equals("BITSPERPIXEL")) { sBitsPerPixel = sValue.trim(); }
357 else if (sItem.equals("MODE")) { sColorMode = sValue.trim(); }
358 }
359 } // s equals null if
360 s = buf.readLine();
361 } // while
362 return true;
363 } // readLine try
364 finally
365 {
366 buf.close();
367 }
368 }
369
370 public String getFormat() { return sFormat; }
371 public String getFileSize() { return sFileSize; }
372 public String getDPIX() { return sDPIX; }
373 public String getDPIY() { return sDPIY; }
374 public String getWidth() { return sWidth; }
375 public String getHeight() { return sHeight; }
376 public String getColorDepth() { return sBitsPerPixel; }
377 public String getColorMode() { return sColorMode; }
378
379 /**
380 * Called from IntervalTimer if it times out
381 *
382 */
383 public void timedOut()
384 {
385 if (pr != null)
386 {
387 // Terminate the external process since it is taking too long
388 pr.destroy();
389 pr = null;
390
391 // Create the error for log and email
392 System.out.println("Alchemy did not complete process in the time specified");
393 new FlexError(FlexError.CRITICAL, "Conversion process timed out on: ", IDENTIFIER, sInputCommand);
394 }
395 } // timedOut
396
397
398 } // Convert