OpenmisOscarBundleCache.java

00001 /*
00002  * Oscar - An implementation of the OSGi framework.
00003  * Copyright (c) 2004, Richard S. Hall
00004  * All rights reserved.
00005  *  
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  *  
00010  *   * Redistributions of source code must retain the above copyright
00011  *     notice, this list of conditions and the following disclaimer.
00012  *   * Redistributions in binary form must reproduce the above copyright
00013  *     notice, this list of conditions and the following disclaimer in
00014  *     the documentation and/or other materials provided with the
00015  *     distribution.
00016  *   * Neither the name of the ungoverned.org nor the names of its
00017  *     contributors may be used to endorse or promote products derived
00018  *     from this software without specific prior written permission.
00019  *  
00020  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00021  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00022  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00023  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00024  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00025  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00026  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00027  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00028  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00029  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00030  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00031  * 
00032  * Contact: Richard S. Hall (heavy@ungoverned.org)
00033  * Contributor(s):
00034  *
00035 **/
00036 package org.openmobileis.oscar.utils;
00037 
00038 import java.io.BufferedInputStream;
00039 import java.io.File;
00040 import java.io.InputStream;
00041 
00042 import org.ungoverned.oscar.cache.BundleArchive;
00043 import org.ungoverned.oscar.cache.BundleCache;
00044 import org.ungoverned.oscar.util.PropertyResolver;
00045 import org.osgi.framework.Bundle;
00046 import org.osgi.service.log.LogService;
00047 
00093 public class OpenmisOscarBundleCache implements BundleCache
00094 {
00095     public static final String CACHE_BUFSIZE_PROP = "oscar.cache.bufsize";
00096     public static final String CACHE_DIR_PROP = "oscar.cache.dir";
00097     public static final String CACHE_PROFILE_DIR_PROP = "oscar.cache.profiledir";
00098     public static final String CACHE_PROFILE_PROP = "oscar.cache.profile";
00099 
00100     protected static transient int BUFSIZE = 4096;
00101     protected static transient final String CACHE_DIR_NAME = ".noscar";
00102     protected static transient final String BUNDLE_DIR_PREFIX = "bundle";
00103 
00104     private PropertyResolver m_cfg = null;
00105     private LogService m_logger = null;
00106     private File m_profileDir = null;
00107     private BundleArchive[] m_archives = null;
00108 
00109     public OpenmisOscarBundleCache()
00110     {
00111     }
00112 
00113     public void initialize(PropertyResolver cfg, LogService logger) throws Exception
00114     {
00115         // Save Properties reference.
00116         m_cfg = cfg;
00117         // Save LogService reference.
00118         m_logger = logger;
00119 
00120         // Get buffer size value.
00121         try
00122         {
00123             String sBufSize = m_cfg.get(CACHE_BUFSIZE_PROP);
00124             if (sBufSize != null)
00125             {
00126                 BUFSIZE = Integer.parseInt(sBufSize);
00127             }
00128         }
00129         catch (NumberFormatException ne)
00130         {
00131             // Use the default value.
00132         }
00133 
00134         // See if the profile directory is specified.
00135         String profileDirStr = m_cfg.get(CACHE_PROFILE_DIR_PROP);
00136         if (profileDirStr != null)
00137         {
00138             m_profileDir = new File(profileDirStr);
00139         }
00140         else
00141         {
00142             // Since no profile directory was specified, then the profile
00143             // directory will be a directory in the cache directory named
00144             // after the profile.
00145 
00146             // First, determine the location of the cache directory; it
00147             // can either be specified or in the default location.
00148             String cacheDirStr = m_cfg.get(CACHE_DIR_PROP);
00149             if (cacheDirStr == null)
00150             {
00151                 // Since no cache directory was specified, put it
00152                 // ".oscar" in the user's home by default.
00153                 cacheDirStr = System.getProperty("user.home");
00154                 cacheDirStr = cacheDirStr.endsWith(File.separator)
00155                     ? cacheDirStr : cacheDirStr + File.separator;
00156                 cacheDirStr = cacheDirStr + CACHE_DIR_NAME;
00157             }
00158 
00159             // Now, get the profile name.
00160             String profileName = m_cfg.get(CACHE_PROFILE_PROP);
00161             if (profileName == null)
00162             {
00163                 throw new IllegalArgumentException(
00164                     "No profile name or directory has been specified.");
00165             }
00166             // Profile name cannot contain the File.separator char.
00167             else if (profileName.indexOf(File.separator) >= 0)
00168             {
00169                 throw new IllegalArgumentException(
00170                     "The profile name cannot contain the file separator character.");
00171             }
00172 
00173             m_profileDir = new File(cacheDirStr, profileName);
00174         }
00175 
00176         // Create profile directory.
00177         if (!m_profileDir.exists())
00178         {
00179             if (!m_profileDir.mkdirs())
00180             {
00181                 m_logger.log(
00182                     LogService.LOG_ERROR,
00183                     "Unable to create directory: " + m_profileDir);
00184                 throw new RuntimeException("Unable to create profile directory.");
00185             }
00186         }
00187 
00188         // Create the existing bundle archives in the profile directory,
00189         // if any exist.
00190         File[] children = m_profileDir.listFiles();
00191         int count = 0;
00192         for (int i = 0; (children != null) && (i < children.length); i++)
00193         {
00194             // Count the legitimate bundle directories.
00195             if (children[i].getName().startsWith(BUNDLE_DIR_PREFIX))
00196             {
00197                 count++;
00198             }
00199         }
00200         m_archives = new BundleArchive[count];
00201         count = 0;
00202         for (int i = 0; (children != null) && (i < children.length); i++)
00203         {
00204             // Ignore directories that aren't bundle directories.
00205             if (children[i].getName().startsWith(BUNDLE_DIR_PREFIX))
00206             {
00207                 String id = children[i].getName().substring(BUNDLE_DIR_PREFIX.length());
00208                 m_archives[count] = new OpenmisOscarBundleArchive(
00209                     m_logger, children[i], Long.parseLong(id));
00210                 
00211                 // As we don't want Oscar to automatically start bundles,
00212                 // we mark all valid archives as INSTALLED
00213                 if (m_archives[count].getPersistentState() != Bundle.UNINSTALLED) {
00214                         m_archives[count].setPersistentState(Bundle.INSTALLED);
00215                 }
00216                 count++;
00217             }
00218         }
00219     }
00220 
00221     public BundleArchive[] getArchives()
00222         throws Exception
00223     {
00224         return m_archives;
00225     }
00226 
00227     public BundleArchive getArchive(long id)
00228         throws Exception
00229     {
00230         for (int i = 0; i < m_archives.length; i++)
00231         {
00232             if (m_archives[i].getId() == id)
00233             {
00234                 return m_archives[i];
00235             }
00236         }
00237         return null;
00238     }
00239 
00240     public BundleArchive create(long id, String location, InputStream is)
00241         throws Exception
00242     {
00243         // Define new bundle's directory.
00244         File bundleDir = new File(m_profileDir, "bundle" + id);
00245 
00246         try
00247         {
00248             // Buffer the input stream.
00249             is = new BufferedInputStream(is, OpenmisOscarBundleCache.BUFSIZE);
00250             // Create an archive instance for the new bundle.
00251             BundleArchive ba = new OpenmisOscarBundleArchive(
00252                 m_logger, bundleDir, id, location, is);
00253             // Add the archive instance to the list of bundle archives.
00254             BundleArchive[] bas = new BundleArchive[m_archives.length + 1];
00255             System.arraycopy(m_archives, 0, bas, 0, m_archives.length);
00256             bas[m_archives.length] = ba;
00257             m_archives = bas;
00258             return ba;
00259         }
00260         finally
00261         {
00262             if (is != null) is.close();
00263         }
00264     }
00265 
00266     public void update(BundleArchive ba, InputStream is)
00267         throws Exception
00268     {
00269         try
00270         {
00271             // Buffer the input stream.
00272             is = new BufferedInputStream(is, OpenmisOscarBundleCache.BUFSIZE);
00273             // Do the update.
00274             ((OpenmisOscarBundleArchive) ba).update(is);
00275         }
00276         finally
00277         {
00278             if (is != null) is.close();
00279         }
00280     }
00281 
00282     public void purge(BundleArchive ba)
00283         throws Exception
00284     {
00285         ((OpenmisOscarBundleArchive) ba).purge();
00286     }
00287 
00288     public void remove(BundleArchive ba)
00289         throws Exception
00290     {
00291         ((OpenmisOscarBundleArchive) ba).remove();
00292     }
00293 }

Generated on Mon Dec 4 11:03:28 2006 for OpenMobileIS by  doxygen 1.5.1-p1