felix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rickh...@apache.org
Subject svn commit: r1022172 - in /felix/trunk/framework/src/main/java/org/apache/felix/framework: Felix.java cache/BundleArchive.java cache/BundleCache.java
Date Wed, 13 Oct 2010 16:24:08 GMT
Author: rickhall
Date: Wed Oct 13 16:24:07 2010
New Revision: 1022172

URL: http://svn.apache.org/viewvc?rev=1022172&view=rev
Log:
Modify bundle cache to use a single file to record bundle state
if a configuration property is set. (FELIX-2654)

Modified:
    felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java
    felix/trunk/framework/src/main/java/org/apache/felix/framework/cache/BundleArchive.java
    felix/trunk/framework/src/main/java/org/apache/felix/framework/cache/BundleCache.java

Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java?rev=1022172&r1=1022171&r2=1022172&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java Wed Oct 13 16:24:07
2010
@@ -2461,7 +2461,7 @@ public class Felix extends BundleImpl im
                 try
                 {
                     // Add the bundle to the cache.
-                    ba = m_cache.create(id, location, is);
+                    ba = m_cache.create(id, getInitialBundleStartLevel(), location, is);
                 }
                 catch (Exception ex)
                 {
@@ -2577,15 +2577,6 @@ public class Felix extends BundleImpl im
                 }
             }
 
-            // If the bundle is new, then set its start level; existing
-            // bundles already have their start level set.
-            if (isNew)
-            {
-                // This will persistently set the bundle's start level.
-                bundle.setStartLevel(getInitialBundleStartLevel());
-                bundle.setLastModified(System.currentTimeMillis());
-            }
-
             // Acquire global lock.
             boolean locked = acquireGlobalLock();
             if (!locked)

Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/cache/BundleArchive.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/cache/BundleArchive.java?rev=1022172&r1=1022171&r2=1022172&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/cache/BundleArchive.java
(original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/cache/BundleArchive.java
Wed Oct 13 16:24:07 2010
@@ -67,32 +67,38 @@ public class BundleArchive
     public static final transient String REFERENCE_PROTOCOL = "reference:";
     public static final transient String INPUTSTREAM_PROTOCOL = "inputstream:";
 
-    private static final transient String BUNDLE_ID_FILE = "bundle.id";
-    private static final transient String BUNDLE_LOCATION_FILE = "bundle.location";
+    private static final transient String BUNDLE_INFO_FILE = "bundle.info";
     private static final transient String REVISION_LOCATION_FILE = "revision.location";
-    private static final transient String BUNDLE_STATE_FILE = "bundle.state";
-    private static final transient String BUNDLE_START_LEVEL_FILE = "bundle.startlevel";
-    private static final transient String REFRESH_COUNTER_FILE = "refresh.counter";
-    private static final transient String BUNDLE_LASTMODIFIED_FILE = "bundle.lastmodified";
     private static final transient String REVISION_DIRECTORY = "version";
     private static final transient String DATA_DIRECTORY = "data";
-    private static final transient String ACTIVE_STATE = "active";
-    private static final transient String STARTING_STATE = "starting";
-    private static final transient String INSTALLED_STATE = "installed";
-    private static final transient String UNINSTALLED_STATE = "uninstalled";
 
     private final Logger m_logger;
     private final Map m_configMap;
-    private long m_id = -1;
     private final File m_archiveRootDir;
+    private final boolean m_isSingleBundleFile;
+
+    private long m_id = -1;
     private String m_originalLocation = null;
     private int m_persistentState = -1;
     private int m_startLevel = -1;
     private long m_lastModified = -1;
-    private BundleRevision[] m_revisions = null;
 
+    /**
+     * The refresh count field is used when generating the bundle revision
+     * directory name where native libraries are extracted. This is necessary
+     * because Sun's JVM requires a one-to-one mapping between native libraries
+     * and class loaders where the native library is uniquely identified by its
+     * absolute path in the file system. This constraint creates a problem when
+     * a bundle is refreshed, because it gets a new class loader. Using the
+     * refresh counter to generate the name of the bundle revision directory
+     * resolves this problem because each time bundle is refresh, the native
+     * library will have a unique name. As a result of the unique name, the JVM
+     * will then reload the native library without a problem.
+    **/
     private long m_refreshCount = -1;
 
+    private BundleRevision[] m_revisions = null;
+
     /**
      * <p>
      * This constructor is only used by the system bundle archive implementation
@@ -104,6 +110,9 @@ public class BundleArchive
         m_logger = null;
         m_configMap = null;
         m_archiveRootDir = null;
+
+        String s = (String) m_configMap.get(BundleCache.CACHE_SINGLEBUNDLEFILE_PROP);
+        m_isSingleBundleFile = (s == null) || (!s.equalsIgnoreCase("true")) ? false : true;
     }
 
     /**
@@ -124,7 +133,7 @@ public class BundleArchive
      * @throws Exception if any error occurs.
     **/
     public BundleArchive(Logger logger, Map configMap, File archiveRootDir, long id,
-        String location, InputStream is) throws Exception
+        int startLevel, String location, InputStream is) throws Exception
     {
         m_logger = logger;
         m_configMap = configMap;
@@ -136,6 +145,13 @@ public class BundleArchive
                 "Bundle ID cannot be less than or equal to zero.");
         }
         m_originalLocation = location;
