|
1 /* |
|
2 * Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: This class is used for converting media files |
|
15 * |
|
16 */ |
|
17 |
|
18 package com.nokia.tools.themeinstaller.mediaconverter; |
|
19 |
|
20 import java.io.BufferedReader; |
|
21 import java.io.File; |
|
22 import java.io.IOException; |
|
23 import java.io.InputStream; |
|
24 import java.io.InputStreamReader; |
|
25 import java.net.URL; |
|
26 import java.util.ArrayList; |
|
27 import java.util.Iterator; |
|
28 import java.util.List; |
|
29 |
|
30 import javax.imageio.IIOImage; |
|
31 import javax.imageio.ImageIO; |
|
32 import javax.imageio.ImageReader; |
|
33 import javax.imageio.ImageWriter; |
|
34 import javax.imageio.stream.ImageInputStream; |
|
35 import javax.imageio.stream.ImageOutputStream; |
|
36 |
|
37 import com.nokia.tools.themeinstaller.odtconverter.ConverterProperties; |
|
38 |
|
39 /** |
|
40 * Base class for different MediaConverters |
|
41 * Media converters are used for e.g. converting jpg to mbm |
|
42 * @author jutarhon |
|
43 * |
|
44 */ |
|
45 public class MediaConverter |
|
46 { |
|
47 protected static final String MEDIA_CONVERTER_APPLICATION= "media_converter"; |
|
48 private static final String WINDOWS_EXCUTABLE_EXTENSION = "exe"; |
|
49 private static final String LINUX_OS_NAME = "linux"; |
|
50 private static final String OPERATING_SYSTEM_PROPERTY = "os.name"; |
|
51 protected static final char SPACE = ' '; |
|
52 protected static final char DOT = '.'; |
|
53 private static final String BMP = "bmp"; |
|
54 private static final String COLOR_SETTING = "color_setting"; |
|
55 protected static String DEFAULT_SUCCESS_LINE = "Success."; |
|
56 |
|
57 protected ConverterProperties iProperties; |
|
58 private Process iProcess; |
|
59 |
|
60 protected String iExtraParameters = null; |
|
61 |
|
62 /** |
|
63 * Default constructor. |
|
64 * @throws IOException If loading properties fails |
|
65 */ |
|
66 public MediaConverter() throws IOException |
|
67 { |
|
68 iProperties = new ConverterProperties(); |
|
69 } |
|
70 |
|
71 /** |
|
72 * Returns possible set extra parameters for running converter application |
|
73 * or null if not set |
|
74 * @return the iExtraParameters |
|
75 */ |
|
76 public String getExtraParameters() |
|
77 { |
|
78 return iExtraParameters; |
|
79 } |
|
80 |
|
81 /** |
|
82 * Sets extra parameters for running converter application |
|
83 * Set null for unsetting |
|
84 * @param aExtraParameters Extra parameters to set |
|
85 */ |
|
86 public void setExtraParameters( String aExtraParameters ) |
|
87 { |
|
88 iExtraParameters = aExtraParameters; |
|
89 } |
|
90 |
|
91 /** |
|
92 * Returns command line parameters for specified filenames |
|
93 * including the actual executable |
|
94 * example: bmconv.exe target.mbm source.jpg |
|
95 * @param aFilenames List of filenames to added to command line |
|
96 * @param aTargetFile Filename for target bitmap |
|
97 * @return Executable parameters |
|
98 */ |
|
99 protected String getExecParameters( List aFilenames, String aTargetFile ) |
|
100 { |
|
101 StringBuffer sb = new StringBuffer(); |
|
102 |
|
103 // Get the execution location |
|
104 URL resource = |
|
105 getClass().getProtectionDomain().getCodeSource().getLocation(); |
|
106 File bin = new File( resource.getPath() ); |
|
107 |
|
108 // Find the bmconv from the installation directory |
|
109 sb.append( bin.getParent() + File.separatorChar ); |
|
110 |
|
111 // Windows uses bmconv.exe and Linux bmconv |
|
112 if ( System.getProperty( OPERATING_SYSTEM_PROPERTY ).equalsIgnoreCase( |
|
113 LINUX_OS_NAME ) ) |
|
114 { |
|
115 sb.append( iProperties.getProperty( MEDIA_CONVERTER_APPLICATION ) ); |
|
116 } |
|
117 else |
|
118 { |
|
119 sb.append( iProperties.getProperty( MEDIA_CONVERTER_APPLICATION ) |
|
120 + DOT + WINDOWS_EXCUTABLE_EXTENSION ); |
|
121 } |
|
122 |
|
123 sb.append( SPACE ); |
|
124 if( iExtraParameters != null ) |
|
125 { |
|
126 sb.append( iExtraParameters ); |
|
127 sb.append( SPACE ); |
|
128 } |
|
129 sb.append( aTargetFile ); |
|
130 sb.append( SPACE ); |
|
131 for ( Iterator iterator = aFilenames.iterator(); iterator.hasNext(); ) |
|
132 { |
|
133 sb.append( iProperties.getProperty( COLOR_SETTING ) ); |
|
134 sb.append( iterator.next() ); |
|
135 if( iterator.hasNext() ) |
|
136 { |
|
137 sb.append( SPACE ); |
|
138 } |
|
139 } |
|
140 return sb.toString(); |
|
141 } |
|
142 /** |
|
143 * Getter for environment variables in form "key=value" |
|
144 * To be overwritten in derived class if environment variables are needed |
|
145 * @return String array of "key=value" pairs. |
|
146 */ |
|
147 protected String[] getEnvironmentVariables() |
|
148 { |
|
149 return null; |
|
150 } |
|
151 |
|
152 /** |
|
153 * Returns success line that is excepted in output |
|
154 * @return Success line |
|
155 */ |
|
156 protected String getSuccesIndicationLine() |
|
157 { |
|
158 return DEFAULT_SUCCESS_LINE; |
|
159 } |
|
160 |
|
161 /** |
|
162 * Cancels the executing conversion operation |
|
163 */ |
|
164 public void cancelConversion() |
|
165 { |
|
166 if( iProcess != null ) |
|
167 { |
|
168 iProcess.destroy(); |
|
169 } |
|
170 } |
|
171 |
|
172 /** |
|
173 * Converts one ore more files to target file |
|
174 * @param aFilenames Files to be converted |
|
175 * @param aTargetFile Target file |
|
176 * @throws IOException If IO error occurs or tool fails conversion |
|
177 */ |
|
178 public void convertMedia( List aFilenames, |
|
179 String aTargetFile ) throws IOException |
|
180 { |
|
181 ArrayList newFiles = new ArrayList(); |
|
182 |
|
183 checkMedias( aFilenames, newFiles ); |
|
184 Runtime rt = Runtime.getRuntime(); |
|
185 iProcess = rt.exec( getExecParameters( aFilenames, aTargetFile ), |
|
186 getEnvironmentVariables() ); |
|
187 try |
|
188 { |
|
189 iProcess.waitFor(); |
|
190 } |
|
191 catch ( InterruptedException e ) |
|
192 { |
|
193 throw new IOException( "Conversion interrupted" ); |
|
194 } |
|
195 |
|
196 if( iProcess.exitValue() != 0 ) |
|
197 { |
|
198 InputStream input = null; |
|
199 BufferedReader in = null; |
|
200 StringBuffer sb = null; |
|
201 try |
|
202 { |
|
203 // reading the error logs |
|
204 input = iProcess.getErrorStream(); |
|
205 in = new BufferedReader( new InputStreamReader( input ) ); |
|
206 sb = new StringBuffer(); |
|
207 String line = null; |
|
208 while ( ( line = in.readLine() ) != null ) |
|
209 { |
|
210 sb.append( line ); |
|
211 sb.append( '\n' ); |
|
212 } |
|
213 } |
|
214 finally |
|
215 { |
|
216 if( input != null ) |
|
217 { |
|
218 input.close(); |
|
219 } |
|
220 if( in != null ) |
|
221 { |
|
222 in.close(); |
|
223 } |
|
224 } |
|
225 |
|
226 deleteTemporaryFiles( newFiles ); |
|
227 throw new IOException( "Conversion failed with error code: " + |
|
228 iProcess.exitValue() + |
|
229 "\nError log: " + sb.toString() ); |
|
230 } |
|
231 // read the output logs, and check that there is success indication (in case that tool does not |
|
232 // support sending error code) |
|
233 boolean success = false; |
|
234 String line = null; |
|
235 String lastLine = null; |
|
236 InputStream input = null; |
|
237 BufferedReader in = null; |
|
238 try |
|
239 { |
|
240 input = iProcess.getInputStream(); |
|
241 in = new BufferedReader( new InputStreamReader( input ) ); |
|
242 while ( ( line = in.readLine() ) != null ) |
|
243 { |
|
244 if( line.equals( getSuccesIndicationLine() ) ) |
|
245 { |
|
246 success = true; |
|
247 break; |
|
248 } |
|
249 lastLine = line; |
|
250 } |
|
251 } |
|
252 finally |
|
253 { |
|
254 if( input != null ) |
|
255 { |
|
256 input.close(); |
|
257 } |
|
258 if( in != null ) |
|
259 { |
|
260 in.close(); |
|
261 } |
|
262 } |
|
263 iProcess = null; |
|
264 // Delete temporary files |
|
265 deleteTemporaryFiles( newFiles ); |
|
266 // did not found success line |
|
267 if( !success ) |
|
268 { |
|
269 throw new IOException( "Running media converter failed: " + lastLine ); |
|
270 } |
|
271 } |
|
272 |
|
273 /** |
|
274 * Delete temporary files |
|
275 * @param newFiles List of temporary files |
|
276 * @throws IOException If file deletion fails |
|
277 */ |
|
278 protected void deleteTemporaryFiles( List aNewFiles ) throws IOException |
|
279 { |
|
280 for ( Iterator iterator = aNewFiles.iterator(); iterator.hasNext(); ) |
|
281 { |
|
282 String filename = ( String ) iterator.next(); |
|
283 File file = new File( filename ); |
|
284 if( !file.delete() ) |
|
285 { |
|
286 throw new IOException( "Temporary file deletion failed: " + filename ); |
|
287 } |
|
288 } |
|
289 } |
|
290 |
|
291 /** |
|
292 * Checks that input medias does not contain illegal files and converts |
|
293 * other image formats to BMP |
|
294 * @param aFilenames List of files to be added in MBM file |
|
295 * @param aNewFiles List of created temporary files |
|
296 * @throws IOException thrown if some of encoders are missing, or some error in image reading/writing |
|
297 */ |
|
298 protected void checkMedias( List aFilenames, |
|
299 List aNewFiles ) throws IOException |
|
300 { |
|
301 // load BMP writer |
|
302 Iterator writers = ImageIO.getImageWritersByFormatName( BMP ); |
|
303 if( !writers.hasNext() ) |
|
304 { |
|
305 throw new IOException( "BMP encoder not found" ); |
|
306 } |
|
307 ImageWriter bmpWriter = ( ImageWriter ) writers.next(); |
|
308 |
|
309 ArrayList newNames = new ArrayList(); |
|
310 // Go through all files and check if there is something else than BMP |
|
311 for ( Iterator iterator = aFilenames.iterator(); |
|
312 iterator.hasNext(); ) |
|
313 { |
|
314 String imageName = ( String ) iterator.next(); |
|
315 ImageInputStream input = ImageIO.createImageInputStream( |
|
316 new File( imageName ) ); |
|
317 |
|
318 String destinationImage = null; |
|
319 try |
|
320 { |
|
321 Iterator readers = ImageIO.getImageReaders( input ); |
|
322 if( !readers.hasNext() ) |
|
323 { |
|
324 throw new IOException( "Unknown file" ); |
|
325 } |
|
326 ImageReader ir = ( ImageReader ) readers.next(); |
|
327 //Convert file if it is not BMP |
|
328 destinationImage = imageName; |
|
329 if( !ir.getFormatName().equalsIgnoreCase( BMP ) ) |
|
330 { |
|
331 // read original image |
|
332 ir.setInput( input ); |
|
333 IIOImage image = ir.readAll( 0, null ); |
|
334 destinationImage = imageName.substring( |
|
335 0, imageName.lastIndexOf( DOT ) + 1 ) + BMP; |
|
336 File destFile = new File( destinationImage ); |
|
337 int index = 1; |
|
338 // create unique name to not overwrite any existing files |
|
339 while( destFile.exists() ) |
|
340 { |
|
341 destinationImage = imageName.substring( 0, |
|
342 imageName.lastIndexOf( DOT ) ) |
|
343 + index++ + DOT + BMP; |
|
344 destFile = new File( destinationImage ); |
|
345 } |
|
346 // Write image back in BMP format |
|
347 ImageOutputStream output = |
|
348 ImageIO.createImageOutputStream( destFile ); |
|
349 try |
|
350 { |
|
351 bmpWriter.setOutput( output ); |
|
352 bmpWriter.write( image ); |
|
353 } |
|
354 finally |
|
355 { |
|
356 if( output != null ) |
|
357 { |
|
358 output.close(); |
|
359 } |
|
360 } |
|
361 aNewFiles.add( destinationImage ); |
|
362 } |
|
363 } |
|
364 finally |
|
365 { |
|
366 if( input != null ) |
|
367 { |
|
368 input.close(); |
|
369 } |
|
370 } |
|
371 |
|
372 newNames.add( destinationImage ); |
|
373 } |
|
374 // change new names to list |
|
375 aFilenames.clear(); |
|
376 aFilenames.addAll( newNames ); |
|
377 } |
|
378 } |