javamanager/javainstaller/installer/javasrc/com/nokia/mj/impl/installer/storagehandler/StorageHandler.java
branchRCL_3
changeset 19 04becd199f91
child 47 f40128debb5d
child 49 35baca0e7a2e
equal deleted inserted replaced
16:f5050f1da672 19:04becd199f91
       
     1 /*
       
     2 * Copyright (c) 2008-2010 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:
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 package com.nokia.mj.impl.installer.storagehandler;
       
    20 
       
    21 import com.nokia.mj.impl.installer.utils.InstallerException;
       
    22 import com.nokia.mj.impl.installer.utils.Log;
       
    23 import com.nokia.mj.impl.installer.utils.PlatformUid;
       
    24 import com.nokia.mj.impl.storage.StorageAttribute;
       
    25 import com.nokia.mj.impl.storage.StorageEntry;
       
    26 import com.nokia.mj.impl.storage.StorageFactory;
       
    27 import com.nokia.mj.impl.storage.StorageNames;
       
    28 import com.nokia.mj.impl.storage.StorageSession;
       
    29 import com.nokia.mj.impl.utils.Attribute;
       
    30 import com.nokia.mj.impl.utils.Tokenizer;
       
    31 import com.nokia.mj.impl.utils.Uid;
       
    32 import com.nokia.mj.impl.utils.Version;
       
    33 
       
    34 import java.util.Enumeration;
       
    35 import java.util.Hashtable;
       
    36 import java.util.Vector;
       
    37 
       
    38 /**
       
    39  * StorageHandler offers JavaStorage services for JavaInstaller.
       
    40  */
       
    41 public class StorageHandler
       
    42 {
       
    43 
       
    44     /** StorageSession instance. */
       
    45     private StorageSession iSession = null;
       
    46     private boolean iTransactionExists = false;
       
    47 
       
    48     /**
       
    49      * Default constructor.
       
    50      */
       
    51     public StorageHandler()
       
    52     {
       
    53         try
       
    54         {
       
    55             iSession = StorageFactory.createSession();
       
    56             iSession.open();
       
    57         }
       
    58         catch (Throwable t)
       
    59         {
       
    60             InstallerException.internalError
       
    61             ("Error while constructing StorageHandler", t);
       
    62         }
       
    63     }
       
    64 
       
    65     /**
       
    66      * Closes this object.
       
    67      */
       
    68     public void close()
       
    69     {
       
    70         if (iSession != null)
       
    71         {
       
    72             try
       
    73             {
       
    74                 iSession.close();
       
    75                 iSession.destroySession();
       
    76                 iSession = null;
       
    77             }
       
    78             catch (Throwable t)
       
    79             {
       
    80                 InstallerException.internalError
       
    81                 ("Error while closing StorageHandler", t);
       
    82             }
       
    83         }
       
    84     }
       
    85 
       
    86     /**
       
    87      * Start a new Storage session for storage update.
       
    88      * This method creates a new JavaStorage transaction.
       
    89      * @throws InstallerException if session opening fails.
       
    90      */
       
    91     public void startSession()
       
    92     {
       
    93         try
       
    94         {
       
    95             checkSession();
       
    96             iSession.startTransaction();
       
    97             iTransactionExists = true;
       
    98         }
       
    99         catch (Throwable t)
       
   100         {
       
   101             InstallerException.internalError
       
   102             ("Error while starting Storage session", t);
       
   103         }
       
   104     }
       
   105 
       
   106     /**
       
   107      * Commit a successful session.
       
   108      * @throws InstallerException if committing session fails.
       
   109      */
       
   110     public void commitSession()
       
   111     {
       
   112         try
       
   113         {
       
   114             checkSession();
       
   115             checkTransaction();
       
   116             iSession.commitTransaction();
       
   117             iTransactionExists = false;
       
   118             close();
       
   119         }
       
   120         catch (Throwable t)
       
   121         {
       
   122             InstallerException.internalError
       
   123             ("Error while committing Storage session", t);
       
   124         }
       
   125     }
       
   126 
       
   127     /**
       
   128      * Rollback a session.
       
   129      * @throws InstallerException if session rollback fails.
       
   130      */
       
   131     public void rollbackSession()
       
   132     {
       
   133         try
       
   134         {
       
   135             checkSession();
       
   136             checkTransaction();
       
   137             iSession.rollbackTransaction();
       
   138             iTransactionExists = false;
       
   139             close();
       
   140         }
       
   141         catch (Throwable t)
       
   142         {
       
   143             InstallerException.internalError
       
   144             ("Error while rolling back Storage session", t);
       
   145         }
       
   146     }
       
   147 
       
   148     /**
       
   149      * Returns instance of StorageSession, or null if session
       
   150      * does not exist.
       
   151      */
       
   152     public StorageSession getSession()
       
   153     {
       
   154         return iSession;
       
   155     }
       
   156 
       
   157     /**
       
   158      * Get string which contains listing of all entries
       
   159      * from given storage table.
       
   160      */
       
   161     public String getStorageEntriesString(String aTableName)
       
   162     {
       
   163         StringBuffer result = new StringBuffer();
       
   164         try
       
   165         {
       
   166             result.append("Table ").append(aTableName).append("\n");
       
   167             StorageEntry query = new StorageEntry();
       
   168             StorageEntry[] entries = iSession.search(aTableName, query);
       
   169             if (entries == null)
       
   170             {
       
   171                 return null;
       
   172             }
       
   173             for (int i = 0; i < entries.length; i++)
       
   174             {
       
   175                 StorageEntry entry = entries[i];
       
   176                 result.append(entry.toString()).append("\n");
       
   177             }
       
   178         }
       
   179         catch (Throwable t)
       
   180         {
       
   181             InstallerException.internalError
       
   182             ("Error while getting storage table " + aTableName, t);
       
   183         }
       
   184         return result.toString();
       
   185     }
       
   186 
       
   187     /**
       
   188      * Get uids for all existing suites.
       
   189      */
       
   190     public Uid[] getSuiteUids()
       
   191     {
       
   192         try
       
   193         {
       
   194             checkSession();
       
   195             StorageEntry query = new StorageEntry();
       
   196             query.addAttribute(new StorageAttribute(StorageNames.ID, ""));
       
   197             StorageEntry[] entries = iSession.search(
       
   198                                          StorageNames.APPLICATION_PACKAGE_TABLE, query);
       
   199             if (entries == null)
       
   200             {
       
   201                 return null;
       
   202             }
       
   203             Uid[] uids = new Uid[entries.length];
       
   204             for (int i = 0; i < entries.length; i++)
       
   205             {
       
   206                 StorageEntry entry = entries[i];
       
   207                 uids[i] = PlatformUid.createUid
       
   208                           (entry.getAttribute(StorageNames.ID).getValue());
       
   209             }
       
   210             return uids;
       
   211         }
       
   212         catch (Throwable t)
       
   213         {
       
   214             InstallerException.internalError
       
   215             ("Error while getting suite uids", t);
       
   216         }
       
   217         return null;
       
   218     }
       
   219 
       
   220     /**
       
   221      * Get suite uid. Given uid parameter can either be an
       
   222      * application uid or suite uid. If it is a suite uid,
       
   223      * itself is returned. If no matching suite is found,
       
   224      * returns null.
       
   225      */
       
   226     public Uid getSuiteUid(Uid aUid)
       
   227     {
       
   228         try
       
   229         {
       
   230             checkSession();
       
   231             // Check if aUid is an application uid.
       
   232             StorageEntry query = new StorageEntry();
       
   233             query.addAttribute(new StorageAttribute
       
   234                                (StorageNames.ID, aUid.getStringValue()));
       
   235             query.addAttribute(new StorageAttribute(
       
   236                                    StorageNames.PACKAGE_ID, ""));
       
   237             StorageEntry[] entries = iSession.search(
       
   238                                          StorageNames.APPLICATION_TABLE, query);
       
   239             if (entries != null && entries.length > 0)
       
   240             {
       
   241                 // Uid is an application uid, return suite uid column.
       
   242                 return PlatformUid.createUid
       
   243                        (entries[0].getAttribute(StorageNames.PACKAGE_ID).getValue());
       
   244             }
       
   245             // Check if aUid is a suite uid.
       
   246             query = new StorageEntry();
       
   247             query.addAttribute(new StorageAttribute
       
   248                                (StorageNames.ID, aUid.getStringValue()));
       
   249             entries = iSession.search(
       
   250                           StorageNames.APPLICATION_PACKAGE_TABLE, query);
       
   251             if (entries != null && entries.length > 0)
       
   252             {
       
   253                 // Uid is a suite uid, return itself.
       
   254                 return aUid;
       
   255             }
       
   256         }
       
   257         catch (Throwable t)
       
   258         {
       
   259             InstallerException.internalError
       
   260             ("Error while getting suite uid", t);
       
   261         }
       
   262         return null;
       
   263     }
       
   264 
       
   265     /**
       
   266      * Get application uids that belong to given suite.
       
   267      * Note that this method does not guarantee the order in which
       
   268      * application uids are returned.
       
   269      * If no matching suite is found, returns null.
       
   270      */
       
   271     public Uid[] getAppUids(Uid aUid)
       
   272     {
       
   273         try
       
   274         {
       
   275             checkSession();
       
   276             Uid[] uids = null;
       
   277             StorageEntry query = new StorageEntry();
       
   278             query.addAttribute(new StorageAttribute
       
   279                                (StorageNames.PACKAGE_ID, aUid.getStringValue()));
       
   280             query.addAttribute(new StorageAttribute(StorageNames.ID, ""));
       
   281             StorageEntry[] entries = iSession.search(
       
   282                                          StorageNames.APPLICATION_TABLE, query);
       
   283             if (entries != null && entries.length > 0)
       
   284             {
       
   285                 uids = new Uid[entries.length];
       
   286                 for (int i = 0; i < entries.length; i++)
       
   287                 {
       
   288                     uids[i] = PlatformUid.createUid
       
   289                               (entries[i].getAttribute(StorageNames.ID).getValue());
       
   290                 }
       
   291             }
       
   292             return uids;
       
   293         }
       
   294         catch (Throwable t)
       
   295         {
       
   296             InstallerException.internalError
       
   297             ("Error while getting application uids", t);
       
   298         }
       
   299         return null;
       
   300     }
       
   301 
       
   302     /**
       
   303      * Reads suite info from JavaStorage. Retrieves info basing
       
   304      * on uid field in the given SuiteInfo. If uid field is not present,
       
   305      * then info is fetched using Name and Vendor fields.
       
   306      * If matching suite is not found from storage, returns false.
       
   307      */
       
   308     public boolean readSuiteInfo(SuiteInfo aSuiteInfo)
       
   309     {
       
   310         try
       
   311         {
       
   312             checkSession();
       
   313             if (aSuiteInfo == null)
       
   314             {
       
   315                 return false;
       
   316             }
       
   317             boolean result = false;
       
   318             if (aSuiteInfo.getUid() == null)
       
   319             {
       
   320                 // Fetch suite info basing on name and vendor.
       
   321                 if (aSuiteInfo.getName() == null ||
       
   322                         aSuiteInfo.getVendor() == null)
       
   323                 {
       
   324                     Log.logError
       
   325                     ("StorageHandler.readSuiteInfo: uid or name " +
       
   326                      "and vendor not found from SuiteInfo");
       
   327                     return result;
       
   328                 }
       
   329                 StorageEntry query = new StorageEntry();
       
   330                 query.addAttribute(new StorageAttribute
       
   331                                    (StorageNames.PACKAGE_NAME,
       
   332                                     aSuiteInfo.getName()));
       
   333                 query.addAttribute(new StorageAttribute
       
   334                                    (StorageNames.VENDOR,
       
   335                                     aSuiteInfo.getVendor()));
       
   336                 query.addAttribute(new StorageAttribute(StorageNames.ID, ""));
       
   337                 StorageEntry[] entries = iSession.search(
       
   338                                              StorageNames.APPLICATION_PACKAGE_TABLE, query);
       
   339                 if (entries != null && entries.length > 0)
       
   340                 {
       
   341                     // Found matching suite.
       
   342                     aSuiteInfo.setUid(PlatformUid.createUid
       
   343                                       (entries[0].getAttribute(
       
   344                                            StorageNames.ID).getValue()));
       
   345                 }
       
   346             }
       
   347             if (aSuiteInfo.getUid() != null)
       
   348             {
       
   349                 // Fetch suite info basing on uid.
       
   350                 result = readSuiteInfoByUid(aSuiteInfo);
       
   351             }
       
   352             return result;
       
   353         }
       
   354         catch (Throwable t)
       
   355         {
       
   356             InstallerException.internalError
       
   357             ("Error while reading suite info", t);
       
   358         }
       
   359         return false;
       
   360     }
       
   361 
       
   362     /**
       
   363      * Writes suite info to JavaStorage.
       
   364      */
       
   365     public void writeSuiteInfo(SuiteInfo aSuiteInfo)
       
   366     {
       
   367         try
       
   368         {
       
   369             checkSession();
       
   370             checkTransaction();
       
   371             // Write StorageNames.APPLICATION_PACKAGE_TABLE table.
       
   372             StorageEntry entry = new StorageEntry();
       
   373             entry.addAttribute
       
   374             (new StorageAttribute
       
   375              (StorageNames.ID, aSuiteInfo.getUid().getStringValue()));
       
   376             entry.addAttribute
       
   377             (new StorageAttribute
       
   378              (StorageNames.PACKAGE_NAME, aSuiteInfo.getName()));
       
   379             entry.addAttribute
       
   380             (new StorageAttribute
       
   381              (StorageNames.VENDOR, aSuiteInfo.getVendor()));
       
   382             entry.addAttribute
       
   383             (new StorageAttribute
       
   384              (StorageNames.VERSION, aSuiteInfo.getVersion().toString()));
       
   385             entry.addAttribute
       
   386             (new StorageAttribute
       
   387              (StorageNames.ROOT_PATH, aSuiteInfo.getRootDir()));
       
   388             entry.addAttribute
       
   389             (new StorageAttribute
       
   390              (StorageNames.MEDIA_ID, Integer.toString(aSuiteInfo.getMediaId()),
       
   391               StorageAttribute.INT_TYPE));
       
   392             entry.addAttribute
       
   393             (new StorageAttribute
       
   394              (StorageNames.INITIAL_SIZE, Integer.toString(aSuiteInfo.getInitialSize()),
       
   395               StorageAttribute.INT_TYPE));
       
   396             entry.addAttribute
       
   397             (new StorageAttribute
       
   398              (StorageNames.JAD_PATH, aSuiteInfo.getJadPath()));
       
   399             entry.addAttribute
       
   400             (new StorageAttribute
       
   401              (StorageNames.JAR_PATH, aSuiteInfo.getJarPath()));
       
   402             entry.addAttribute
       
   403             (new StorageAttribute
       
   404              (StorageNames.JAD_URL, aSuiteInfo.getJadUrl()));
       
   405             entry.addAttribute
       
   406             (new StorageAttribute
       
   407              (StorageNames.JAR_URL, aSuiteInfo.getJarUrl()));
       
   408             entry.addAttribute
       
   409             (new StorageAttribute
       
   410              (StorageNames.ACCESS_POINT, aSuiteInfo.getAccessPoint()));
       
   411             entry.addAttribute
       
   412             (new StorageAttribute
       
   413              (StorageNames.CONTENT_INFO, Integer.toString(aSuiteInfo.getContentInfo()),
       
   414               StorageAttribute.INT_TYPE));
       
   415             entry.addAttribute
       
   416             (new StorageAttribute
       
   417              (StorageNames.CONTENT_ID, aSuiteInfo.getContentId()));
       
   418             iSession.write(StorageNames.APPLICATION_PACKAGE_TABLE, entry);
       
   419             // Write StorageNames.APPLICATION_PACKAGE_ATTRIBUTES_TABLE table.
       
   420             writeAttributes(aSuiteInfo.getUid(), aSuiteInfo.getAttributes());
       
   421             // Write StorageNames.APPLICATION_TABLE table.
       
   422             Vector apps = aSuiteInfo.getApplications();
       
   423             if (apps != null)
       
   424             {
       
   425                 for (int i = 0; i < apps.size(); i++)
       
   426                 {
       
   427                     writeAppInfo(aSuiteInfo.getUid(),
       
   428                                  (ApplicationInfo)apps.elementAt(i));
       
   429                 }
       
   430             }
       
   431             // Update StorageNames.MIDP_PACKAGE_TABLE table.
       
   432             // This table is shared with security framework
       
   433             // so we must have a special handling for it.
       
   434             // Create a new entry to be inserted or updated.
       
   435             entry = new StorageEntry();
       
   436             entry.addAttribute
       
   437             (new StorageAttribute
       
   438              (StorageNames.ID, aSuiteInfo.getUid().getStringValue()));
       
   439             entry.addAttribute
       
   440             (new StorageAttribute
       
   441              (StorageNames.ON_SCREEN_KEYPAD,
       
   442               Integer.toString(aSuiteInfo.getOnScreenKeypad()),
       
   443               StorageAttribute.INT_TYPE));
       
   444             // Check if an entry already exists.
       
   445             StorageEntry matchEntry = new StorageEntry();
       
   446             matchEntry.addAttribute(new StorageAttribute(StorageNames.ID,
       
   447                                     aSuiteInfo.getUid().getStringValue()));
       
   448             StorageEntry[] entries = iSession.search(
       
   449                                          StorageNames.MIDP_PACKAGE_TABLE, matchEntry);
       
   450             if (entries != null && entries.length > 0)
       
   451             {
       
   452                 // Entry exists, update it.
       
   453                 iSession.update(StorageNames.MIDP_PACKAGE_TABLE, entry, matchEntry);
       
   454             }
       
   455             else
       
   456             {
       
   457                 // Entry does not exist, create it.
       
   458                 iSession.write(StorageNames.MIDP_PACKAGE_TABLE, entry);
       
   459             }
       
   460             // Update StorageNames.PREINSTALL_TABLE table.
       
   461             writePreinstallState(aSuiteInfo);
       
   462         }
       
   463         catch (Throwable t)
       
   464         {
       
   465             InstallerException.internalError
       
   466             ("Error while writing suite info", t);
       
   467         }
       
   468     }
       
   469 
       
   470     /**
       
   471      * Updates changed parts of suite info to JavaStorage.
       
   472      */
       
   473     public void updateSuiteInfo(SuiteInfo aOldSuiteInfo, SuiteInfo aNewSuiteInfo)
       
   474     {
       
   475         try
       
   476         {
       
   477             checkSession();
       
   478             checkTransaction();
       
   479             removeSuiteInfo(aOldSuiteInfo, true);
       
   480             writeSuiteInfo(aNewSuiteInfo);
       
   481         }
       
   482         catch (Throwable t)
       
   483         {
       
   484             InstallerException.internalError
       
   485             ("Error while updating suite info", t);
       
   486         }
       
   487     }
       
   488 
       
   489     /**
       
   490      * Removes info from JavaStorage for given suite uid.
       
   491      */
       
   492     public void removeSuiteInfo(SuiteInfo aSuiteInfo)
       
   493     {
       
   494         try
       
   495         {
       
   496             removeSuiteInfo(aSuiteInfo, false);
       
   497         }
       
   498         catch (Throwable t)
       
   499         {
       
   500             InstallerException.internalError
       
   501             ("Error while removing suite info", t);
       
   502         }
       
   503     }
       
   504 
       
   505     /**
       
   506      * Allocates a free uid which is not in use in storage.
       
   507      *
       
   508      * @param aPreviousUid if null allocates a random uid,
       
   509      * if not null allocates next free uid
       
   510      * @return a free uid, or null if uid cannot be allocated
       
   511      */
       
   512     public Uid allocateUid(Uid aPreviousUid)
       
   513     {
       
   514         try
       
   515         {
       
   516             checkSession();
       
   517             Uid uid = PlatformUid.generateUid(aPreviousUid, null);
       
   518             if (uidInUse(uid))
       
   519             {
       
   520                 Uid startUid = uid;
       
   521                 do
       
   522                 {
       
   523                     uid = PlatformUid.generateUid(uid, null);
       
   524                     if (uid.equals(startUid))
       
   525                     {
       
   526                         InstallerException.internalError
       
   527                         ("No more free uids.");
       
   528                     }
       
   529                 }
       
   530                 while (uidInUse(uid));
       
   531             }
       
   532             return uid;
       
   533         }
       
   534         catch (Throwable t)
       
   535         {
       
   536             InstallerException.internalError
       
   537             ("Error while allocating uid", t);
       
   538         }
       
   539         return null;
       
   540     }
       
   541 
       
   542     /**
       
   543      * Allocates a free uid which is not in use in storage.
       
   544      *
       
   545      * @param aUidSeed seed used for allocating uid
       
   546      * @return a free uid, or null if uid cannot be allocated
       
   547      */
       
   548     public Uid allocateUid(String aUidSeed)
       
   549     {
       
   550         Uid uid = PlatformUid.generateUid(null, aUidSeed);
       
   551         if (uidInUse(uid))
       
   552         {
       
   553             uid = allocateUid(uid);
       
   554         }
       
   555         return uid;
       
   556     }
       
   557 
       
   558     /**
       
   559      * Removes all data from all JavaStorage tables.
       
   560      * @return true if removal was successful, false if removal failed.
       
   561      * @throws StorageException if JavaStorage throws it.
       
   562      */
       
   563     public static boolean removeAllData()
       
   564     {
       
   565         boolean result = true;
       
   566         // Remove all data from JavaStorage tables.
       
   567         String[] tableNames =
       
   568         {
       
   569             StorageNames.APPLICATION_PACKAGE_TABLE,
       
   570             StorageNames.APPLICATION_TABLE,
       
   571             StorageNames.APPLICATION_PACKAGE_ATTRIBUTES_TABLE,
       
   572             StorageNames.MIDP_PACKAGE_TABLE,
       
   573             StorageNames.MIDP_PERMISSIONS_TABLE,
       
   574             StorageNames.MIDP_FUNC_GRP_SETTINGS_TABLE,
       
   575             StorageNames.PUSH_REGISTRATIONS_TABLE,
       
   576             StorageNames.ALARM_REGISTRATIONS_TABLE,
       
   577             StorageNames.RUNTIME_SETTINGS_TABLE,
       
   578             StorageNames.PREINSTALL_TABLE,
       
   579         };
       
   580         StorageSession session = StorageFactory.createSession();
       
   581         session.open();
       
   582         session.startTransaction();
       
   583         for (int i = 0; i < tableNames.length; i++)
       
   584         {
       
   585             if (session.remove(tableNames[i], new StorageEntry()) == -1)
       
   586             {
       
   587                 Log.logError("Removing data from JavaStorage table " +
       
   588                              tableNames[i] + " failed");
       
   589                 result = false;
       
   590             }
       
   591             else
       
   592             {
       
   593                 Log.log("Removed data from JavaStorage table " + tableNames[i]);
       
   594             }
       
   595         }
       
   596         session.commitTransaction();
       
   597         session.close();
       
   598         session.destroySession();
       
   599         // Remove all data from JavaOtaStorage tables.
       
   600         String tableName = StorageNames.OTA_STATUS_TABLE;
       
   601         session = StorageFactory.createSession();
       
   602         session.open(StorageNames.JAVA_OTA_DATABASE_NAME);
       
   603         if (session.remove(tableName, new StorageEntry()) == -1)
       
   604         {
       
   605             Log.logError("Removing data from JavaOtaStorage table " +
       
   606                          tableName + " failed");
       
   607             result = false;
       
   608         }
       
   609         else
       
   610         {
       
   611             Log.log("Removed data from JavaOtaStorage table " + tableName);
       
   612         }
       
   613         session.close();
       
   614         session.destroySession();
       
   615         return result;
       
   616     }
       
   617 
       
   618     /**
       
   619      * Returns storage attribute value from given entry, or null
       
   620      * if attribute does not exist.
       
   621      */
       
   622     static String getAttributeValue(StorageEntry aEntry, String aName)
       
   623     {
       
   624         if (aEntry == null)
       
   625         {
       
   626             return null;
       
   627         }
       
   628         StorageAttribute attr = aEntry.getAttribute(aName);
       
   629         if (attr != null)
       
   630         {
       
   631             return attr.getValue();
       
   632         }
       
   633         return null;
       
   634     }
       
   635 
       
   636     /**
       
   637      * Returns true if given uid is already in use in storage.
       
   638      */
       
   639     private boolean uidInUse(Uid aUid)
       
   640     {
       
   641         checkSession();
       
   642         StorageEntry query = new StorageEntry();
       
   643         query.addAttribute(new StorageAttribute(
       
   644                                StorageNames.ID, aUid.getStringValue()));
       
   645         // Check if aUid is a suite uid.
       
   646         StorageEntry[] entries = iSession.search(
       
   647                                      StorageNames.APPLICATION_PACKAGE_TABLE, query);
       
   648         if (entries != null && entries.length > 0)
       
   649         {
       
   650             return true;
       
   651         }
       
   652         // Check if aUid is an application uid.
       
   653         entries = iSession.search(StorageNames.APPLICATION_TABLE, query);
       
   654         if (entries != null && entries.length > 0)
       
   655         {
       
   656             return true;
       
   657         }
       
   658         return false;
       
   659     }
       
   660 
       
   661     /**
       
   662      * Reads suite info from JavaStorage. Retrieves info basing
       
   663      * on uid field in the given SuiteInfo.
       
   664      * If matching suite is not found from storage, returns false.
       
   665      */
       
   666     private boolean readSuiteInfoByUid(SuiteInfo aSuiteInfo)
       
   667     {
       
   668         if (aSuiteInfo == null)
       
   669         {
       
   670             return false;
       
   671         }
       
   672         boolean result = false;
       
   673         // Read StorageNames.APPLICATION_PACKAGE_TABLE table.
       
   674         StorageEntry query = new StorageEntry();
       
   675         query.addAttribute(new StorageAttribute(StorageNames.ID,
       
   676                                                 aSuiteInfo.getUid().getStringValue()));
       
   677         StorageEntry[] entries = iSession.search(
       
   678                                      StorageNames.APPLICATION_PACKAGE_TABLE, query);
       
   679         if (entries != null && entries.length > 0)
       
   680         {
       
   681             result = true;
       
   682             // Fill suite info.
       
   683             StorageEntry entry = entries[0];
       
   684             aSuiteInfo.setName(getAttributeValue(entry, StorageNames.PACKAGE_NAME));
       
   685             aSuiteInfo.setVendor(getAttributeValue(entry, StorageNames.VENDOR));
       
   686             aSuiteInfo.setVersion(Version.getVersion(
       
   687                                       getAttributeValue(entry, StorageNames.VERSION)));
       
   688             aSuiteInfo.setRootDir(getAttributeValue(entry, StorageNames.ROOT_PATH));
       
   689             aSuiteInfo.setMediaId(Integer.parseInt(
       
   690                                       getAttributeValue(entry, StorageNames.MEDIA_ID)));
       
   691             aSuiteInfo.setInitialSize(Integer.parseInt(
       
   692                                           getAttributeValue(entry, StorageNames.INITIAL_SIZE)));
       
   693             aSuiteInfo.setJadPath(getAttributeValue(entry, StorageNames.JAD_PATH));
       
   694             aSuiteInfo.setJarPath(getAttributeValue(entry, StorageNames.JAR_PATH));
       
   695             aSuiteInfo.setJadUrl(getAttributeValue(entry, StorageNames.JAD_URL));
       
   696             aSuiteInfo.setJarUrl(getAttributeValue(entry, StorageNames.JAR_URL));
       
   697             aSuiteInfo.setAccessPoint(getAttributeValue(entry, StorageNames.ACCESS_POINT));
       
   698             aSuiteInfo.setContentInfo(Integer.parseInt(
       
   699                                           getAttributeValue(entry, StorageNames.CONTENT_INFO)));
       
   700             aSuiteInfo.setContentId(getAttributeValue(entry, StorageNames.CONTENT_ID));
       
   701             // Read attributes.
       
   702             aSuiteInfo.setAttributes(readAttributes(aSuiteInfo.getUid()));
       
   703             // Check from attributes if suite is trusted.
       
   704             // This check does not work if the MIDlet-Jar-RSA-SHA1
       
   705             // attribute is specified in Manifest for untrusted
       
   706             // application: in upgrade the existing application
       
   707             // is assumed to be trusted! Trust info must be initialized
       
   708             // from Security framework after SuiteInfo has been read.
       
   709             if (aSuiteInfo.getAttribute("MIDlet-Jar-RSA-SHA1") != null)
       
   710             {
       
   711                 aSuiteInfo.setTrusted(true);
       
   712             }
       
   713             // Read application uids.
       
   714             Uid[] appUids = getAppUids(aSuiteInfo.getUid());
       
   715             if (appUids != null)
       
   716             {
       
   717                 for (int i = 0; i < appUids.length; i++)
       
   718                 {
       
   719                     ApplicationInfo appInfo = readAppInfo(appUids[i]);
       
   720                     aSuiteInfo.addApplication(appInfo);
       
   721                 }
       
   722             }
       
   723             sortApps(aSuiteInfo);
       
   724         }
       
   725 
       
   726         if (result)
       
   727         {
       
   728             // Read StorageNames.MIDP_PACKAGE_TABLE table.
       
   729             result = false;
       
   730             query = new StorageEntry();
       
   731             query.addAttribute(new StorageAttribute(StorageNames.ID,
       
   732                                                     aSuiteInfo.getUid().getStringValue()));
       
   733             query.addAttribute(new StorageAttribute(
       
   734                                    StorageNames.ON_SCREEN_KEYPAD, ""));
       
   735             entries = iSession.search(StorageNames.MIDP_PACKAGE_TABLE, query);
       
   736             if (entries != null && entries.length > 0)
       
   737             {
       
   738                 result = true;
       
   739                 // Fill suite info.
       
   740                 StorageEntry entry = entries[0];
       
   741                 aSuiteInfo.setOnScreenKeypad(Integer.parseInt(
       
   742                                                  getAttributeValue(entry, StorageNames.ON_SCREEN_KEYPAD)));
       
   743             }
       
   744             else
       
   745             {
       
   746                 Log.logError("Reading " + StorageNames.MIDP_PACKAGE_TABLE +
       
   747                              " table failed, no entries found");
       
   748             }
       
   749         }
       
   750 
       
   751         if (result)
       
   752         {
       
   753             // Read StorageNames.PREINSTALL_TABLE table.
       
   754             //result = false;
       
   755             aSuiteInfo.iPreinstallState = readPreinstallState(aSuiteInfo);
       
   756             if (aSuiteInfo.iPreinstallState >= 0)
       
   757             {
       
   758                 result = true;
       
   759             }
       
   760             else
       
   761             {
       
   762                 Log.logWarning("Reading " + StorageNames.PREINSTALL_TABLE +
       
   763                                " table failed, no entries found");
       
   764             }
       
   765         }
       
   766 
       
   767         return result;
       
   768     }
       
   769 
       
   770     /**
       
   771      * Reads suite attributes from JavaStorage. Retrieves info basing
       
   772      * on given suite uid.
       
   773      * If matching suite is not found from storage, returns null.
       
   774      */
       
   775     private Hashtable readAttributes(Uid aUid)
       
   776     {
       
   777         if (aUid == null)
       
   778         {
       
   779             return null;
       
   780         }
       
   781         Hashtable attrs = null;
       
   782         StorageEntry query = new StorageEntry();
       
   783         query.addAttribute(new StorageAttribute(
       
   784                                StorageNames.ID, aUid.getStringValue()));
       
   785         StorageEntry[] entries = iSession.search(
       
   786                                      StorageNames.APPLICATION_PACKAGE_ATTRIBUTES_TABLE, query);
       
   787         if (entries != null)
       
   788         {
       
   789             attrs = new Hashtable();
       
   790             for (int i = 0; i < entries.length; i++)
       
   791             {
       
   792                 StorageEntry entry = entries[i];
       
   793                 String name = getAttributeValue(entry, StorageNames.NAME);
       
   794                 String value = getAttributeValue(entry, StorageNames.VALUE);
       
   795                 String trustedStr = getAttributeValue(entry, StorageNames.TRUSTED);
       
   796                 boolean trusted = Integer.parseInt(trustedStr) > 0;
       
   797                 if (value == null)
       
   798                 {
       
   799                     Log.logWarning("Attribute " + name + " has empty value");
       
   800                     value = "";
       
   801                 }
       
   802                 attrs.put(name, new Attribute(name, value, trusted));
       
   803             }
       
   804         }
       
   805         return attrs;
       
   806     }
       
   807 
       
   808     /**
       
   809      * Writes suite attributes to JavaStorage.
       
   810      */
       
   811     private void writeAttributes(Uid aUid, Hashtable aAttrs)
       
   812     {
       
   813         if (aUid == null || aAttrs == null)
       
   814         {
       
   815             return;
       
   816         }
       
   817         StorageEntry entry = null;
       
   818         Enumeration e = aAttrs.elements();
       
   819         while (e.hasMoreElements())
       
   820         {
       
   821             Attribute attr = (Attribute)e.nextElement();
       
   822             entry = new StorageEntry();
       
   823             entry.addAttribute(new StorageAttribute(
       
   824                                    StorageNames.ID, aUid.getStringValue()));
       
   825             entry.addAttribute(new StorageAttribute(
       
   826                                    StorageNames.NAME, attr.getName()));
       
   827             entry.addAttribute(new StorageAttribute(
       
   828                                    StorageNames.VALUE, attr.getValue()));
       
   829             entry.addAttribute(new StorageAttribute(
       
   830                                    StorageNames.TRUSTED, (attr.isTrusted()? "1": "0"),
       
   831                                    StorageAttribute.INT_TYPE));
       
   832             iSession.write(StorageNames.APPLICATION_PACKAGE_ATTRIBUTES_TABLE, entry);
       
   833         }
       
   834     }
       
   835 
       
   836     /**
       
   837      * Reads application info from JavaStorage. Retrieves info basing
       
   838      * on given application uid.
       
   839      * If matching application is not found from storage, returns null.
       
   840      */
       
   841     private ApplicationInfo readAppInfo(Uid aUid)
       
   842     {
       
   843         if (aUid == null)
       
   844         {
       
   845             return null;
       
   846         }
       
   847         ApplicationInfo appInfo = null;
       
   848         StorageEntry query = new StorageEntry();
       
   849         query.addAttribute(new StorageAttribute(
       
   850                                StorageNames.ID, aUid.getStringValue()));
       
   851         StorageEntry[] entries = iSession.search(
       
   852                                      StorageNames.APPLICATION_TABLE, query);
       
   853         if (entries != null)
       
   854         {
       
   855             for (int i = 0; i < entries.length; i++)
       
   856             {
       
   857                 StorageEntry entry = entries[i];
       
   858                 String autoStartStr = getAttributeValue(
       
   859                                           entry, StorageNames.AUTORUN);
       
   860                 int autoStart = Integer.parseInt(autoStartStr);
       
   861                 appInfo = new ApplicationInfo(aUid,
       
   862                                               getAttributeValue(entry, StorageNames.NAME),
       
   863                                               getAttributeValue(entry, StorageNames.MAIN_CLASS),
       
   864                                               autoStart);
       
   865             }
       
   866         }
       
   867         return appInfo;
       
   868     }
       
   869 
       
   870     /**
       
   871      * Writes application info to JavaStorage.
       
   872      */
       
   873     private void writeAppInfo(Uid aUid, ApplicationInfo aAppInfo)
       
   874     {
       
   875         if (aUid == null || aAppInfo == null)
       
   876         {
       
   877             return;
       
   878         }
       
   879         StorageEntry entry = new StorageEntry();
       
   880         entry.addAttribute(new StorageAttribute(
       
   881                                StorageNames.ID, aAppInfo.getUid().getStringValue()));
       
   882         entry.addAttribute(new StorageAttribute(
       
   883                                StorageNames.PACKAGE_ID, aUid.getStringValue()));
       
   884         entry.addAttribute(new StorageAttribute(
       
   885                                StorageNames.NAME, aAppInfo.getName()));
       
   886         entry.addAttribute(new StorageAttribute(
       
   887                                StorageNames.MAIN_CLASS, aAppInfo.getMainClass()));
       
   888         entry.addAttribute(new StorageAttribute(
       
   889                                StorageNames.AUTORUN, Integer.toString(aAppInfo.getAutoStart()),
       
   890                                StorageAttribute.INT_TYPE));
       
   891         iSession.write(StorageNames.APPLICATION_TABLE, entry);
       
   892     }
       
   893 
       
   894     /**
       
   895      * Removes info from JavaStorage for given suite uid.
       
   896      */
       
   897     private void removeSuiteInfo(SuiteInfo aSuiteInfo, boolean aUpdate)
       
   898     {
       
   899         Uid uid = aSuiteInfo.getUid();
       
   900         checkSession();
       
   901         checkTransaction();
       
   902         iSession.remove(StorageNames.APPLICATION_PACKAGE_TABLE, uid);
       
   903         iSession.remove(StorageNames.APPLICATION_PACKAGE_ATTRIBUTES_TABLE, uid);
       
   904 
       
   905         // StorageNames.MIDP_PACKAGE_TABLE table is removed when
       
   906         // AuthenticationModule.removeSecurityData()
       
   907         // is called in RemoveSecurityData step,
       
   908         // so do not remove it here.
       
   909         // If StorageNames.MIDP_PACKAGE_TABLE was removed here,
       
   910         // it would cause security error in update.
       
   911 
       
   912         // Remove data from StorageNames.APPLICATION_TABLE table.
       
   913         Uid[] appUids = getAppUids(uid);
       
   914         if (appUids != null)
       
   915         {
       
   916             for (int i = 0; i < appUids.length; i++)
       
   917             {
       
   918                 iSession.remove(StorageNames.APPLICATION_TABLE, appUids[i]);
       
   919             }
       
   920         }
       
   921         if (aUpdate)
       
   922         {
       
   923             // User or Preinstaller is making an update,
       
   924             // do not change preinstall state.
       
   925         }
       
   926         else
       
   927         {
       
   928             // Not an update ==> user is making uninstallation.
       
   929             int oldPreinstallState = readPreinstallState(aSuiteInfo);
       
   930             if (oldPreinstallState == aSuiteInfo.STATE_PREINSTALLED)
       
   931             {
       
   932                 // User is uninstalling a preinstalled application,
       
   933                 // set preinstall state to STATE_NO_PREINSTALL.
       
   934                 setNoPreinstallState(aSuiteInfo);
       
   935             }
       
   936             else if (oldPreinstallState == aSuiteInfo.STATE_INSTALLED)
       
   937             {
       
   938                 // Remove existing data from StorageNames.PREINSTALL_TABLE table.
       
   939                 removePreinstallState(aSuiteInfo);
       
   940             }
       
   941         }
       
   942     }
       
   943 
       
   944     /**
       
   945      * Reads preinstall state from INSTALL_STATE column
       
   946      * value from StorageNames.PREINSTALL_TABLE table.
       
   947      * If INSTALL_STATE value is not found, returns -1.
       
   948      */
       
   949     private int readPreinstallState(SuiteInfo aSuiteInfo)
       
   950     {
       
   951         int result = -1;
       
   952         // Match preinstall state using name and vendor.
       
   953         StorageEntry query = new StorageEntry();
       
   954         query.addAttribute
       
   955         (new StorageAttribute
       
   956          (StorageNames.NAME, aSuiteInfo.getName()));
       
   957         query.addAttribute
       
   958         (new StorageAttribute
       
   959          (StorageNames.VENDOR, aSuiteInfo.getVendor()));
       
   960         query.addAttribute(new StorageAttribute(
       
   961                                StorageNames.INSTALL_STATE, ""));
       
   962         StorageEntry[] entries = iSession.search(
       
   963                                      StorageNames.PREINSTALL_TABLE, query);
       
   964         if (entries != null && entries.length > 0)
       
   965         {
       
   966             // Fill suite info.
       
   967             StorageEntry entry = entries[0];
       
   968             result = Integer.parseInt
       
   969                      (getAttributeValue(entry, StorageNames.INSTALL_STATE));
       
   970         }
       
   971         return result;
       
   972     }
       
   973 
       
   974     /**
       
   975      * Writes preinstall state to StorageNames.PREINSTALL_TABLE table.
       
   976      */
       
   977     private void writePreinstallState(SuiteInfo aSuiteInfo)
       
   978     {
       
   979         if (aSuiteInfo == null)
       
   980         {
       
   981             return;
       
   982         }
       
   983 
       
   984         // Before writing new preinstall state we must fetch the old state.
       
   985         int oldPreinstallState = readPreinstallState(aSuiteInfo);
       
   986 
       
   987         // Match preinstall state using name and vendor.
       
   988         StorageEntry matchEntry = new StorageEntry();
       
   989         matchEntry.addAttribute
       
   990         (new StorageAttribute
       
   991          (StorageNames.NAME, aSuiteInfo.getName()));
       
   992         matchEntry.addAttribute
       
   993         (new StorageAttribute
       
   994          (StorageNames.VENDOR, aSuiteInfo.getVendor()));
       
   995 
       
   996         // Create a new entry with name, vendor and version.
       
   997         StorageEntry entry = new StorageEntry();
       
   998         entry.addAttribute
       
   999         (new StorageAttribute
       
  1000          (StorageNames.NAME, aSuiteInfo.getName()));
       
  1001         entry.addAttribute
       
  1002         (new StorageAttribute
       
  1003          (StorageNames.VENDOR, aSuiteInfo.getVendor()));
       
  1004         entry.addAttribute
       
  1005         (new StorageAttribute
       
  1006          (StorageNames.VERSION, aSuiteInfo.getVersion().toString()));
       
  1007 
       
  1008         if (oldPreinstallState >= 0)
       
  1009         {
       
  1010             // Entry exists, update version into it.
       
  1011             if (aSuiteInfo.iPreinstallState == aSuiteInfo.STATE_PREINSTALLED)
       
  1012             {
       
  1013                 // Update preinstall state only if the new state
       
  1014                 // indicates preinstallation.
       
  1015                 entry.addAttribute
       
  1016                 (new StorageAttribute
       
  1017                  (StorageNames.INSTALL_STATE,
       
  1018                   Integer.toString(aSuiteInfo.iPreinstallState),
       
  1019                   StorageAttribute.INT_TYPE));
       
  1020                 Log.log("Setting preinstall state to " +
       
  1021                         aSuiteInfo.iPreinstallState);
       
  1022             }
       
  1023             iSession.update(StorageNames.PREINSTALL_TABLE, entry, matchEntry);
       
  1024         }
       
  1025         else
       
  1026         {
       
  1027             // Entry does not exist, create it with name, vendor,
       
  1028             // version and state.
       
  1029             entry.addAttribute
       
  1030             (new StorageAttribute
       
  1031              (StorageNames.INSTALL_STATE,
       
  1032               Integer.toString(aSuiteInfo.iPreinstallState),
       
  1033               StorageAttribute.INT_TYPE));
       
  1034             Log.log("Setting preinstall state to " +
       
  1035                     aSuiteInfo.iPreinstallState);
       
  1036             iSession.write(StorageNames.PREINSTALL_TABLE, entry);
       
  1037         }
       
  1038     }
       
  1039 
       
  1040     /**
       
  1041      * Updates preinstall state to STATE_NO_PREINSTALL in
       
  1042      * StorageNames.PREINSTALL_TABLE table.
       
  1043      */
       
  1044     private void setNoPreinstallState(SuiteInfo aSuiteInfo)
       
  1045     {
       
  1046         if (aSuiteInfo == null)
       
  1047         {
       
  1048             return;
       
  1049         }
       
  1050 
       
  1051         // Match preinstall state using name and vendor.
       
  1052         StorageEntry matchEntry = new StorageEntry();
       
  1053         matchEntry.addAttribute
       
  1054         (new StorageAttribute
       
  1055          (StorageNames.NAME, aSuiteInfo.getName()));
       
  1056         matchEntry.addAttribute
       
  1057         (new StorageAttribute
       
  1058          (StorageNames.VENDOR, aSuiteInfo.getVendor()));
       
  1059 
       
  1060         // Create a new entry with name, vendor, version and state.
       
  1061         StorageEntry entry = new StorageEntry();
       
  1062         entry.addAttribute
       
  1063         (new StorageAttribute
       
  1064          (StorageNames.NAME, aSuiteInfo.getName()));
       
  1065         entry.addAttribute
       
  1066         (new StorageAttribute
       
  1067          (StorageNames.VENDOR, aSuiteInfo.getVendor()));
       
  1068         entry.addAttribute
       
  1069         (new StorageAttribute
       
  1070          (StorageNames.VERSION, aSuiteInfo.getVersion().toString()));
       
  1071         entry.addAttribute
       
  1072         (new StorageAttribute
       
  1073          (StorageNames.INSTALL_STATE,
       
  1074           Integer.toString(aSuiteInfo.STATE_NO_PREINSTALL),
       
  1075           StorageAttribute.INT_TYPE));
       
  1076 
       
  1077         Log.log("Setting preinstall state to " +
       
  1078                 aSuiteInfo.STATE_NO_PREINSTALL);
       
  1079         iSession.update(StorageNames.PREINSTALL_TABLE, entry, matchEntry);
       
  1080     }
       
  1081 
       
  1082     /**
       
  1083      * Removes preinstall state for given suite from
       
  1084      * preinstall table but only if preinstall state
       
  1085      * in given SuiteInfo is SuiteInfo.STATE_INSTALLED.
       
  1086      */
       
  1087     private void removePreinstallState(SuiteInfo aSuiteInfo)
       
  1088     {
       
  1089         if (aSuiteInfo == null ||
       
  1090                 aSuiteInfo.iPreinstallState != aSuiteInfo.STATE_INSTALLED)
       
  1091         {
       
  1092             return;
       
  1093         }
       
  1094         // Match preinstall state using name and vendor.
       
  1095         StorageEntry matchEntry = new StorageEntry();
       
  1096         matchEntry.addAttribute
       
  1097         (new StorageAttribute
       
  1098          (StorageNames.NAME, aSuiteInfo.getName()));
       
  1099         matchEntry.addAttribute
       
  1100         (new StorageAttribute
       
  1101          (StorageNames.VENDOR, aSuiteInfo.getVendor()));
       
  1102 
       
  1103         Log.log("Removing preinstall state");
       
  1104         iSession.remove(StorageNames.PREINSTALL_TABLE, matchEntry);
       
  1105     }
       
  1106 
       
  1107     /**
       
  1108      * Checks that JavaStorage session exists.
       
  1109      * @throws InstallerException if session does not exist.
       
  1110      */
       
  1111     private void checkSession()
       
  1112     {
       
  1113         if (iSession == null)
       
  1114         {
       
  1115             InstallerException.internalError("Session does not exist.");
       
  1116         }
       
  1117     }
       
  1118 
       
  1119     /**
       
  1120      * Checks that JavaStorage transaction exists.
       
  1121      * @throws InstallerException if transaction does not exist.
       
  1122      */
       
  1123     private void checkTransaction()
       
  1124     {
       
  1125         if (!iTransactionExists)
       
  1126         {
       
  1127             InstallerException.internalError("Transaction does not exist.");
       
  1128         }
       
  1129     }
       
  1130 
       
  1131     /**
       
  1132      * Sort the suite applications by matching application mainclass
       
  1133      * names and classnames in MIDlet-n attributes.
       
  1134      */
       
  1135     private void sortApps(SuiteInfo aSuiteInfo)
       
  1136     {
       
  1137         Vector apps = aSuiteInfo.getApplications();
       
  1138         ApplicationInfo[] sortedApps = new ApplicationInfo[apps.size()];
       
  1139         for (int i = 0; i < apps.size(); i++)
       
  1140         {
       
  1141             ApplicationInfo app = (ApplicationInfo)apps.elementAt(i);
       
  1142             String appMainClass = app.getMainClass();
       
  1143             for (int j = 1; true; j++)
       
  1144             {
       
  1145                 String attrValue = aSuiteInfo.getAttributeValue("MIDlet-" + j);
       
  1146                 if (attrValue == null)
       
  1147                 {
       
  1148                     break;
       
  1149                 }
       
  1150                 String[] tokens = Tokenizer.split(attrValue, ",");
       
  1151                 if (tokens[2].trim().equals(appMainClass))
       
  1152                 {
       
  1153                     while (j < sortedApps.length && sortedApps[j - 1] != null)
       
  1154                     {
       
  1155                         // Increase j in case the same class name is already
       
  1156                         // used by some other application in the same suite.
       
  1157                         j++;
       
  1158                     }
       
  1159                     sortedApps[j-1] = (ApplicationInfo)apps.elementAt(i);
       
  1160                     break;
       
  1161                 }
       
  1162             }
       
  1163         }
       
  1164         aSuiteInfo.setApplications(new Vector());
       
  1165         for (int i = 0; i < sortedApps.length; i++)
       
  1166         {
       
  1167             aSuiteInfo.addApplication(sortedApps[i]);
       
  1168         }
       
  1169     }
       
  1170 }