+        m_persistentState = Bundle.INSTALLED;
+        m_startLevel = startLevel;
+        m_lastModified = System.currentTimeMillis();
+        m_refreshCount = 0;
+
+        String s = (String) m_configMap.get(BundleCache.CACHE_SINGLEBUNDLEFILE_PROP);
+        m_isSingleBundleFile = (s == null) || (!s.equalsIgnoreCase("true")) ? false : true;
 
         // Save state.
         initialize();
@@ -163,6 +179,14 @@ public class BundleArchive
         m_configMap = configMap;
         m_archiveRootDir = archiveRootDir;
 
+        String s = (String) m_configMap.get(BundleCache.CACHE_SINGLEBUNDLEFILE_PROP);
+        m_isSingleBundleFile = (s == null) || (!s.equalsIgnoreCase("true")) ? false : true;
+
+        if (m_isSingleBundleFile)
+        {
+            readBundleInfo();
+        }
+
         // Add a revision for each one that already exists in the file
         // system. The file system might contain more than one revision
         // if the bundle was updated in a previous session, but the
@@ -214,34 +238,8 @@ public class BundleArchive
     {
         if (m_id <= 0)
         {
-            // Read bundle location.
-            InputStream is = null;
-            BufferedReader br = null;
-            try
-            {
-                is = BundleCache.getSecureAction()
-                    .getFileInputStream(new File(m_archiveRootDir, BUNDLE_ID_FILE));
-                br = new BufferedReader(new InputStreamReader(is));
-                m_id = Long.parseLong(br.readLine());
-            }
-            catch (FileNotFoundException ex)
-            {
-                // HACK: Get the bundle identifier from the archive root directory
-                // name, which is of the form "bundle<id>" where <id> is the
bundle
-                // identifier numbers. This is a hack to deal with old archives that
-                // did not save their bundle identifier, but instead had it passed
-                // into them. Eventually, this can be removed.
-                m_id = Long.parseLong(
-                    m_archiveRootDir.getName().substring(
-                        BundleCache.BUNDLE_DIR_PREFIX.length()));
-            }
-            finally
-            {
-                if (br != null) br.close();
-                if (is != null) is.close();
-            }
+            m_id = readId();
         }
-
         return m_id;
     }
 
@@ -256,21 +254,7 @@ public class BundleArchive
     {
         if (m_originalLocation == null)
         {
-            // Read bundle location.
-            InputStream is = null;
-            BufferedReader br = null;
-            try
-            {
-                is = BundleCache.getSecureAction()
-                    .getFileInputStream(new File(m_archiveRootDir, BUNDLE_LOCATION_FILE));
-                br = new BufferedReader(new InputStreamReader(is));
-                m_originalLocation = br.readLine();
-            }
-            finally
-            {
-                if (br != null) br.close();
-                if (is != null) is.close();
-            }
+            m_originalLocation = readLocation();
         }
         return m_originalLocation;
     }
