Bundles.java

00001 /*
00002  * Copyright (c) 2003-2006, KNOPFLERFISH project
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following
00007  * conditions are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  *
00012  * - Redistributions in binary form must reproduce the above
00013  *   copyright notice, this list of conditions and the following
00014  *   disclaimer in the documentation and/or other materials
00015  *   provided with the distribution.
00016  *
00017  * - Neither the name of the KNOPFLERFISH project nor the names of its
00018  *   contributors may be used to endorse or promote products derived
00019  *   from this software without specific prior written permission.
00020  *
00021  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00027  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00028  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00029  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
00030  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00031  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
00032  * OF THE POSSIBILITY OF SUCH DAMAGE.
00033  */
00034 
00035 package org.knopflerfish.framework;
00036 
00037 import java.io.*;
00038 import java.net.*;
00039 import java.security.*;
00040 
00041 
00042 import java.util.List;
00043 import java.util.ArrayList;
00044 import java.util.Iterator;
00045 import java.util.Enumeration;
00046 import java.util.Hashtable;
00047 
00048 import org.osgi.framework.*;
00049 
00058 public class Bundles {
00059 
00064   private Hashtable /* location String -> BundleImpl */ bundles = new Hashtable();
00065 
00069   private Framework framework;
00070 
00071 
00075   Bundles(Framework fw) {
00076     framework = fw;
00077     bundles.put(fw.systemBundle.location, fw.systemBundle);
00078   }
00079 
00080 
00086   BundleImpl install(final String location, final InputStream in) throws BundleException {
00087     BundleImpl b;
00088     synchronized (this) {
00089       b = (BundleImpl)bundles.get(location);
00090       if (b != null) {
00091         return b;
00092       }
00093       b = framework.perm.callInstall0(this, location, in);
00094     }
00095     framework.listeners.bundleChanged(new BundleEvent(BundleEvent.INSTALLED, b));
00096     return b;
00097   }
00098 
00099 
00100   BundleImpl install0(String location, InputStream in, Object checkContext)
00101     throws BundleException {
00102     InputStream bin;
00103     BundleArchive ba = null;
00104     try {
00105       if (in == null) {
00106         // Do it the manual way to have a chance to 
00107         // set request properties
00108         URL url  = new URL(location);
00109         URLConnection conn = url.openConnection(); 
00110 
00111         // Support for http proxy authentication
00112         //TODO put in update as well
00113         String auth = System.getProperty("http.proxyAuth");
00114         if (auth != null && !"".equals(auth)) {
00115           if ("http".equals(url.getProtocol()) ||
00116               "https".equals(url.getProtocol())) {
00117             String base64 = Util.base64Encode(auth);
00118             conn.setRequestProperty("Proxy-Authorization", 
00119                                     "Basic " + base64);
00120           }
00121         }
00122         bin = conn.getInputStream();
00123       } else {
00124         bin = in;
00125       }
00126       BundleImpl res = null;
00127       try {
00128         ba = framework.storage.insertBundleJar(location, bin);
00129       } finally {
00130         bin.close();
00131       }
00132 
00133       String ee = ba.getAttribute(Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT);
00134       if (ee != null) {
00135         if (Debug.packages) {
00136           Debug.println("bundle #" + ba.getBundleId() + " has EE=" + ee);
00137         }
00138         if (!framework.isValidEE(ee)) {
00139           throw new RuntimeException("Execution environment '" + ee +
00140                                      "' is not supported");
00141         }
00142       }
00143       res = new BundleImpl(framework, ba);
00144 
00145       framework.perm.checkLifecycleAdminPerm(res, checkContext);
00146       if (res.isExtension()) {
00147         framework.perm.checkExtensionLifecycleAdminPerm(res, checkContext);
00148         if (!res.hasPermission(new AllPermission())) {
00149           throw new SecurityException();
00150         }
00151       }
00152 
00153       /* Commit bundle to storage */
00154       ba.setLastModified(System.currentTimeMillis());
00155 
00156       bundles.put(location, res);
00157               
00158       return res;
00159     } catch (Exception e) {
00160       if (ba != null) {
00161         ba.purge();
00162       }
00163       throw new BundleException("Failed to install bundle: " + e, e);
00164     }
00165   }
00166     
00167 
00173   void remove(String location) {
00174     bundles.remove(location);
00175   }
00176 
00177 
00185   public Bundle getBundle(long id) {
00186     synchronized (bundles) {
00187       for (Enumeration e = bundles.elements(); e.hasMoreElements();) {
00188         BundleImpl b = (BundleImpl)e.nextElement();
00189         if (b.id == id) {
00190           return b;
00191         }
00192       }
00193     }
00194     return null;
00195   }
00196 
00197 
00205   public Bundle getBundle(String location) {
00206     return (Bundle) bundles.get(location);
00207   }
00208 
00209 
00217   BundleImpl getBundle(String name, Version version) {
00218     synchronized (bundles) {
00219       for (Enumeration e = bundles.elements(); e.hasMoreElements();) {
00220         BundleImpl b = (BundleImpl)e.nextElement();
00221         if (name.equals(b.symbolicName) && version.equals(b.version)) {
00222           return b;
00223         }
00224       }
00225     }
00226     return null;
00227   }
00228 
00229 
00235   List getBundles() {
00236     ArrayList res = new ArrayList(bundles.size());
00237     synchronized (bundles) {
00238       res.addAll(bundles.values());
00239     }
00240     return res;
00241   }
00242 
00243 
00250   List getBundles(String name) {
00251     ArrayList res = new ArrayList();
00252     synchronized (bundles) {
00253       for (Enumeration e = bundles.elements(); e.hasMoreElements();) {
00254         BundleImpl b = (BundleImpl)e.nextElement();
00255         if (name.equals(b.symbolicName)) {
00256           res.add(b);
00257         }
00258       }
00259     }
00260     return res;
00261   }
00262 
00263 
00272   List getBundles(String name, VersionRange range) {
00273     List res = getBundles(name);
00274     for (int i = 0; i < res.size(); ) {
00275       BundleImpl b = (BundleImpl)res.remove(i);
00276       if (range.withinRange(b.version)) {
00277         int j = i;
00278         while (--j >= 0) {
00279           if (b.version.compareTo(((BundleImpl)res.get(j)).version) <= 0) {
00280             break;
00281           }
00282         }
00283         res.add(j + 1, b);
00284         i++;
00285       }
00286     }
00287     return res;
00288   }
00289 
00290 
00296   List getActiveBundles() {
00297     ArrayList slist = new ArrayList();
00298     synchronized (bundles) {
00299       for (Enumeration e = bundles.elements(); e.hasMoreElements();) {
00300         BundleImpl b = (BundleImpl)e.nextElement();
00301         int s = b.getState();
00302         if (s == Bundle.ACTIVE || s == Bundle.STARTING) {
00303           slist.add(b);
00304         }
00305       }
00306     }
00307     return slist;
00308   }
00309 
00310 
00318   synchronized void load() {
00319     BundleArchive [] bas = framework.storage.getAllBundleArchives();
00320     for (int i = 0; i < bas.length; i++) {
00321       BundleImpl b = new BundleImpl(framework, bas[i]);
00322       bundles.put(b.location, b);
00323     }
00324   }
00325 
00326 
00332   void startBundles(List slist) {
00333     // Sort in start order
00334     for (Iterator i = slist.iterator(); i.hasNext();) {
00335       BundleImpl rb = (BundleImpl)i.next();
00336       if (rb.getUpdatedState() == Bundle.RESOLVED) {
00337         try {
00338           rb.start();
00339         } catch (BundleException be) {
00340           rb.framework.listeners.frameworkError(rb, be);
00341         }
00342       } 
00343     }    
00344   }
00345 
00346 
00354   List getFragmentBundles(BundleImpl target) {
00355     ArrayList retval = new ArrayList();
00356     for (Enumeration e = bundles.elements(); e.hasMoreElements();) {
00357       BundleImpl b = (BundleImpl)e.nextElement();
00358       if (b.isFragment() &&
00359           b.state != Bundle.UNINSTALLED &&
00360           b.getFragmentHost() == target) {
00361         retval.add(b);
00362       }
00363     }
00364     return retval;
00365   }
00366 }

Generated on Mon Jan 11 21:19:13 2010 for OpenMobileIS by  doxygen 1.5.4