themeinstaller/source/src/com/nokia/tools/themeinstaller/installationmanager/InstallationManager.java
branchRCL_3
changeset 33 04b7640f6fb5
parent 0 05da4621cfb2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/themeinstaller/source/src/com/nokia/tools/themeinstaller/installationmanager/InstallationManager.java	Wed Sep 01 12:32:13 2010 +0100
@@ -0,0 +1,430 @@
+/*
+* 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:  Starting point for theme install procedure.
+ *
+*/
+
+
+package com.nokia.tools.themeinstaller.installationmanager;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Enumeration;
+import java.util.Observable;
+import java.util.Observer;
+import java.util.Vector;
+
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.traversal.NodeIterator;
+
+import com.nokia.tools.themeinstaller.defrep.DefinitionRepository;
+import com.nokia.tools.themeinstaller.defrep.IDefinitionRepository;
+import com.nokia.tools.themeinstaller.defrep.operations.FileOperation;
+import com.nokia.tools.themeinstaller.defrep.operations.FileOperationEvent;
+import com.nokia.tools.themeinstaller.odtconverter.ConverterProperties;
+import com.nokia.tools.themeinstaller.odtconverter.IParseOperationListener;
+import com.nokia.tools.themeinstaller.odtconverter.ODTDocument;
+import com.nokia.tools.themeinstaller.odtconverter.ODTHeader;
+import com.nokia.tools.themeinstaller.odtconverter.ODTInputStream;
+import com.sun.org.apache.xpath.internal.XPathAPI;
+
+/**
+ * Installation Manager class is the starting point for the theme installation
+ * procedure.
+ */
+public class InstallationManager implements Observer, IInstallationListener
+    {
+
+    protected static final String MANIFEST_SUFFIX = ".dat";
+
+    // Theme manifest file
+    private File iManifest;
+
+    // Destination root directory
+    private File iDestinationDir;
+
+    // Definition repository for file operations
+    private IDefinitionRepository iDefRep;
+
+    // Data directory containing the theme to install
+    private String iDataDir;
+
+    // Installation observer
+    private IInstallationListener iListener;
+
+    // Resource installer
+    private IResourceInstaller iResourceInstaller;
+
+    // Installation list of ongoing installations
+    private InstallationList iList;
+
+    // Lock for asynchronous operations.
+    private Lock iLock;
+
+    // Lock for multi theme installs
+    private Lock iMultiThemeLock;
+
+    // Localisation settings
+    private File iLocSettings;
+    
+    //DTD may contain some errors such as missing semicolon. Set
+    //this to true if these are to be fixed. Currently passed via 
+    //argument.
+    private static boolean fixDTD = false;
+
+    /**
+     * Default constructor
+     * @param aParams Installation parameters
+     * @param aListener Installation observer
+     * @throws IOException if Resource Installer can not be created
+     */
+    public InstallationManager( InstallationParameters aParams,
+                                IInstallationListener aListener )
+        throws IOException
+        {
+        // Properties must be initialized before using them
+        ConverterProperties.initialize( aParams.getPropFile() );
+
+        iManifest = aParams.getManifest();
+        iLocSettings = aParams.getLocSettings();
+        iDestinationDir = aParams.getDestinationDir();
+        iListener = aListener;
+
+        // Create destination directory structure
+        if( !iDestinationDir.exists() )
+            {
+            iDestinationDir.mkdirs();
+            }
+
+        iDefRep = DefinitionRepository.getInstance();
+
+        if( iManifest.getParent() == null )
+            {
+            iDataDir = ManifestFactory.CURRENT_DIR + File.separatorChar;
+            }
+        else
+            {
+            iDataDir = iManifest.getParent() + File.separatorChar;
+            }
+
+        iResourceInstaller =
+            new ResourceInstaller( iDefRep, iDestinationDir, iDataDir);
+        iList = new InstallationList();
+        iLock = new Lock();
+        iMultiThemeLock = new Lock();
+        }
+
+    
+    public static boolean isFixDTD() {
+		return fixDTD;
+	}
+
+
+	public static void setFixDTD(boolean fixDTD) {
+		InstallationManager.fixDTD = fixDTD;
+	}
+
+
+	/**
+     * Starts the actual installation
+     * Progress will be informed via listener
+     * @throws IOException If files cannot be found, or new files cannot be written
+     * @throws IllegalArgumentException If there exists syntax errors in manifest file
+     */
+    public void startInstallation() throws IOException
+        {
+        // Source parameter is a directory
+        if( iManifest.isDirectory() )
+            {
+            Enumeration manifests = searchManifests( iManifest ).elements();
+            if( manifests.hasMoreElements() )
+                {
+                // Install all found themes
+                installMultiTheme( manifests );
+                }
+            else
+                {
+                // No themes found
+                throw new IllegalArgumentException(
+                        "Manifest files not found from: " + iManifest.getPath() );
+                }
+            }
+        // Source parameter is a file
+        else
+            {
+            // Parse the manifest
+            ManifestFactory factory = new ManifestFactory( iLocSettings );
+            IThemeManifest manifest = factory.createManifest( iManifest );
+
+            // Install sub themes of a multi theme manifest, if any
+            Enumeration manifests = manifest.getManifestFiles().elements();
+            if( manifests.hasMoreElements() )
+                {
+                installMultiTheme( manifests );
+                }
+            // Install a normal theme
+            else
+                {
+                installTheme( manifest, iLocSettings );
+                }
+            }
+        }
+
+    /* (non-Javadoc)
+     * @see java.util.Observer#update(java.util.Observable, java.lang.Object)
+     */
+    public void update( Observable aObservable, Object aEvent )
+        {
+        // Language install event
+        if( aObservable instanceof LanguageInstaller )
+            {
+            // Notify that the parsing operation has completed and
+            // the install of next language variant will start
+            iLock.unLock();
+
+            LanguageInstallEvent event = ( LanguageInstallEvent )aEvent;
+            ODTHeader header = event.getODTDocument().getODTHeader();
+            ProgressEvent pe = new ProgressEvent();
+            pe.setState( IInstallationListener.STATE_PARSED );
+            pe.setName( ( String )header.get( ODTHeader.ThemeShortName ) );
+            pe.setLanguage( (
+                    ( Integer )header.get( ODTHeader.Language ) ).intValue() );
+            pe.setError( event.getErrorCode(), event.getReason() );
+
+            iListener.installationProgress( pe );
+            if( event.getErrorCode() ==
+                IParseOperationListener.OPERATION_SUCCESSFUL )
+                {
+                InputStream in = null;
+                try
+                    {
+                    // Store the ODT file
+                    ODTDocument document = event.getODTDocument();
+                    in = new ODTInputStream( document );
+                    
+//                    Source s = new DOMSource(document.getDOMDocument());
+//                    
+//                    Result r = new StreamResult(new File("C://output.xml"));
+//                    
+//                    Transformer t = TransformerFactory.newInstance().newTransformer();
+//                    
+//                    t.transform(s, r);
+                    	
+                    iDefRep.storeODT( iDestinationDir,
+                            document.getODTHeader(),
+                            in,
+                            this );
+                    }
+                catch ( Exception e )
+                    {
+                    pe.setError( IInstallationListener.ERROR, e.toString() );
+                    iListener.installationCompleted( pe );
+                    }
+                finally
+                    {
+                    if( in != null )
+                        {
+                        try
+                            {
+                            in.close();
+                            }
+                        catch ( IOException e )
+                            {
+                            // Ignore error
+                            }
+                        }
+                    }
+                }
+            else
+                {
+                pe.setError( event.getErrorCode(), event.getReason() );
+                iListener.installationCompleted( pe );
+                }
+            }
+        // File operation event
+        else if( aObservable instanceof FileOperation )
+            {
+            FileOperationEvent event = ( FileOperationEvent )aEvent;
+            ProgressEvent pe = new ProgressEvent();
+            pe.setState( IInstallationListener.STATE_WRITED );
+            pe.setFileName( event.getFullDestPath() );
+            pe.setError( event.getErrorCode(), null );
+
+            if( event.getErrorCode() == FileOperationEvent.OPERATION_SUCCESSFUL )
+                {
+                pe.setFileName( event.getFullDestPath() );
+                iListener.installationProgress( pe );
+                }
+            else
+                {
+                pe.setError( event.getErrorCode(), null );
+                iListener.installationCompleted( pe );
+                }
+
+            iList.removeInstall( event.getDestPath() );
+            if( !iList.installsExist() )
+                {
+                pe.setError( event.getErrorCode(), null );
+                iListener.installationCompleted( pe );
+                }
+            }
+        }
+
+    /* (non-Javadoc)
+     * @see com.nokia.tools.themeinstaller.installationmanager.IInstallationListener#installationProgress(com.nokia.tools.themeinstaller.installationmanager.ProgressEvent)
+     */
+    public void installationProgress( ProgressEvent aEvent )
+        {
+        // Pass the event
+        iListener.installationProgress( aEvent );
+        }
+
+    /* (non-Javadoc)
+     * @see com.nokia.tools.themeinstaller.installationmanager.IInstallationListener#installationCompleted(com.nokia.tools.themeinstaller.installationmanager.ProgressEvent)
+     */
+    public void installationCompleted( ProgressEvent aEvent )
+        {
+        // Pass the event and release the multi theme install lock
+        iListener.installationCompleted( aEvent );
+        iMultiThemeLock.unLock();
+        }
+
+    /**
+     * Install a normal theme
+     * @param aManifest Manifest file
+     * @throws IOException if resource files can not be installed
+     */
+    private void installTheme( IThemeManifest aManifest, File aLocSettings )
+        throws IOException
+        {
+        // Create unlocalized header for copying language independent resources
+        ODTHeader unlocalizedHeader =
+            LanguageInstaller.createHeader( aManifest, null );
+        Vector resources = aManifest.getResources();
+        Vector odtResources =
+            iResourceInstaller.installResources( resources, unlocalizedHeader );
+
+        // Get all languages
+        Enumeration languages =
+            aManifest.getLanguages().elements();
+
+        // Install each language variant
+        while( languages.hasMoreElements() )
+            {
+            LanguageSpecificData language =
+                ( LanguageSpecificData )languages.nextElement();
+            LanguageInstaller installer = new LanguageInstaller(
+                    this, aManifest, language, aLocSettings, iResourceInstaller );
+
+            // Add language id to the log
+            iList.addInstall( language.getLanguageId() );
+
+            // Add language independent resources
+            installer.addResources( odtResources );
+
+            try
+                {
+                // Start the installation process
+                installer.install();
+
+                // Wait for the parsing process to complete
+                iLock.lock();
+                }
+            catch( Exception e )
+                {
+                // In error cases, cancel the installation
+                ProgressEvent pe = new ProgressEvent();
+                pe.setName( aManifest.getThemeShortName() );
+                pe.setLanguage( language.getLanguageId().intValue() );
+                pe.setError( IInstallationListener.ERROR, e.toString() );
+                iListener.installationCompleted( pe );
+                }
+            }
+        }
+
+    /**
+     * Install sub themes of a multi theme manifest.
+     * @param aManifests List of manifests
+     */
+    private void installMultiTheme( Enumeration aManifests )
+        {
+        while( aManifests.hasMoreElements() )
+            {
+            File f = ( File )aManifests.nextElement();
+            try
+                {
+                // Create installation parameters for the new
+                // Installation Manager instance
+                InstallationParameters params = new InstallationParameters(
+                        f, iDestinationDir );
+                params.setLocSettings( iLocSettings );
+
+                // Create a new installation manager
+                InstallationManager i = new InstallationManager( params, this );
+                i.startInstallation();
+
+                // Install only a theme at a time
+                iMultiThemeLock.lock();
+                }
+            catch ( Exception e )
+                {
+                // In error cases, cancel the installation
+                ProgressEvent pe = new ProgressEvent();
+                pe.setFileName( f.getPath() );
+                pe.setError( IInstallationListener.ERROR,
+                        "Sub theme installation failed: " + e.toString() );
+                iListener.installationCompleted( pe );
+                }
+            }
+
+        }
+
+    private Vector searchManifests( File aLocation )
+        {
+        // Create a FilenameFilter class for searching manifest (.dat) files
+        FilenameFilter filter = new FilenameFilter()
+            {
+            public boolean accept( File aDir, String aName )
+                {
+                if( aName.endsWith( MANIFEST_SUFFIX ) )
+                    {
+                    return true;
+                    }
+                return false;
+                }
+            };
+
+        // List all manifest files in the directory and add them to
+        // the result vector
+        File[] files = aLocation.listFiles( filter );
+        Vector v = new Vector();
+        for( int i = 0; i < files.length; i++ )
+            {
+            v.add( files[ i ] );
+            }
+
+        return v;
+        }
+
+    }