@@ -288,49 +272,7 @@ public class BundleArchive
     {
         if (m_persistentState < 0)
         {
-            // Get bundle state file.
-            File stateFile = new File(m_archiveRootDir, BUNDLE_STATE_FILE);
-
-            // If the state file doesn't exist, then
-            // assume the bundle was installed.
-            if (!BundleCache.getSecureAction().fileExists(stateFile))
-            {
-                m_persistentState = Bundle.INSTALLED;
-            }
-            else
-            {
-                // Read the bundle state.
-                InputStream is = null;
-                BufferedReader br = null;
-                try
-                {
-                    is = BundleCache.getSecureAction()
-                        .getFileInputStream(stateFile);
-                    br = new BufferedReader(new InputStreamReader(is));
-                    String s = br.readLine();
-                    if ((s != null) && s.equals(ACTIVE_STATE))
-                    {
-                        m_persistentState = Bundle.ACTIVE;
-                    }
-                    else if ((s != null) && s.equals(STARTING_STATE))
-                    {
-                        m_persistentState = Bundle.STARTING;
-                    }
-                    else if ((s != null) && s.equals(UNINSTALLED_STATE))
-                    {
-                        m_persistentState = Bundle.UNINSTALLED;
-                    }
-                    else
-                    {
-                        m_persistentState = Bundle.INSTALLED;
-                    }
-                }
-                finally
-                {
-                    if (br != null) br.close();
-                    if (is != null) is.close();
-                }
-            }
+            m_persistentState = readPersistentState();
         }
         return m_persistentState;
     }
@@ -346,46 +288,16 @@ public class BundleArchive
     **/
     public synchronized void setPersistentState(int state) throws Exception
     {
-        // Write the bundle state.
-        OutputStream os = null;
-        BufferedWriter bw = null;
         if (m_persistentState != state)
         {
-            try
-            {
-                os = BundleCache.getSecureAction()
-                    .getFileOutputStream(new File(m_archiveRootDir, BUNDLE_STATE_FILE));
-                bw = new BufferedWriter(new OutputStreamWriter(os));
-                String s = null;
-                switch (state)
-                {
-                    case Bundle.ACTIVE:
-                        s = ACTIVE_STATE;
-                        break;
-                    case Bundle.STARTING:
-                        s = STARTING_STATE;
-                        break;
-                    case Bundle.UNINSTALLED:
-                        s = UNINSTALLED_STATE;
-                        break;
-                    default:
-                        s = INSTALLED_STATE;
-                        break;
-                }
-                bw.write(s, 0, s.length());
-                m_persistentState = state;
-            }
-            catch (IOException ex)
+            m_persistentState = state;
+            if (m_isSingleBundleFile)
             {
-                m_logger.log(
-                    Logger.LOG_ERROR,
-                    getClass().getName() + ": Unable to record state - " + ex);
-                throw ex;
+                writeBundleInfo();
             }
-            finally
+            else
             {
-                if (bw != null) bw.close();
-                if (os != null) os.close();
+                writePersistentState();
             }
         }
     }
@@ -401,33 +313,7 @@ public class BundleArchive
     {
         if (m_startLevel < 0)
         {
-            // Get bundle start level file.
-            File levelFile = new File(m_archiveRootDir, BUNDLE_START_LEVEL_FILE);
-
-            // If the start level file doesn't exist, then
-            // return an error.
-            if (!BundleCache.getSecureAction().fileExists(levelFile))
-            {
-                m_startLevel = -1;
-            }
-            else
-            {
-                // Read the bundle start level.
-                InputStream is = null;
-                BufferedReader br= null;
-                try
-                {
-                    is = BundleCache.getSecureAction()
-                        .getFileInputStream(levelFile);
-                    br = new BufferedReader(new InputStreamReader(is));
-                    m_startLevel = Integer.parseInt(br.readLine());
-                }
-                finally
-                {
-                    if (br != null) br.close();
-                    if (is != null) is.close();
-                }
-            }
+            m_startLevel = readStartLevel();
         }
         return m_startLevel;
     }
@@ -441,29 +327,17 @@ public class BundleArchive
     **/
     public synchronized void setStartLevel(int level) throws Exception
     {
-        // Write the bundle start level.
-        OutputStream os = null;
-        BufferedWriter bw = null;
-        try
+        if (m_startLevel != level)
         {
-            os = BundleCache.getSecureAction()
-                .getFileOutputStream(new File(m_archiveRootDir, BUNDLE_START_LEVEL_FILE));
-            bw = new BufferedWriter(new OutputStreamWriter(os));
-            String s = Integer.toString(level);
-            bw.write(s, 0, s.length());
             m_startLevel = level;
-        }
-        catch (IOException ex)
-        {
-            m_logger.log(
-                Logger.LOG_ERROR,
-                getClass().getName() + ": Unable to record start level - " + ex);
-            throw ex;
-        }
-        finally
-        {
-            if (bw != null) bw.close();
-            if (os != null) os.close();
+            if (m_isSingleBundleFile)
+            {
+                writeBundleInfo();
+            }
+            else
+            {
+                writeStartLevel();
+            }
         }
     }
 
