diff -r fe49e33862e2 -r 04b7640f6fb5 themeinstaller/source/src/com/nokia/tools/themeinstaller/mediaconverter/MediaConverter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/themeinstaller/source/src/com/nokia/tools/themeinstaller/mediaconverter/MediaConverter.java Wed Sep 01 12:32:13 2010 +0100 @@ -0,0 +1,378 @@ +/* +* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: This class is used for converting media files + * +*/ + +package com.nokia.tools.themeinstaller.mediaconverter; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import javax.imageio.IIOImage; +import javax.imageio.ImageIO; +import javax.imageio.ImageReader; +import javax.imageio.ImageWriter; +import javax.imageio.stream.ImageInputStream; +import javax.imageio.stream.ImageOutputStream; + +import com.nokia.tools.themeinstaller.odtconverter.ConverterProperties; + +/** + * Base class for different MediaConverters + * Media converters are used for e.g. converting jpg to mbm + * @author jutarhon + * + */ +public class MediaConverter + { + protected static final String MEDIA_CONVERTER_APPLICATION= "media_converter"; + private static final String WINDOWS_EXCUTABLE_EXTENSION = "exe"; + private static final String LINUX_OS_NAME = "linux"; + private static final String OPERATING_SYSTEM_PROPERTY = "os.name"; + protected static final char SPACE = ' '; + protected static final char DOT = '.'; + private static final String BMP = "bmp"; + private static final String COLOR_SETTING = "color_setting"; + protected static String DEFAULT_SUCCESS_LINE = "Success."; + + protected ConverterProperties iProperties; + private Process iProcess; + + protected String iExtraParameters = null; + + /** + * Default constructor. + * @throws IOException If loading properties fails + */ + public MediaConverter() throws IOException + { + iProperties = new ConverterProperties(); + } + + /** + * Returns possible set extra parameters for running converter application + * or null if not set + * @return the iExtraParameters + */ + public String getExtraParameters() + { + return iExtraParameters; + } + + /** + * Sets extra parameters for running converter application + * Set null for unsetting + * @param aExtraParameters Extra parameters to set + */ + public void setExtraParameters( String aExtraParameters ) + { + iExtraParameters = aExtraParameters; + } + + /** + * Returns command line parameters for specified filenames + * including the actual executable + * example: bmconv.exe target.mbm source.jpg + * @param aFilenames List of filenames to added to command line + * @param aTargetFile Filename for target bitmap + * @return Executable parameters + */ + protected String getExecParameters( List aFilenames, String aTargetFile ) + { + StringBuffer sb = new StringBuffer(); + + // Get the execution location + URL resource = + getClass().getProtectionDomain().getCodeSource().getLocation(); + File bin = new File( resource.getPath() ); + + // Find the bmconv from the installation directory + sb.append( bin.getParent() + File.separatorChar ); + + // Windows uses bmconv.exe and Linux bmconv + if ( System.getProperty( OPERATING_SYSTEM_PROPERTY ).equalsIgnoreCase( + LINUX_OS_NAME ) ) + { + sb.append( iProperties.getProperty( MEDIA_CONVERTER_APPLICATION ) ); + } + else + { + sb.append( iProperties.getProperty( MEDIA_CONVERTER_APPLICATION ) + + DOT + WINDOWS_EXCUTABLE_EXTENSION ); + } + + sb.append( SPACE ); + if( iExtraParameters != null ) + { + sb.append( iExtraParameters ); + sb.append( SPACE ); + } + sb.append( aTargetFile ); + sb.append( SPACE ); + for ( Iterator iterator = aFilenames.iterator(); iterator.hasNext(); ) + { + sb.append( iProperties.getProperty( COLOR_SETTING ) ); + sb.append( iterator.next() ); + if( iterator.hasNext() ) + { + sb.append( SPACE ); + } + } + return sb.toString(); + } + /** + * Getter for environment variables in form "key=value" + * To be overwritten in derived class if environment variables are needed + * @return String array of "key=value" pairs. + */ + protected String[] getEnvironmentVariables() + { + return null; + } + + /** + * Returns success line that is excepted in output + * @return Success line + */ + protected String getSuccesIndicationLine() + { + return DEFAULT_SUCCESS_LINE; + } + + /** + * Cancels the executing conversion operation + */ + public void cancelConversion() + { + if( iProcess != null ) + { + iProcess.destroy(); + } + } + + /** + * Converts one ore more files to target file + * @param aFilenames Files to be converted + * @param aTargetFile Target file + * @throws IOException If IO error occurs or tool fails conversion + */ + public void convertMedia( List aFilenames, + String aTargetFile ) throws IOException + { + ArrayList newFiles = new ArrayList(); + + checkMedias( aFilenames, newFiles ); + Runtime rt = Runtime.getRuntime(); + iProcess = rt.exec( getExecParameters( aFilenames, aTargetFile ), + getEnvironmentVariables() ); + try + { + iProcess.waitFor(); + } + catch ( InterruptedException e ) + { + throw new IOException( "Conversion interrupted" ); + } + + if( iProcess.exitValue() != 0 ) + { + InputStream input = null; + BufferedReader in = null; + StringBuffer sb = null; + try + { + // reading the error logs + input = iProcess.getErrorStream(); + in = new BufferedReader( new InputStreamReader( input ) ); + sb = new StringBuffer(); + String line = null; + while ( ( line = in.readLine() ) != null ) + { + sb.append( line ); + sb.append( '\n' ); + } + } + finally + { + if( input != null ) + { + input.close(); + } + if( in != null ) + { + in.close(); + } + } + + deleteTemporaryFiles( newFiles ); + throw new IOException( "Conversion failed with error code: " + + iProcess.exitValue() + + "\nError log: " + sb.toString() ); + } + // read the output logs, and check that there is success indication (in case that tool does not + // support sending error code) + boolean success = false; + String line = null; + String lastLine = null; + InputStream input = null; + BufferedReader in = null; + try + { + input = iProcess.getInputStream(); + in = new BufferedReader( new InputStreamReader( input ) ); + while ( ( line = in.readLine() ) != null ) + { + if( line.equals( getSuccesIndicationLine() ) ) + { + success = true; + break; + } + lastLine = line; + } + } + finally + { + if( input != null ) + { + input.close(); + } + if( in != null ) + { + in.close(); + } + } + iProcess = null; + // Delete temporary files + deleteTemporaryFiles( newFiles ); + // did not found success line + if( !success ) + { + throw new IOException( "Running media converter failed: " + lastLine ); + } + } + + /** + * Delete temporary files + * @param newFiles List of temporary files + * @throws IOException If file deletion fails + */ + protected void deleteTemporaryFiles( List aNewFiles ) throws IOException + { + for ( Iterator iterator = aNewFiles.iterator(); iterator.hasNext(); ) + { + String filename = ( String ) iterator.next(); + File file = new File( filename ); + if( !file.delete() ) + { + throw new IOException( "Temporary file deletion failed: " + filename ); + } + } + } + + /** + * Checks that input medias does not contain illegal files and converts + * other image formats to BMP + * @param aFilenames List of files to be added in MBM file + * @param aNewFiles List of created temporary files + * @throws IOException thrown if some of encoders are missing, or some error in image reading/writing + */ + protected void checkMedias( List aFilenames, + List aNewFiles ) throws IOException + { + // load BMP writer + Iterator writers = ImageIO.getImageWritersByFormatName( BMP ); + if( !writers.hasNext() ) + { + throw new IOException( "BMP encoder not found" ); + } + ImageWriter bmpWriter = ( ImageWriter ) writers.next(); + + ArrayList newNames = new ArrayList(); + // Go through all files and check if there is something else than BMP + for ( Iterator iterator = aFilenames.iterator(); + iterator.hasNext(); ) + { + String imageName = ( String ) iterator.next(); + ImageInputStream input = ImageIO.createImageInputStream( + new File( imageName ) ); + + String destinationImage = null; + try + { + Iterator readers = ImageIO.getImageReaders( input ); + if( !readers.hasNext() ) + { + throw new IOException( "Unknown file" ); + } + ImageReader ir = ( ImageReader ) readers.next(); + //Convert file if it is not BMP + destinationImage = imageName; + if( !ir.getFormatName().equalsIgnoreCase( BMP ) ) + { + // read original image + ir.setInput( input ); + IIOImage image = ir.readAll( 0, null ); + destinationImage = imageName.substring( + 0, imageName.lastIndexOf( DOT ) + 1 ) + BMP; + File destFile = new File( destinationImage ); + int index = 1; + // create unique name to not overwrite any existing files + while( destFile.exists() ) + { + destinationImage = imageName.substring( 0, + imageName.lastIndexOf( DOT ) ) + + index++ + DOT + BMP; + destFile = new File( destinationImage ); + } + // Write image back in BMP format + ImageOutputStream output = + ImageIO.createImageOutputStream( destFile ); + try + { + bmpWriter.setOutput( output ); + bmpWriter.write( image ); + } + finally + { + if( output != null ) + { + output.close(); + } + } + aNewFiles.add( destinationImage ); + } + } + finally + { + if( input != null ) + { + input.close(); + } + } + + newNames.add( destinationImage ); + } + // change new names to list + aFilenames.clear(); + aFilenames.addAll( newNames ); + } + }