themeinstaller/source/src/com/nokia/tools/themeinstaller/installationmanager/InstallationManager.java
branchRCL_3
changeset 33 04b7640f6fb5
parent 0 05da4621cfb2
equal deleted inserted replaced
32:fe49e33862e2 33:04b7640f6fb5
       
     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:  Starting point for theme install procedure.
       
    15  *
       
    16 */
       
    17 
       
    18 
       
    19 package com.nokia.tools.themeinstaller.installationmanager;
       
    20 
       
    21 import java.io.File;
       
    22 import java.io.FilenameFilter;
       
    23 import java.io.IOException;
       
    24 import java.io.InputStream;
       
    25 import java.util.Enumeration;
       
    26 import java.util.Observable;
       
    27 import java.util.Observer;
       
    28 import java.util.Vector;
       
    29 
       
    30 import javax.xml.transform.Result;
       
    31 import javax.xml.transform.Source;
       
    32 import javax.xml.transform.Transformer;
       
    33 import javax.xml.transform.TransformerFactory;
       
    34 import javax.xml.transform.dom.DOMSource;
       
    35 import javax.xml.transform.stream.StreamResult;
       
    36 
       
    37 import org.w3c.dom.Node;
       
    38 import org.w3c.dom.NodeList;
       
    39 import org.w3c.dom.traversal.NodeIterator;
       
    40 
       
    41 import com.nokia.tools.themeinstaller.defrep.DefinitionRepository;
       
    42 import com.nokia.tools.themeinstaller.defrep.IDefinitionRepository;
       
    43 import com.nokia.tools.themeinstaller.defrep.operations.FileOperation;
       
    44 import com.nokia.tools.themeinstaller.defrep.operations.FileOperationEvent;
       
    45 import com.nokia.tools.themeinstaller.odtconverter.ConverterProperties;
       
    46 import com.nokia.tools.themeinstaller.odtconverter.IParseOperationListener;
       
    47 import com.nokia.tools.themeinstaller.odtconverter.ODTDocument;
       
    48 import com.nokia.tools.themeinstaller.odtconverter.ODTHeader;
       
    49 import com.nokia.tools.themeinstaller.odtconverter.ODTInputStream;
       
    50 import com.sun.org.apache.xpath.internal.XPathAPI;
       
    51 
       
    52 /**
       
    53  * Installation Manager class is the starting point for the theme installation
       
    54  * procedure.
       
    55  */
       
    56 public class InstallationManager implements Observer, IInstallationListener
       
    57     {
       
    58 
       
    59     protected static final String MANIFEST_SUFFIX = ".dat";
       
    60 
       
    61     // Theme manifest file
       
    62     private File iManifest;
       
    63 
       
    64     // Destination root directory
       
    65     private File iDestinationDir;
       
    66 
       
    67     // Definition repository for file operations
       
    68     private IDefinitionRepository iDefRep;
       
    69 
       
    70     // Data directory containing the theme to install
       
    71     private String iDataDir;
       
    72 
       
    73     // Installation observer
       
    74     private IInstallationListener iListener;
       
    75 
       
    76     // Resource installer
       
    77     private IResourceInstaller iResourceInstaller;
       
    78 
       
    79     // Installation list of ongoing installations
       
    80     private InstallationList iList;
       
    81 
       
    82     // Lock for asynchronous operations.
       
    83     private Lock iLock;
       
    84 
       
    85     // Lock for multi theme installs
       
    86     private Lock iMultiThemeLock;
       
    87 
       
    88     // Localisation settings
       
    89     private File iLocSettings;
       
    90     
       
    91     //DTD may contain some errors such as missing semicolon. Set
       
    92     //this to true if these are to be fixed. Currently passed via 
       
    93     //argument.
       
    94     private static boolean fixDTD = false;
       
    95 
       
    96     /**
       
    97      * Default constructor
       
    98      * @param aParams Installation parameters
       
    99      * @param aListener Installation observer
       
   100      * @throws IOException if Resource Installer can not be created
       
   101      */
       
   102     public InstallationManager( InstallationParameters aParams,
       
   103                                 IInstallationListener aListener )
       
   104         throws IOException
       
   105         {
       
   106         // Properties must be initialized before using them
       
   107         ConverterProperties.initialize( aParams.getPropFile() );
       
   108 
       
   109         iManifest = aParams.getManifest();
       
   110         iLocSettings = aParams.getLocSettings();
       
   111         iDestinationDir = aParams.getDestinationDir();
       
   112         iListener = aListener;
       
   113 
       
   114         // Create destination directory structure
       
   115         if( !iDestinationDir.exists() )
       
   116             {
       
   117             iDestinationDir.mkdirs();
       
   118             }
       
   119 
       
   120         iDefRep = DefinitionRepository.getInstance();
       
   121 
       
   122         if( iManifest.getParent() == null )
       
   123             {
       
   124             iDataDir = ManifestFactory.CURRENT_DIR + File.separatorChar;
       
   125             }
       
   126         else
       
   127             {
       
   128             iDataDir = iManifest.getParent() + File.separatorChar;
       
   129             }
       
   130 
       
   131         iResourceInstaller =
       
   132             new ResourceInstaller( iDefRep, iDestinationDir, iDataDir);
       
   133         iList = new InstallationList();
       
   134         iLock = new Lock();
       
   135         iMultiThemeLock = new Lock();
       
   136         }
       
   137 
       
   138     
       
   139     public static boolean isFixDTD() {
       
   140 		return fixDTD;
       
   141 	}
       
   142 
       
   143 
       
   144 	public static void setFixDTD(boolean fixDTD) {
       
   145 		InstallationManager.fixDTD = fixDTD;
       
   146 	}
       
   147 
       
   148 
       
   149 	/**
       
   150      * Starts the actual installation
       
   151      * Progress will be informed via listener
       
   152      * @throws IOException If files cannot be found, or new files cannot be written
       
   153      * @throws IllegalArgumentException If there exists syntax errors in manifest file
       
   154      */
       
   155     public void startInstallation() throws IOException
       
   156         {
       
   157         // Source parameter is a directory
       
   158         if( iManifest.isDirectory() )
       
   159             {
       
   160             Enumeration manifests = searchManifests( iManifest ).elements();
       
   161             if( manifests.hasMoreElements() )
       
   162                 {
       
   163                 // Install all found themes
       
   164                 installMultiTheme( manifests );
       
   165                 }
       
   166             else
       
   167                 {
       
   168                 // No themes found
       
   169                 throw new IllegalArgumentException(
       
   170                         "Manifest files not found from: " + iManifest.getPath() );
       
   171                 }
       
   172             }
       
   173         // Source parameter is a file
       
   174         else
       
   175             {
       
   176             // Parse the manifest
       
   177             ManifestFactory factory = new ManifestFactory( iLocSettings );
       
   178             IThemeManifest manifest = factory.createManifest( iManifest );
       
   179 
       
   180             // Install sub themes of a multi theme manifest, if any
       
   181             Enumeration manifests = manifest.getManifestFiles().elements();
       
   182             if( manifests.hasMoreElements() )
       
   183                 {
       
   184                 installMultiTheme( manifests );
       
   185                 }
       
   186             // Install a normal theme
       
   187             else
       
   188                 {
       
   189                 installTheme( manifest, iLocSettings );
       
   190                 }
       
   191             }
       
   192         }
       
   193 
       
   194     /* (non-Javadoc)
       
   195      * @see java.util.Observer#update(java.util.Observable, java.lang.Object)
       
   196      */
       
   197     public void update( Observable aObservable, Object aEvent )
       
   198         {
       
   199         // Language install event
       
   200         if( aObservable instanceof LanguageInstaller )
       
   201             {
       
   202             // Notify that the parsing operation has completed and
       
   203             // the install of next language variant will start
       
   204             iLock.unLock();
       
   205 
       
   206             LanguageInstallEvent event = ( LanguageInstallEvent )aEvent;
       
   207             ODTHeader header = event.getODTDocument().getODTHeader();
       
   208             ProgressEvent pe = new ProgressEvent();
       
   209             pe.setState( IInstallationListener.STATE_PARSED );
       
   210             pe.setName( ( String )header.get( ODTHeader.ThemeShortName ) );
       
   211             pe.setLanguage( (
       
   212                     ( Integer )header.get( ODTHeader.Language ) ).intValue() );
       
   213             pe.setError( event.getErrorCode(), event.getReason() );
       
   214 
       
   215             iListener.installationProgress( pe );
       
   216             if( event.getErrorCode() ==
       
   217                 IParseOperationListener.OPERATION_SUCCESSFUL )
       
   218                 {
       
   219                 InputStream in = null;
       
   220                 try
       
   221                     {
       
   222                     // Store the ODT file
       
   223                     ODTDocument document = event.getODTDocument();
       
   224                     in = new ODTInputStream( document );
       
   225                     
       
   226 //                    Source s = new DOMSource(document.getDOMDocument());
       
   227 //                    
       
   228 //                    Result r = new StreamResult(new File("C://output.xml"));
       
   229 //                    
       
   230 //                    Transformer t = TransformerFactory.newInstance().newTransformer();
       
   231 //                    
       
   232 //                    t.transform(s, r);
       
   233                     	
       
   234                     iDefRep.storeODT( iDestinationDir,
       
   235                             document.getODTHeader(),
       
   236                             in,
       
   237                             this );
       
   238                     }
       
   239                 catch ( Exception e )
       
   240                     {
       
   241                     pe.setError( IInstallationListener.ERROR, e.toString() );
       
   242                     iListener.installationCompleted( pe );
       
   243                     }
       
   244                 finally
       
   245                     {
       
   246                     if( in != null )
       
   247                         {
       
   248                         try
       
   249                             {
       
   250                             in.close();
       
   251                             }
       
   252                         catch ( IOException e )
       
   253                             {
       
   254                             // Ignore error
       
   255                             }
       
   256                         }
       
   257                     }
       
   258                 }
       
   259             else
       
   260                 {
       
   261                 pe.setError( event.getErrorCode(), event.getReason() );
       
   262                 iListener.installationCompleted( pe );
       
   263                 }
       
   264             }
       
   265         // File operation event
       
   266         else if( aObservable instanceof FileOperation )
       
   267             {
       
   268             FileOperationEvent event = ( FileOperationEvent )aEvent;
       
   269             ProgressEvent pe = new ProgressEvent();
       
   270             pe.setState( IInstallationListener.STATE_WRITED );
       
   271             pe.setFileName( event.getFullDestPath() );
       
   272             pe.setError( event.getErrorCode(), null );
       
   273 
       
   274             if( event.getErrorCode() == FileOperationEvent.OPERATION_SUCCESSFUL )
       
   275                 {
       
   276                 pe.setFileName( event.getFullDestPath() );
       
   277                 iListener.installationProgress( pe );
       
   278                 }
       
   279             else
       
   280                 {
       
   281                 pe.setError( event.getErrorCode(), null );
       
   282                 iListener.installationCompleted( pe );
       
   283                 }
       
   284 
       
   285             iList.removeInstall( event.getDestPath() );
       
   286             if( !iList.installsExist() )
       
   287                 {
       
   288                 pe.setError( event.getErrorCode(), null );
       
   289                 iListener.installationCompleted( pe );
       
   290                 }
       
   291             }
       
   292         }
       
   293 
       
   294     /* (non-Javadoc)
       
   295      * @see com.nokia.tools.themeinstaller.installationmanager.IInstallationListener#installationProgress(com.nokia.tools.themeinstaller.installationmanager.ProgressEvent)
       
   296      */
       
   297     public void installationProgress( ProgressEvent aEvent )
       
   298         {
       
   299         // Pass the event
       
   300         iListener.installationProgress( aEvent );
       
   301         }
       
   302 
       
   303     /* (non-Javadoc)
       
   304      * @see com.nokia.tools.themeinstaller.installationmanager.IInstallationListener#installationCompleted(com.nokia.tools.themeinstaller.installationmanager.ProgressEvent)
       
   305      */
       
   306     public void installationCompleted( ProgressEvent aEvent )
       
   307         {
       
   308         // Pass the event and release the multi theme install lock
       
   309         iListener.installationCompleted( aEvent );
       
   310         iMultiThemeLock.unLock();
       
   311         }
       
   312 
       
   313     /**
       
   314      * Install a normal theme
       
   315      * @param aManifest Manifest file
       
   316      * @throws IOException if resource files can not be installed
       
   317      */
       
   318     private void installTheme( IThemeManifest aManifest, File aLocSettings )
       
   319         throws IOException
       
   320         {
       
   321         // Create unlocalized header for copying language independent resources
       
   322         ODTHeader unlocalizedHeader =
       
   323             LanguageInstaller.createHeader( aManifest, null );
       
   324         Vector resources = aManifest.getResources();
       
   325         Vector odtResources =
       
   326             iResourceInstaller.installResources( resources, unlocalizedHeader );
       
   327 
       
   328         // Get all languages
       
   329         Enumeration languages =
       
   330             aManifest.getLanguages().elements();
       
   331 
       
   332         // Install each language variant
       
   333         while( languages.hasMoreElements() )
       
   334             {
       
   335             LanguageSpecificData language =
       
   336                 ( LanguageSpecificData )languages.nextElement();
       
   337             LanguageInstaller installer = new LanguageInstaller(
       
   338                     this, aManifest, language, aLocSettings, iResourceInstaller );
       
   339 
       
   340             // Add language id to the log
       
   341             iList.addInstall( language.getLanguageId() );
       
   342 
       
   343             // Add language independent resources
       
   344             installer.addResources( odtResources );
       
   345 
       
   346             try
       
   347                 {
       
   348                 // Start the installation process
       
   349                 installer.install();
       
   350 
       
   351                 // Wait for the parsing process to complete
       
   352                 iLock.lock();
       
   353                 }
       
   354             catch( Exception e )
       
   355                 {
       
   356                 // In error cases, cancel the installation
       
   357                 ProgressEvent pe = new ProgressEvent();
       
   358                 pe.setName( aManifest.getThemeShortName() );
       
   359                 pe.setLanguage( language.getLanguageId().intValue() );
       
   360                 pe.setError( IInstallationListener.ERROR, e.toString() );
       
   361                 iListener.installationCompleted( pe );
       
   362                 }
       
   363             }
       
   364         }
       
   365 
       
   366     /**
       
   367      * Install sub themes of a multi theme manifest.
       
   368      * @param aManifests List of manifests
       
   369      */
       
   370     private void installMultiTheme( Enumeration aManifests )
       
   371         {
       
   372         while( aManifests.hasMoreElements() )
       
   373             {
       
   374             File f = ( File )aManifests.nextElement();
       
   375             try
       
   376                 {
       
   377                 // Create installation parameters for the new
       
   378                 // Installation Manager instance
       
   379                 InstallationParameters params = new InstallationParameters(
       
   380                         f, iDestinationDir );
       
   381                 params.setLocSettings( iLocSettings );
       
   382 
       
   383                 // Create a new installation manager
       
   384                 InstallationManager i = new InstallationManager( params, this );
       
   385                 i.startInstallation();
       
   386 
       
   387                 // Install only a theme at a time
       
   388                 iMultiThemeLock.lock();
       
   389                 }
       
   390             catch ( Exception e )
       
   391                 {
       
   392                 // In error cases, cancel the installation
       
   393                 ProgressEvent pe = new ProgressEvent();
       
   394                 pe.setFileName( f.getPath() );
       
   395                 pe.setError( IInstallationListener.ERROR,
       
   396                         "Sub theme installation failed: " + e.toString() );
       
   397                 iListener.installationCompleted( pe );
       
   398                 }
       
   399             }
       
   400 
       
   401         }
       
   402 
       
   403     private Vector searchManifests( File aLocation )
       
   404         {
       
   405         // Create a FilenameFilter class for searching manifest (.dat) files
       
   406         FilenameFilter filter = new FilenameFilter()
       
   407             {
       
   408             public boolean accept( File aDir, String aName )
       
   409                 {
       
   410                 if( aName.endsWith( MANIFEST_SUFFIX ) )
       
   411                     {
       
   412                     return true;
       
   413                     }
       
   414                 return false;
       
   415                 }
       
   416             };
       
   417 
       
   418         // List all manifest files in the directory and add them to
       
   419         // the result vector
       
   420         File[] files = aLocation.listFiles( filter );
       
   421         Vector v = new Vector();
       
   422         for( int i = 0; i < files.length; i++ )
       
   423             {
       
   424             v.add( files[ i ] );
       
   425             }
       
   426 
       
   427         return v;
       
   428         }
       
   429 
       
   430     }