@@ -478,32 +352,7 @@ public class BundleArchive
     {
         if (m_lastModified < 0)
         {
-            // Get bundle last modification time file.
-            File lastModFile = new File(m_archiveRootDir, BUNDLE_LASTMODIFIED_FILE);
-
-            // If the last modification file doesn't exist, then
-            // return an error.
-            if (!BundleCache.getSecureAction().fileExists(lastModFile))
-            {
-                m_lastModified = 0;
-            }
-            else
-            {
-                // Read the bundle start level.
-                InputStream is = null;
-                BufferedReader br= null;
-                try
-                {
-                    is = BundleCache.getSecureAction().getFileInputStream(lastModFile);
-                    br = new BufferedReader(new InputStreamReader(is));
-                    m_lastModified = Long.parseLong(br.readLine());
-                }
-                finally
-                {
-                    if (br != null) br.close();
-                    if (is != null) is.close();
-                }
-            }
+            m_lastModified = readLastModified();
         }
         return m_lastModified;
     }
@@ -520,29 +369,73 @@ public class BundleArchive
     **/
     public synchronized void setLastModified(long lastModified) throws Exception
     {
-        // Write the bundle last modification time.
-        OutputStream os = null;
-        BufferedWriter bw = null;
-        try
+        if (m_lastModified != lastModified)
         {
-            os = BundleCache.getSecureAction()
-                .getFileOutputStream(new File(m_archiveRootDir, BUNDLE_LASTMODIFIED_FILE));
-            bw = new BufferedWriter(new OutputStreamWriter(os));
-            String s = Long.toString(lastModified);
-            bw.write(s, 0, s.length());
             m_lastModified = lastModified;
+            if (m_isSingleBundleFile)
+            {
+                writeBundleInfo();
+            }
+            else
+            {
+                writeLastModified();
+            }
         }
-        catch (IOException ex)
+    }
+
+    /**
+     * This utility method is used to retrieve the current refresh
+     * counter value for the bundle. This value is used when generating
+     * the bundle revision directory name where native libraries are extracted.
+     * This is necessary because Sun's JVM requires a one-to-one mapping
+     * between native libraries and class loaders where the native library
+     * is uniquely identified by its absolute path in the file system. This
+     * constraint creates a problem when a bundle is refreshed, because it
+     * gets a new class loader. Using the refresh counter to generate the name
+     * of the bundle revision directory resolves this problem because each time
+     * bundle is refresh, the native library will have a unique name.
+     * As a result of the unique name, the JVM will then reload the
+     * native library without a problem.
+    **/
+    private long getRefreshCount() throws Exception
+    {
+        // If the refresh counter is not yet initialized, do so now.
+        if (m_refreshCount < 0)
         {
-            m_logger.log(
-                Logger.LOG_ERROR,
-                getClass().getName() + ": Unable to record last modification time - " + ex);
-            throw ex;
+            m_refreshCount = readRefreshCount();
         }
-        finally
+
+        return m_refreshCount;
+    }
+
+    /**
+     * This utility method is used to retrieve the current refresh
+     * counter value for the bundle. This value is used when generating
+     * the bundle revision directory name where native libraries are extracted.
+     * This is necessary because Sun's JVM requires a one-to-one mapping
+     * between native libraries and class loaders where the native library
+     * is uniquely identified by its absolute path in the file system. This
+     * constraint creates a problem when a bundle is refreshed, because it
+     * gets a new class loader. Using the refresh counter to generate the name
+     * of the bundle revision directory resolves this problem because each time
+     * bundle is refresh, the native library will have a unique name.
+     * As a result of the unique name, the JVM will then reload the
+     * native library without a problem.
+    **/
+    private void setRefreshCount(long count)
+        throws Exception
+    {
+        if (m_refreshCount != count)
         {
-            if (bw != null) bw.close();
-            if (os != null) os.close();
+            m_refreshCount = count;
+            if (m_isSingleBundleFile)
+            {
+                writeBundleInfo();
+            }
+            else
+            {
+                writeRefreshCount();
+            }
         }
     }
 
@@ -860,19 +753,17 @@ public class BundleArchive
                 throw new IOException("Unable to create archive directory.");
             }
 
