PackageAdminImpl.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.util.*;
00038 
00039 import org.osgi.framework.*;
00040 import org.osgi.service.packageadmin.*;
00041 
00070 public class PackageAdminImpl implements PackageAdmin {
00071 
00072   final static String SPEC_VERSION = "1.2";
00073 
00074   private Framework framework;
00075 
00076   
00077   PackageAdminImpl(Framework fw) {
00078     framework = fw;
00079   }
00080 
00081 
00101   public ExportedPackage[] getExportedPackages(Bundle bundle) {
00102     ArrayList pkgs = new ArrayList();
00103     if (bundle != null) {
00104       for (Iterator i = ((BundleImpl)bundle).getExports(); i.hasNext(); ) {
00105         pkgs.add(new ExportedPackageImpl((ExportPkg)i.next()));
00106       }
00107     } else {
00108       for (Iterator bi = framework.bundles.getBundles().iterator(); bi.hasNext(); ) {
00109         for (Iterator i = ((BundleImpl)bi.next()).getExports(); i.hasNext(); ) {
00110           pkgs.add(new ExportedPackageImpl((ExportPkg)i.next()));
00111         }
00112       }
00113     }
00114     int size = pkgs.size();
00115     if (size > 0) {
00116       return (ExportedPackage [])pkgs.toArray(new ExportedPackage[size]);
00117     } else {
00118       return null;
00119     }
00120   }
00121 
00122 
00131   public ExportedPackage[] getExportedPackages(String name) {
00132     Pkg pkg = framework.packages.getPkg(name);
00133     ExportedPackage[] res = null;
00134     if (pkg != null) {
00135       synchronized (pkg) {
00136         int size = pkg.exporters.size();
00137         if (size > 0) {
00138           res = new ExportedPackage[size];
00139           Iterator i = pkg.exporters.iterator();
00140           for (int pos = 0; pos < size;) {
00141             res[pos++] = new ExportedPackageImpl((ExportPkg)i.next());
00142           }
00143         }
00144       }
00145     }
00146     return res;
00147   }
00148 
00149   
00166   public ExportedPackage getExportedPackage(String name) {
00167     Pkg p = (Pkg)framework.packages.getPkg(name);
00168     if (p != null) {
00169       ExportPkg ep = p.getBestProvider();
00170       if (ep != null) {
00171         return new ExportedPackageImpl(ep);
00172       }
00173     }
00174     return null;
00175   }
00176   
00177 
00184   public void refreshPackages(final Bundle[] bundles) {
00185     framework.perm.checkResolveAdminPerm();
00186     
00187     boolean restart = false;
00188     if (bundles != null) {
00189       for (int i = 0; i < bundles.length; i++) {
00190         if (((BundleImpl)bundles[i]).extensionNeedsRestart()) {
00191           restart = true;
00192           break;
00193         }
00194       }
00195     } else {
00196       for (Iterator iter = framework.bundles.getBundles().iterator();
00197            iter.hasNext(); ) {
00198         if (((BundleImpl)iter.next()).extensionNeedsRestart()) {
00199           restart = true;
00200           break;
00201         }
00202       }
00203     }
00204     if (restart) {
00205       try {
00206         // will restart the framework.
00207         framework.systemBundle.stop(Framework.EXIT_CODE_RESTART);
00208       } catch (BundleException ignored) {
00209         /* this can't be happening. */
00210       }
00211       return ;
00212     }
00213 
00214     final PackageAdminImpl thisClass = this;
00215     Thread t = new Thread() {
00216         public void run() {
00217            framework.perm.callRefreshPackages0(thisClass, bundles);
00218         }
00219       };
00220     t.setDaemon(false);
00221     t.start();
00222   }
00223 
00224 
00225   void refreshPackages0(final Bundle[] bundles) {
00226     BundleImpl bi[] = (BundleImpl[])framework.packages
00227       .getZombieAffected(bundles).toArray(new BundleImpl[0]);
00228     ArrayList startList = new ArrayList();
00229 
00230     // Stop affected bundles and remove their classloaders
00231     // in reverse start order
00232     for (int bx = bi.length; bx-- > 0; ) {
00233       BundleException be = null;
00234       synchronized (bi[bx]) {
00235         if (bi[bx].state == Bundle.ACTIVE) {
00236           startList.add(0, bi[bx]);
00237           be = bi[bx].stop0(false);
00238         }
00239       }
00240       if (be != null) {
00241         framework.listeners.frameworkError(bi[bx], be);
00242       }
00243     }
00244 
00245     synchronized (framework.packages) {
00246       // Do this again in case something changed during the stop
00247       // phase, this time synchronized with packages to prevent
00248       // resolving of bundles.
00249       bi = (BundleImpl[])framework.packages
00250         .getZombieAffected(bundles).toArray(new BundleImpl[0]);
00251 
00252       // Update the affected bundle states in normal start order
00253       int startPos = startList.size() - 1;
00254       BundleImpl nextStart =  startPos >= 0 ? (BundleImpl)startList.get(startPos) : null;
00255       for (int bx = bi.length; bx-- > 0; ) {
00256         BundleException be = null;
00257         synchronized (bi[bx]) {
00258           switch (bi[bx].state) {
00259           case Bundle.STARTING:
00260           case Bundle.ACTIVE:
00261             synchronized (bi[bx]) {
00262               if (bi[bx].state == Bundle.ACTIVE) {
00263                 be = bi[bx].stop0(false);
00264                 if (nextStart != bi[bx]) {
00265                   startList.add(startPos + 1, bi[bx]);
00266                 }
00267               }
00268             }
00269           case Bundle.STOPPING:
00270           case Bundle.RESOLVED:
00271             bi[bx].setStateInstalled(true);
00272             if (bi[bx] == nextStart) {
00273               nextStart = --startPos >= 0 ? (BundleImpl)startList.get(startPos) : null;
00274             }
00275           case Bundle.INSTALLED:
00276           case Bundle.UNINSTALLED:
00277             break;
00278           }
00279           bi[bx].purge();
00280         }
00281         if (be != null) {
00282           framework.listeners.frameworkError(bi[bx], be);
00283         }
00284       }
00285     }
00286 
00287     // Restart previously active bundles in normal start order
00288     framework.bundles.startBundles(startList);
00289     framework.listeners.frameworkEvent(new FrameworkEvent(FrameworkEvent.PACKAGES_REFRESHED, this));
00290   }
00291 
00292   public boolean resolveBundles(Bundle[] bundles) {
00293     framework.perm.checkResolveAdminPerm();
00294     List bl;
00295     if (bundles != null) {
00296       bl =  new ArrayList();
00297       for (int bx = 0 ; bx < bundles.length; bx++ ) {
00298         bl.add(bundles[bx]);
00299       }
00300     } else {
00301       bl = framework.bundles.getBundles();
00302     }
00303     boolean res = true;
00304     for (Iterator i = bl.iterator(); i.hasNext(); ) {
00305       BundleImpl b = (BundleImpl)i.next();
00306       if (b.getUpdatedState() == Bundle.INSTALLED) {
00307         res = false;
00308       }
00309     }
00310     return res;
00311   }
00312 
00313 
00314   public RequiredBundle[] getRequiredBundles(String symbolicName) {
00315     List bs;
00316     ArrayList res = new ArrayList();
00317     if (symbolicName != null) {
00318       bs = framework.bundles.getBundles(symbolicName);
00319     } else {
00320       bs = framework.bundles.getBundles();
00321     }
00322     for (Iterator i = bs.iterator(); i.hasNext(); ) {
00323       BundleImpl b = (BundleImpl)i.next();
00324       if ((b.state & BundleImpl.RESOLVED_FLAGS) != 0 && !b.isFragment()) {
00325         res.add(new RequiredBundleImpl(b.bpkgs));
00326       }
00327     }
00328     int s = res.size();
00329     if (s > 0) {
00330       return (RequiredBundle [])res.toArray(new RequiredBundle[s]);
00331     } else {
00332       return null;
00333     }
00334   }
00335 
00336 
00337   public Bundle[] getBundles(String symbolicName, String versionRange) {
00338     VersionRange vr = versionRange != null ? new VersionRange(versionRange.trim()) :
00339       VersionRange.defaultVersionRange;
00340     List bs = framework.bundles.getBundles(symbolicName, vr);
00341     int size = bs.size();
00342     if (size > 0) {
00343       Bundle[] res = new Bundle[size];
00344       Iterator i = bs.iterator();
00345       for (int pos = 0; pos < size;) {
00346         res[pos++] = (Bundle)i.next();
00347       }
00348       return res;
00349     } else {
00350       return null;
00351     }
00352   }
00353 
00354 
00355   public Bundle[] getFragments(Bundle bundle) {
00356     if (bundle == null) {
00357       return null;
00358     }
00359 
00360     BundleImpl b = (BundleImpl)bundle;
00361 
00362     if (b.isFragment()) {
00363       return null;
00364     }
00365 
00366     if (b.isFragmentHost()) {
00367       return (Bundle[])b.fragments.toArray(new Bundle[0]);
00368     } else {
00369       return null;
00370     }
00371   }
00372 
00373 
00374   public Bundle[] getHosts(Bundle bundle) {
00375     if (bundle == null) {
00376       return null;
00377     }
00378 
00379     BundleImpl b = (BundleImpl)bundle;
00380     if (b.isFragment() && 
00381         b.isAttached()) {
00382       return new Bundle[]{b.getFragmentHost()};
00383     }
00384 
00385     return null;
00386   }
00387 
00388 
00389   public Bundle getBundle(Class clazz) {
00390     ClassLoader cl = clazz.getClassLoader();
00391     if (cl instanceof BundleClassLoader) {
00392       return ((BundleClassLoader)cl).getBundle();
00393     } else {
00394       return null;
00395     }
00396   }
00397 
00398 
00399   public int getBundleType(Bundle bundle) {
00400     BundleImpl b = (BundleImpl)bundle;
00401 
00402     if (b.isFragment() && !b.isExtension()) {
00403       return BUNDLE_TYPE_FRAGMENT;
00404     }
00405 
00406     return 0;
00407   }
00408 
00409 }

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