diff -r fe49e33862e2 -r 04b7640f6fb5 themeinstaller/source/src/com/nokia/tools/themeinstaller/installationmanager/ResourceInstaller.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/themeinstaller/source/src/com/nokia/tools/themeinstaller/installationmanager/ResourceInstaller.java Wed Sep 01 12:32:13 2010 +0100 @@ -0,0 +1,329 @@ +/* +* 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: Class for installing theme resources + * +*/ + + +package com.nokia.tools.themeinstaller.installationmanager; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.Observable; +import java.util.Observer; +import java.util.Vector; + +import com.nokia.tools.themeinstaller.defrep.IDefinitionRepository; +import com.nokia.tools.themeinstaller.defrep.operations.FileOperationEvent; +import com.nokia.tools.themeinstaller.defrep.operations.FileOperationUtils; +import com.nokia.tools.themeinstaller.mediaconverter.MediaConverter; +import com.nokia.tools.themeinstaller.odtconverter.MimeTypeResolver; +import com.nokia.tools.themeinstaller.odtconverter.ODTHeader; +import com.nokia.tools.themeinstaller.odtconverter.ODTResource; +import com.nokia.tools.themeinstaller.odtconverter.ThemeStatusResolver; + +/** + * Class for installing theme resources. + */ +public class ResourceInstaller implements IResourceInstaller + { + + // CONSTANTS + private static final String MBM_SUFFIX = "mbm"; + private static final char FILE_EXT_SEPARATOR = '.'; + + // Definition repository for accessing the file storage services + private IDefinitionRepository iDefRep; + + // File operation event for observing file operations + private FileOperationEvent iEvent; + + // Destination root directory + private File iDestinationDir; + + // Data directory + private String iDataDir; + + // Media converter for converting resources + private MediaConverter iMediaConverter; + + // Mime type resolver for resolving resource type + private MimeTypeResolver iMimeResolver; + + // Observer for monitoring file operation completions + private Observer iFileCopyObserver; + + // For storing temporary files. + private Vector iTempFiles; + + // Lock for asynchronous operations. + private Lock iLock; + + /** + * Constructor. + * @param aDefRep Definition Repository for accessing the file storage + * @param aDestinationDir Destination root directory + * @param aDataDir Data directory containing the theme sources + * @param aNameSpace Theme name space + * @throws IOException if Media Converter can not be created + */ + public ResourceInstaller( IDefinitionRepository aDefRep, + File aDestinationDir, + String aDataDir ) throws IOException + { + iDefRep = aDefRep; + iDestinationDir = aDestinationDir; + iDataDir = aDataDir; + iMediaConverter = new MediaConverter(); + iMimeResolver = new MimeTypeResolver(); + iTempFiles = new Vector(); + iLock = new Lock(); + + // Create an observer for monitoring file copy operation completions + iFileCopyObserver = new Observer() + { + public void update( Observable aFileOperation, Object aEvent ) + { + // Store the event + iEvent = ( FileOperationEvent ) aEvent; + // Open the lock + iLock.unLock(); + } + }; + } + + /* (non-Javadoc) + * @see com.nokia.tools.odtconverter.installationmanager.IResourceInstaller#installResources(java.util.Vector, com.nokia.tools.odtconverter.ODTHeader) + */ + public Vector installResources( + Vector aResources, + ODTHeader aHeader ) throws IOException + { + Vector result = new Vector(); + Enumeration resources = aResources.elements(); + + // Process all resource files + while ( resources.hasMoreElements() ) + { + result.add( installResource( ( ThemeResource ) resources.nextElement(), aHeader ) ); + } + + return result; + } + + /* (non-Javadoc) + * @see com.nokia.tools.odtconverter.installationmanager.IResourceInstaller#installResource(com.nokia.tools.odtconverter.installationmanager.ThemeResource, com.nokia.tools.odtconverter.ODTHeader) + */ + public ODTResource installResource( ThemeResource aResource, + ODTHeader aHeader ) throws IOException + { + // Create the ODT resource + ODTResource res = createResource( iDataDir, aResource ); + + // Copy file to correct location + File f = new File( + iDataDir + ( String )res.get( ODTResource.TempFileName ) ); + iDefRep.copyResource( + f, + iDestinationDir, + aHeader, + iFileCopyObserver ); + // Wait for file copying + iLock.lock(); + + if ( iEvent.getErrorCode() == FileOperationEvent.OPERATION_SUCCESSFUL ) + { + deleteTemporaryFile( iEvent.getFile().getName() ); + } + else + { + throw new IOException( "Resource file copying failed: " + + f.getPath() ); + } + + // Set the actual resource location (in Symbian file system) to resource + res.put( ODTResource.FileName, iEvent.getDestPath() ); + return res; + } + + /** + * Delete temporary file. + * + * @param aFileName The file name + * + * @throws IOException Signals that an I/O exception has occurred. + */ + private void deleteTemporaryFile( String aFileName ) throws IOException + { + Enumeration fileObjects = iTempFiles.elements(); + + while ( fileObjects.hasMoreElements() ) + { + File temp = ( File ) fileObjects.nextElement(); + if ( temp.getName().equals( aFileName ) ) + { + if ( !temp.delete() ) + { + throw new IOException( "Temporary file deletion failed: " + + aFileName ); + } + else + { + iTempFiles.remove( temp ); + deleteTemporaryFile( aFileName ); + } + } + } + } + + + /* (non-Javadoc) + * @see com.nokia.tools.odtconverter.installationmanager.IResourceInstaller#createODTResource(com.nokia.tools.odtconverter.ODTHeader) + */ + public ODTResource createODTResource( ODTHeader aHeader, String aNameSpace ) + { + ODTResource res = new ODTResource(); + String odtPath = null; + + // Create ODT file path + odtPath = iDefRep.createODTPath( iDestinationDir, aHeader ); + + // Convert the path to Symbian OS file system format + odtPath = FileOperationUtils.parseSymbianFSPath( odtPath ); + + res.put( ODTResource.FileName, odtPath ); + res.put( ODTResource.CacheType, + new Integer( ManifestFactory.CACHE_TYPE_CACHE_FILE ) ); + + // If EXnThemeStatusLicenceeDefault flag is set, + // locking policy is E_XN_LOCKED + int flags = ( ( Integer )aHeader.get( ODTHeader.Flags ) ).intValue(); + if ( ( flags & ThemeStatusResolver.E_XN_THEME_STATUS_LICENCEE_DEFAULT ) != 0 ) + { + res.put( ODTResource.LockingPolicy, + new Integer( ManifestFactory.E_XN_LOCKED ) ); + } + else + { + res.put( ODTResource.LockingPolicy, + new Integer( ManifestFactory.E_XN_UNLOCKED ) ); + } + + // ODT file's mime type is "unknown" + res.put( ODTResource.MimeType, MimeTypeResolver.UNKNOWN_MIME_TYPE ); + res.put( ODTResource.NameSpace, aNameSpace ); + res.put( ODTResource.ResourceID, aHeader + .get( ODTHeader.ThemeShortName ) ); + res.put( ODTResource.ResourceType, new Integer( + MimeTypeResolver.E_RESOURCEODT ) ); + return res; + } + + + /** + * Creates ODT resource from given node + * @param aItem DOM Node to be added + * @param aDataDirectory Resource directory + * @return new ODTResource object + * @throws IOException if media file can not be converter + */ + private ODTResource createResource( String aDataDirectory, + ThemeResource aItem ) throws IOException + { + ODTResource res = new ODTResource(); + + String tempFileName = null; + String filename = aItem.getFileName(); + int cacheType = aItem.getCacheType(); + + // Determine the need for media conversion + if( cacheType == ManifestFactory.CACHE_TYPE_CACHE_FILE || + cacheType == ManifestFactory.CACHE_TYPE_CACHE_MEMORY ) + { + // Convert the media file + tempFileName = convertMedia( aDataDirectory + filename ); + } + else + { + // No media conversion + tempFileName = filename; + } + + // Remove directories and separators from the file name + int fileNameIndex = tempFileName.lastIndexOf( File.separatorChar ); + if( fileNameIndex > -1 ) + { + tempFileName = tempFileName.substring( fileNameIndex + 1 ); + } + + // Update resource type after media conversion + aItem.setResourceType( iMimeResolver.getResourceType( tempFileName ) ); + aItem.setMimeType( iMimeResolver.getMimeType( tempFileName ) ); + + // Set temporary file name that is not externalized. It is required + // only for copying the resource file in a case that media conversion + // has changed the file name and extension. + res.put( ODTResource.TempFileName, tempFileName ); + + // Set properties that are externalized. The file name is set after the + // resource file is copied to the correct location. + res.put( ODTResource.CacheType, new Integer(cacheType )); + res.put( ODTResource.ResourceID, filename ); + res.put( ODTResource.LockingPolicy, new Integer(aItem.getLockingPolicy() )); + res.put( ODTResource.NameSpace, aItem.getNameSpace() ); + res.put( ODTResource.MimeType, aItem.getMimeType() ); + res.put( ODTResource.ResourceType, new Integer(aItem.getResourceType() )); + return res; + } + + /** + * Uses MediaConverter to converts media to MBM + * @param aFilename File to convert + * @return Filename of converted resource + * @throws IOException File conversion fails + */ + private String convertMedia( String aFilename ) throws IOException + { + ArrayList files = new ArrayList(); + files.add( aFilename ); + int dotPosition = aFilename.lastIndexOf( FILE_EXT_SEPARATOR ) + 1; + String destinationImage = + aFilename.substring( 0, dotPosition ) + MBM_SUFFIX; + + if ( dotPosition == 0 ) + { + destinationImage = aFilename + FILE_EXT_SEPARATOR + MBM_SUFFIX; + } + + String filePrefix = destinationImage.substring( 0, + destinationImage.lastIndexOf( FILE_EXT_SEPARATOR ) ); + File destFile = new File( destinationImage ); + int index = 1; + + // create unique name to not overwrite any existing files + while( destFile.exists() ) + { + destinationImage = + filePrefix + index++ + FILE_EXT_SEPARATOR + MBM_SUFFIX; + destFile = new File( destinationImage ); + } + + iMediaConverter.convertMedia( files, destinationImage ); + iTempFiles.add( destFile ); + return destinationImage; + } + + }