-            // Save id.
-            os = BundleCache.getSecureAction()
-                .getFileOutputStream(new File(m_archiveRootDir, BUNDLE_ID_FILE));
-            bw = new BufferedWriter(new OutputStreamWriter(os));
-            bw.write(Long.toString(m_id), 0, Long.toString(m_id).length());
-            bw.close();
-            os.close();
-
-            // Save location string.
-            os = BundleCache.getSecureAction()
-                .getFileOutputStream(new File(m_archiveRootDir, BUNDLE_LOCATION_FILE));
-            bw = new BufferedWriter(new OutputStreamWriter(os));
-            bw.write(m_originalLocation, 0, m_originalLocation.length());
+            if (m_isSingleBundleFile)
+            {
+                writeBundleInfo();
+            }
+            else
+            {
+                writeId();
+                writeLocation();
+                writePersistentState();
+                writeStartLevel();
+            }
         }
         finally
         {
@@ -1011,96 +902,357 @@ public class BundleArchive
         return result.toString();
     }
 
+    private void readBundleInfo() throws Exception
+    {
+        File infoFile = new File(m_archiveRootDir, BUNDLE_INFO_FILE);
 
-    /**
-     * This utility method is used to retrieve the current refresh
-     * counter value for the bundle. This value is used when generating
-     * the bundle revision directory name where native libraries are extracted.
-     * This is necessary because Sun's JVM requires a one-to-one mapping
-     * between native libraries and class loaders where the native library
-     * is uniquely identified by its absolute path in the file system. This
-     * constraint creates a problem when a bundle is refreshed, because it
-     * gets a new class loader. Using the refresh counter to generate the name
-     * of the bundle revision directory resolves this problem because each time
-     * bundle is refresh, the native library will have a unique name.
-     * As a result of the unique name, the JVM will then reload the
-     * native library without a problem.
-    **/
-    private long getRefreshCount() throws Exception
+        // Read the bundle start level.
+        InputStream is = null;
+        BufferedReader br= null;
+        try
+        {
+            is = BundleCache.getSecureAction()
+                .getFileInputStream(infoFile);
+            br = new BufferedReader(new InputStreamReader(is));
+
+            // Read id.
+            m_id = Long.parseLong(br.readLine());
+            // Read location.
+            m_originalLocation = br.readLine();
+            // Read state.
+            m_persistentState = Integer.parseInt(br.readLine());
+            // Read start level.
+            m_startLevel = Integer.parseInt(br.readLine());
+            // Read last modified.
+            m_lastModified = Long.parseLong(br.readLine());
+            // Read refresh count.
+            m_refreshCount = Long.parseLong(br.readLine());
+        }
+        catch (FileNotFoundException ex)
+        {
+            // If there wasn't an info file, then maybe this is an old-style
+            // bundle cache, so try to read the files individually. We can
+            // delete this eventually.
+            m_id = readId();
+            m_originalLocation = readLocation();
+            m_persistentState = readPersistentState();
+            m_startLevel = readStartLevel();
+            m_lastModified = readLastModified();
+            m_refreshCount = readRefreshCount();
+        }
+        finally
+        {
+            if (br != null) br.close();
+            if (is != null) is.close();
+        }
+    }
+
+    private void writeBundleInfo() throws Exception
     {
-        // If the refresh counter is not yet initialized, do so now.
-        if (m_refreshCount < 0)
+        // Write the bundle start level.
+        OutputStream os = null;
+        BufferedWriter bw = null;
+        try
+        {
+            os = BundleCache.getSecureAction()
+                .getFileOutputStream(new File(m_archiveRootDir, BUNDLE_INFO_FILE));
+            bw = new BufferedWriter(new OutputStreamWriter(os));
+
+            // Write id.
+            String s = Long.toString(m_id);
+            bw.write(s, 0, s.length());
+            bw.newLine();
+            // Write location.
+            s = (m_originalLocation == null) ? "" : m_originalLocation;
+            bw.write(s, 0, s.length());
+            bw.newLine();
+            // Write state.
+            s = Integer.toString(m_persistentState);
+            bw.write(s, 0, s.length());
+            bw.newLine();
+            // Write start level.
+            s = Integer.toString(m_startLevel);
+            bw.write(s, 0, s.length());
+            bw.newLine();
+            // Write last modified.
+            s = Long.toString(m_lastModified);
+            bw.write(s, 0, s.length());
+            bw.newLine();
+            // Write refresh count.
+            s = Long.toString(m_refreshCount);
+            bw.write(s, 0, s.length());
+            bw.newLine();
+        }
+        catch (IOException ex)
+        {
+            m_logger.log(
+                Logger.LOG_ERROR,
+                getClass().getName() + ": Unable to cache bundle info - " + ex);
+            throw ex;
+        }
+        finally
+        {
+            if (bw != null) bw.close();
+            if (os != null) os.close();
+        }
+    }
+
+    //
+    // Deprecated bundle cache format to be deleted eventually.
+    //
+
+    private static final transient String BUNDLE_ID_FILE = "bundle.id";
+    private static final transient String BUNDLE_LOCATION_FILE = "bundle.location";
+    private static final transient String BUNDLE_STATE_FILE = "bundle.state";
+    private static final transient String BUNDLE_START_LEVEL_FILE = "bundle.startlevel";
+    private static final transient String BUNDLE_LASTMODIFIED_FILE = "bundle.lastmodified";
+    private static final transient String REFRESH_COUNTER_FILE = "refresh.counter";
+
+    private void writeId() throws Exception
+    {
+        OutputStream os = BundleCache.getSecureAction()
+            .getFileOutputStream(new File(m_archiveRootDir, BUNDLE_ID_FILE));
+        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
+        bw.write(Long.toString(m_id), 0, Long.toString(m_id).length());
+        bw.close();
+        os.close();
+    }
+
+    private long readId() throws Exception
+    {
+        long id;
+
+        InputStream is = null;
+        BufferedReader br = null;
+        try
+        {
+            is = BundleCache.getSecureAction()
+                .getFileInputStream(new File(m_archiveRootDir, BUNDLE_ID_FILE));
+            br = new BufferedReader(new InputStreamReader(is));
+            id = Long.parseLong(br.readLine());
+        }
+        catch (FileNotFoundException ex)
+        {
+            // HACK: Get the bundle identifier from the archive root directory
+            // name, which is of the form "bundle<id>" where <id> is the bundle
+            // identifier numbers. This is a hack to deal with old archives that
+            // did not save their bundle identifier, but instead had it passed
+            // into them. Eventually, this can be removed.
+            id = Long.parseLong(
+                m_archiveRootDir.getName().substring(
+                    BundleCache.BUNDLE_DIR_PREFIX.length()));
+        }
+        finally
+        {
+            if (br != null) br.close();
+            if (is != null) is.close();
+        }
+
+        return id;
+    }
+
+    private void writeLocation() throws Exception
+    {
+        OutputStream os = BundleCache.getSecureAction()
+            .getFileOutputStream(new File(m_archiveRootDir, BUNDLE_LOCATION_FILE));
+        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
+        bw.write(m_originalLocation, 0, m_originalLocation.length());
+        bw.close();
+        os.close();
+    }
+
+    private String readLocation() throws Exception
+    {
+        InputStream is = null;
+        BufferedReader br = null;
+        try
+        {
+            is = BundleCache.getSecureAction()
+                .getFileInputStream(new File(m_archiveRootDir, BUNDLE_LOCATION_FILE));
+            br = new BufferedReader(new InputStreamReader(is));
+            return br.readLine();
+        }
+        finally
         {
-            // Get refresh counter file.
-            File counterFile = new File(m_archiveRootDir, REFRESH_COUNTER_FILE);
+            if (br != null) br.close();
+            if (is != null) is.close();
+        }
+    }
 
-            // If the refresh counter file doesn't exist, then
-            // assume the counter is at zero.
-            if (!BundleCache.getSecureAction().fileExists(counterFile))
+    private static final transient String ACTIVE_STATE = "active";
+    private static final transient String STARTING_STATE = "starting";
+    private static final transient String INSTALLED_STATE = "installed";
+    private static final transient String UNINSTALLED_STATE = "uninstalled";
+
+    private void writePersistentState() throws Exception
+    {
+        OutputStream os = null;
+        BufferedWriter bw = null;
+        try
+        {
+            os = BundleCache.getSecureAction()
+                .getFileOutputStream(new File(m_archiveRootDir, BUNDLE_STATE_FILE));
+            bw = new BufferedWriter(new OutputStreamWriter(os));
+            String s = null;
+            switch (m_persistentState)
             {
-                m_refreshCount = 0;
+                case Bundle.ACTIVE:
+                    s = ACTIVE_STATE;
+                    break;
+                case Bundle.STARTING:
+                    s = STARTING_STATE;
+                    break;
+                case Bundle.UNINSTALLED:
+                    s = UNINSTALLED_STATE;
+                    break;
+                default:
+                    s = INSTALLED_STATE;
+                    break;
             }
-            else
+            bw.write(s, 0, s.length());
+        }
+        catch (IOException ex)
+        {
+            m_logger.log(
+                Logger.LOG_ERROR,
+                getClass().getName() + ": Unable to record state - " + ex);
+            throw ex;
+        }
+        finally
+        {
+            if (bw != null) bw.close();
+            if (os != null) os.close();
+        }
+    }
+
+    private int readPersistentState() throws Exception
+    {
+        int state = Bundle.INSTALLED;
+
+        // Get bundle state file.
+        File stateFile = new File(m_archiveRootDir, BUNDLE_STATE_FILE);
+
+        // If the state file doesn't exist, then
+        // assume the bundle was installed.
+        if (BundleCache.getSecureAction().fileExists(stateFile))
+        {
+            // Read the bundle state.
+            InputStream is = null;
+            BufferedReader br = null;
+            try
             {
-                // Read the bundle refresh counter.
-                InputStream is = null;
-                BufferedReader br = null;
-                try
+                is = BundleCache.getSecureAction()
+                    .getFileInputStream(stateFile);
+                br = new BufferedReader(new InputStreamReader(is));
+                String s = br.readLine();
+                if ((s != null) && s.equals(ACTIVE_STATE))
                 {
-                    is = BundleCache.getSecureAction()
-                        .getFileInputStream(counterFile);
-                    br = new BufferedReader(new InputStreamReader(is));
-                    long counter = Long.parseLong(br.readLine());
-                    return counter;
+                    state = Bundle.ACTIVE;
                 }
-                finally
+                else if ((s != null) && s.equals(STARTING_STATE))
                 {
-                    if (br != null) br.close();
-                    if (is != null) is.close();
+                    state = Bundle.STARTING;
                 }
+                else if ((s != null) && s.equals(UNINSTALLED_STATE))
+                {
+                    state = Bundle.UNINSTALLED;
+                }
+                else
+                {
+                    state = Bundle.INSTALLED;
+                }
+            }
+            catch (Exception ex)
+            {
+                state = Bundle.INSTALLED;
+            }
+            finally
+            {
+                if (br != null) br.close();
+                if (is != null) is.close();
             }
         }
 
-        return m_refreshCount;
+        return state;
     }
 
-    /**
-     * This utility method is used to retrieve the current refresh
-     * counter value for the bundle. This value is used when generating
-     * the bundle revision directory name where native libraries are extracted.
-     * This is necessary because Sun's JVM requires a one-to-one mapping
-     * between native libraries and class loaders where the native library
-     * is uniquely identified by its absolute path in the file system. This
-     * constraint creates a problem when a bundle is refreshed, because it
-     * gets a new class loader. Using the refresh counter to generate the name
-     * of the bundle revision directory resolves this problem because each time
-     * bundle is refresh, the native library will have a unique name.
-     * As a result of the unique name, the JVM will then reload the
-     * native library without a problem.
-    **/
-    private void setRefreshCount(long counter)
-        throws Exception
+    private void writeStartLevel() throws Exception
+    {
+        OutputStream os = null;
+        BufferedWriter bw = null;
+        try
+        {
+            os = BundleCache.getSecureAction()
+                .getFileOutputStream(new File(m_archiveRootDir, BUNDLE_START_LEVEL_FILE));
+            bw = new BufferedWriter(new OutputStreamWriter(os));
+            String s = Integer.toString(m_startLevel);
+            bw.write(s, 0, s.length());
+        }
+        catch (IOException ex)
+        {
+            m_logger.log(
+                Logger.LOG_ERROR,
+                getClass().getName() + ": Unable to record start level - " + ex);
+            throw ex;
+        }
+        finally
+        {
+            if (bw != null) bw.close();
+            if (os != null) os.close();
+        }
+    }
+
+    private int readStartLevel() throws Exception
     {
-        // Get refresh counter file.
-        File counterFile = new File(m_archiveRootDir, REFRESH_COUNTER_FILE);
+        int level = -1;
+
+        // Get bundle start level file.
+        File levelFile = new File(m_archiveRootDir, BUNDLE_START_LEVEL_FILE);
+
+        // If the start level file doesn't exist, then
+        // return an error.
+        if (!BundleCache.getSecureAction().fileExists(levelFile))
+        {
+            level = -1;
+        }
+        else
+        {
+            // Read the bundle start level.
+            InputStream is = null;
+            BufferedReader br= null;
+            try
+            {
+                is = BundleCache.getSecureAction()
+                    .getFileInputStream(levelFile);
+                br = new BufferedReader(new InputStreamReader(is));
+                level = Integer.parseInt(br.readLine());
+            }
+            finally
+            {
+                if (br != null) br.close();
+                if (is != null) is.close();
+            }
+        }
+        return level;
+    }
 
-        // Write the refresh counter.
+    private void writeLastModified() throws Exception
+    {
         OutputStream os = null;
         BufferedWriter bw = null;
         try
         {
             os = BundleCache.getSecureAction()
-                .getFileOutputStream(counterFile);
+                .getFileOutputStream(new File(m_archiveRootDir, BUNDLE_LASTMODIFIED_FILE));
             bw = new BufferedWriter(new OutputStreamWriter(os));
-            String s = Long.toString(counter);
+            String s = Long.toString(m_lastModified);
             bw.write(s, 0, s.length());
-            m_refreshCount = counter;
         }
         catch (IOException ex)
         {
             m_logger.log(
                 Logger.LOG_ERROR,
-                getClass().getName() + ": Unable to write refresh counter: " + ex);
+                getClass().getName() + ": Unable to record start level - " + ex);
             throw ex;
         }
         finally
@@ -1109,4 +1261,82 @@ public class BundleArchive
             if (os != null) os.close();
         }
     }
+
+    private long readLastModified() throws Exception
+    {
+        long last = 0;
+
+        InputStream is = null;
+        BufferedReader br = null;
+        try
+        {
+            is = BundleCache.getSecureAction()
+                .getFileInputStream(new File(m_archiveRootDir, BUNDLE_LASTMODIFIED_FILE));
+            br = new BufferedReader(new InputStreamReader(is));
+            last = Long.parseLong(br.readLine());
+        }
+        catch (Exception ex)
+        {
+            last = 0;
+        }
+        finally
+        {
+            if (br != null) br.close();
+            if (is != null) is.close();
+        }
+
+        return last;
+    }
+
+    private void writeRefreshCount() throws Exception
+    {
+        OutputStream os = null;
+        BufferedWriter bw = null;
+        try
+        {
+            os = BundleCache.getSecureAction()
+                .getFileOutputStream(new File(m_archiveRootDir, REFRESH_COUNTER_FILE));
+            bw = new BufferedWriter(new OutputStreamWriter(os));
+            String s = Long.toString(m_refreshCount);
+            bw.write(s, 0, s.length());
+        }
+        catch (IOException ex)
+        {
+            m_logger.log(
+                Logger.LOG_ERROR,
+                getClass().getName() + ": Unable to write refresh count: " + ex);
+            throw ex;
+        }
+        finally
+        {
+            if (bw != null) bw.close();
+            if (os != null) os.close();
+        }
+    }
+
+    private long readRefreshCount() throws Exception
+    {
+        long count = 0;
+
+        InputStream is = null;
+        BufferedReader br = null;
+        try
+        {
+            is = BundleCache.getSecureAction()
+                .getFileInputStream(new File(m_archiveRootDir, REFRESH_COUNTER_FILE));
+            br = new BufferedReader(new InputStreamReader(is));
+            count = Long.parseLong(br.readLine());
+        }
+        catch (Exception ex)
+        {
+            count = 0;
+        }
+        finally
+        {
+            if (br != null) br.close();
+            if (is != null) is.close();
+        }
+
+        return count;
+    }
 }
\ No newline at end of file

Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/cache/BundleCache.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/cache/BundleCache.java?rev=1022172&r1=1022171&r2=1022172&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/cache/BundleCache.java
(original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/cache/BundleCache.java
Wed Oct 13 16:24:07 2010
@@ -66,6 +66,8 @@ public class BundleCache
 {
     public static final String CACHE_BUFSIZE_PROP = "felix.cache.bufsize";
     public static final String CACHE_ROOTDIR_PROP = "felix.cache.rootdir";
+    // TODO: CACHE - Remove this once we migrate the cache format.
+    public static final String CACHE_SINGLEBUNDLEFILE_PROP = "felix.cache.singlebundlefile";
 
     protected static transient int BUFSIZE = 4096;
     protected static transient final String CACHE_DIR_NAME = "felix-cache";
@@ -154,7 +156,7 @@ public class BundleCache
             archiveList.toArray(new BundleArchive[archiveList.size()]);
     }
 
-    public BundleArchive create(long id, String location, InputStream is)
+    public BundleArchive create(long id, int startLevel, String location, InputStream is)
         throws Exception
     {
         File cacheDir = determineCacheDir(m_configMap);
@@ -167,7 +169,8 @@ public class BundleCache
         {
             // Create the archive and add it to the list of archives.
             BundleArchive ba =
-                new BundleArchive(m_logger, m_configMap, archiveRootDir, id, location, is);
+                new BundleArchive(
+                    m_logger, m_configMap, archiveRootDir, id, startLevel, location, is);
             return ba;
         }
         catch (Exception ex)



Mime
View raw message