Packages.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 
00041 
00048 class Packages {
00049 
00053   final Framework framework;
00054 
00058   private Hashtable /* String->Pkg */ packages = new Hashtable();
00059 
00063   private HashSet /* BundleImpl */ tempResolved = null;
00064 
00068   private HashMap /* String->ExportPkg */ tempProvider = null;
00069 
00073   private HashMap /* RequireBundle->BundlePackages */ tempRequired = null;
00074 
00078   private HashSet /* ExportPkg */ tempBlackList = null;
00079 
00083   private HashSet /* BundleImpl */ tempBackTracked = null;
00084 
00085   /* Statistics to check need for tempBlackList */
00086   int tempBlackListChecks = 0;
00087   int tempBlackListHits = 0;
00088 
00089 
00093   Packages(Framework fw) {
00094     framework = fw;
00095   }
00096 
00097 
00105   synchronized void registerPackages(Iterator exports, Iterator imports) {
00106     while (exports.hasNext()) {
00107       ExportPkg pe = (ExportPkg)exports.next();
00108       Pkg p = (Pkg)packages.get(pe.name);
00109       if (p == null) {
00110         p = new Pkg(pe.name);
00111         packages.put(pe.name, p);
00112       }
00113       p.addExporter(pe);
00114       if (Debug.packages) {
00115         Debug.println("registerPackages: export, " + pe);
00116       }
00117     }
00118     while (imports.hasNext()) {
00119       ImportPkg pe = (ImportPkg)imports.next();
00120       Pkg p = (Pkg)packages.get(pe.name);
00121       if (p == null) {
00122         p = new Pkg(pe.name);
00123         packages.put(pe.name, p);
00124       }
00125       p.addImporter(pe);
00126       if (Debug.packages) {
00127         Debug.println("registerPackages: import, " + pe);
00128       }
00129     }
00130   }
00131 
00132 
00139   synchronized ExportPkg registerDynamicImport(ImportPkg ip) {
00140     if (Debug.packages) {
00141       Debug.println("registerDynamicImport: try " + ip);
00142     }
00143     ExportPkg res = null;
00144     Pkg p = (Pkg)packages.get(ip.name);
00145     if (p != null) {
00146       tempResolved = new HashSet();
00147       tempProvider = new HashMap();
00148       tempRequired = new HashMap();
00149       tempBlackList = new HashSet();
00150       tempBackTracked = new HashSet();
00151       backTrackUses(ip);
00152       tempBackTracked = null;
00153       ArrayList pkgs = new ArrayList(1);
00154       pkgs.add(ip);
00155       p.addImporter(ip);
00156       List r = resolvePackages(pkgs.iterator());
00157       tempBlackList = null;
00158       if (r.size() == 0) {
00159         registerNewProviders(ip.bpkgs.bundle);
00160         res = (ExportPkg)tempProvider.get(ip.name);
00161         ip.provider = res;
00162       } else {
00163         p.removeImporter(ip);
00164       }
00165       tempProvider = null;
00166       tempRequired = null;
00167       tempResolved = null;
00168     }
00169     if (Debug.packages) {
00170       Debug.println("registerDynamicImport: Done for " + ip.name + ", res = " + res);
00171     }
00172     return res;
00173   }
00174 
00175 
00188   synchronized boolean unregisterPackages(List exports, List imports, boolean force) {
00189     // Check if somebody other than ourselves use our exports
00190     if (!force) {
00191       for (Iterator i = exports.iterator(); i.hasNext(); ) {
00192         ExportPkg ep = (ExportPkg)i.next();
00193         Pkg p = ep.pkg;
00194         if (p.providers.contains(ep)) {
00195           for (Iterator ii = p.importers.iterator(); ii.hasNext(); ) {
00196             ImportPkg ip = (ImportPkg) ii.next();
00197             if (ep == ip.provider && ep.bpkgs != ip.bpkgs) {
00198               if (Debug.packages) {
00199                 Debug.println("unregisterPackages: Failed to unregister, " + ep +
00200                               " is still in use.");
00201               }
00202               markAsZombies(exports);
00203               return false;
00204             }
00205           }
00206         }
00207       }
00208     }
00209 
00210     for (Iterator i = exports.iterator(); i.hasNext(); ) {
00211       ExportPkg ep = (ExportPkg)i.next();
00212       Pkg p = ep.pkg;
00213       if (Debug.packages) {
00214         Debug.println("unregisterPackages: unregister export - " + ep);
00215       }
00216       p.removeExporter(ep);
00217       if (p.isEmpty()) {
00218         packages.remove(ep.name);
00219       }
00220     }
00221 
00222     for (Iterator i = imports.iterator(); i.hasNext(); ) {
00223       ImportPkg ip = (ImportPkg)i.next();
00224       Pkg p = ip.pkg;
00225       if (Debug.packages) {
00226         Debug.println("unregisterPackages: unregister import - " + ip.pkgString());
00227       }
00228       p.removeImporter(ip);
00229       if (p.isEmpty()) {
00230         packages.remove(ip.name);
00231       }
00232     }
00233     return true;
00234   }
00235 
00236 
00244   synchronized String resolve(BundleImpl bundle, Iterator pkgs) {
00245     String res;
00246     if (Debug.packages) {
00247       Debug.println("resolve: " + bundle);
00248     }
00249     // If we entry with tempResolved set, it means that we already have
00250     // resolved bundles. Check that it is true!
00251     if (tempResolved != null) {
00252       if (!tempResolved.contains(bundle)) {
00253         framework.listeners.frameworkError(bundle,
00254                                            new Exception("resolve: InternalError1!"));
00255       }
00256       return null;
00257     }
00258 
00259     tempResolved = new HashSet();
00260     BundleImpl sb = checkBundleSingleton(bundle);
00261     if (sb != null) {
00262       tempResolved = null;
00263       return "Singleton bundle failed to resolve because " + sb + " is already resolved";
00264     }
00265 
00266     tempProvider = new HashMap();
00267     tempRequired = new HashMap();
00268     tempBlackList = new HashSet();
00269     tempResolved.add(bundle);
00270     String br = checkRequireBundle(bundle);
00271     if (br == null) {
00272       List failed = resolvePackages(pkgs);
00273       if (failed.size() == 0) {
00274         registerNewProviders(bundle);
00275         res = null;
00276       } else {
00277         StringBuffer r = new StringBuffer("missing package(s) or can not resolve all of the them: ");
00278         Iterator mi = failed.iterator();
00279         r.append(((ImportPkg)mi.next()).pkgString());
00280         while (mi.hasNext()) {
00281           r.append(", ");
00282           r.append(((ImportPkg)mi.next()).pkgString());
00283         }
00284         res = r.toString();
00285       }
00286     } else {
00287       res = "Failed to resolve required bundle or host: " + br;
00288     } 
00289     tempResolved = null;
00290     tempProvider = null;
00291     tempRequired = null;
00292     tempBlackList = null;
00293     if (Debug.packages) {
00294       Debug.println("resolve: Done for " + bundle);
00295     }
00296     return res;
00297   }
00298 
00299 
00306   Pkg getPkg(String pkg) {
00307     return (Pkg)packages.get(pkg);
00308   }
00309     
00310     
00326   synchronized Collection getZombieAffected(Bundle [] bundles) {
00327     // set of affected bundles will be in start-level/bundle-id order  
00328     TreeSet affected = new TreeSet(new Comparator() {
00329       public int compare(Object o1, Object o2) {
00330         BundleImpl b1 = (BundleImpl)o1; 
00331         BundleImpl b2 = (BundleImpl)o2;
00332         int dif  = b1.getStartLevel() - b2.getStartLevel();
00333         if (dif == 0) {
00334             dif  = (int)(b1.getBundleId() - b2.getBundleId());
00335         }
00336         return dif;
00337       }
00338       public boolean equals(Object o) {
00339         return ((o != null) && getClass().equals(o.getClass()));
00340       }
00341     });
00342     if (bundles == null) {
00343       if (Debug.packages) {
00344         Debug.println("getZombieAffected: check - null");
00345       }
00346       for (Iterator i = packages.values().iterator(); i.hasNext();) {
00347         Pkg p = (Pkg)i.next();
00348         for (Iterator ps = p.providers.iterator(); ps.hasNext(); ) {
00349           ExportPkg ep = (ExportPkg)ps.next();
00350           if (ep.zombie) {
00351             if (Debug.packages) {
00352               Debug.println("getZombieAffected: found zombie - " + ep.bpkgs.bundle);
00353             }
00354             affected.add(ep.bpkgs.bundle);
00355           }
00356         }
00357       }
00358     } else {
00359       for (int i = 0; i < bundles.length; i++) {
00360         if (bundles[i] != null) {
00361           if (Debug.packages) {
00362             Debug.println("getZombieAffected: check - " + bundles[i]);
00363           }
00364           BundleImpl tmp = (BundleImpl)bundles[i];
00365 
00366           if (tmp.isFragment() &&
00367               tmp.isAttached() && 
00368               !affected.contains(tmp.getFragmentHost())) {
00369             affected.add(tmp.getFragmentHost());
00370           } else {
00371             affected.add(bundles[i]);
00372           }
00373         }
00374       }
00375     }
00376     ArrayList moreBundles = new ArrayList(affected);
00377     for (int i = 0; i < moreBundles.size(); i++) {
00378       BundleImpl b = (BundleImpl)moreBundles.get(i);
00379       for (Iterator j = b.getExports(); j.hasNext(); ) {
00380         ExportPkg ep = (ExportPkg)j.next();
00381         if (ep.pkg != null && ep.pkg.providers.contains(ep)) {
00382           for (Iterator k = ep.getPackageImporters().iterator(); k.hasNext(); ) {
00383             Bundle ib = (Bundle)k.next();
00384             if (!affected.contains(ib)) {
00385               moreBundles.add(ib);
00386               if (Debug.packages) {
00387                 Debug.println("getZombieAffected: added - " + ib);
00388               }
00389               affected.add(ib);
00390             }
00391           }
00392         }
00393       }
00394     }
00395     return affected;
00396   }
00397 
00398   //
00399   // Private methods.
00400   //
00401 
00411   private boolean backTrackUses(ImportPkg ip) {
00412     if (Debug.packages) {
00413       Debug.println("backTrackUses: check - " + ip.pkgString());
00414     }
00415     if (tempBackTracked.contains(ip.bpkgs)) {
00416       return false;
00417     }
00418     tempBackTracked.add(ip.bpkgs);
00419     Iterator i = getPackagesProvidedBy(ip.bpkgs).iterator();
00420     if (i.hasNext()) {
00421       do {
00422         ExportPkg ep = (ExportPkg)i.next();
00423         boolean foundUses = false;
00424         for (Iterator ii = ep.pkg.importers.iterator(); ii.hasNext(); ) {
00425           ImportPkg iip = (ImportPkg)ii.next();
00426           if (iip.provider == ep) {
00427             if (backTrackUses(iip)) {
00428               foundUses = true;
00429             }
00430           }
00431         }
00432         if (!foundUses) {
00433           checkUses(ep);
00434         }
00435       } while (i.hasNext());
00436       return true;
00437     } else {
00438       return false;
00439     }
00440   }
00441 
00442 
00448   private void markAsZombies(List exports) {
00449     for (Iterator i = exports.iterator(); i.hasNext();) {
00450       ((ExportPkg)i.next()).zombie = true;
00451     }
00452   }
00453 
00454 
00461   private Collection getPackagesProvidedBy(BundlePackages bpkgs) {
00462     ArrayList res = new ArrayList();
00463     // NYI Improve the speed here!
00464     for (Iterator i = bpkgs.getExports(); i.hasNext();) {
00465       ExportPkg ep = (ExportPkg) i.next();
00466       if (ep.pkg.providers.contains(ep)) {
00467         res.add(ep);
00468       }
00469     }
00470     return res;
00471   }
00472 
00473 
00480   private List resolvePackages(Iterator pkgs) {
00481     ArrayList res = new ArrayList();
00482 
00483     while (pkgs.hasNext()) {
00484       ExportPkg provider = null;
00485       ImportPkg ip = (ImportPkg)pkgs.next();
00486       if (ip.provider != null) {
00487         framework.listeners.frameworkError(ip.bpkgs.bundle,
00488                                            new Exception("resolvePackages: InternalError1!"));
00489       }
00490       if (Debug.packages) {
00491         Debug.println("resolvePackages: check - " + ip.pkgString());
00492       }
00493       provider = (ExportPkg)tempProvider.get(ip.name);
00494       if (provider != null) {
00495         if (Debug.packages) {
00496           Debug.println("resolvePackages: " + ip.name + " - has temporary provider - "
00497                         + provider);
00498         }
00499         if (provider.zombie && provider.bpkgs.bundle.state == Bundle.UNINSTALLED) {
00500           if (Debug.packages) {
00501             Debug.println("resolvePackages: " + ip.name +
00502                           " - provider not used since it is an uninstalled zombie - "
00503                           + provider);
00504           }
00505           provider = null;
00506         } else if (!ip.okPackageVersion(provider.version)) {
00507           if (Debug.packages) {
00508             Debug.println("resolvePackages: " + ip.name +
00509                           " - provider has wrong version - " + provider +
00510                           ", need " + ip.packageRange + ", has " + provider.version);
00511           }
00512           provider = null;
00513         }
00514       } else {
00515         for (Iterator i = ip.pkg.providers.iterator(); i.hasNext(); ) {
00516           ExportPkg ep = (ExportPkg)i.next();
00517           tempBlackListChecks++;
00518           if (tempBlackList.contains(ep)) {
00519             tempBlackListHits++;
00520             continue;
00521           }
00522           if (ep.zombie) {
00523             // TBD! Should we refrain from using a zombie package and try a new provider instead?
00524             continue;
00525           }
00526           if (ip.okPackageVersion(ep.version)) {
00527             if (Debug.packages) {
00528               Debug.println("resolvePackages: " + ip.name + " - has provider - " + ep);
00529             }
00530             HashMap oldTempProvider = (HashMap)tempProvider.clone();
00531             if (!checkUses(ep)) {
00532               tempProvider = oldTempProvider;
00533               tempBlackList.add(ep);
00534               continue;
00535             }
00536             provider = ep;
00537             break;
00538           }
00539         }
00540         if (provider == null) {
00541           provider = pickProvider(ip);
00542         }
00543         if (provider != null) {
00544           tempProvider.put(ip.pkg.pkg, provider);
00545         }
00546       }
00547       if (provider == null) {
00548         if (ip.resolution == Constants.RESOLUTION_MANDATORY) {
00549           res.add(ip);
00550         } else {
00551           if (Debug.packages) {
00552             Debug.println("resolvePackages: Ok, no provider for optional " + ip.name);
00553           }
00554         }
00555       }
00556     }
00557     return res;
00558   }
00559 
00560 
00567   private ExportPkg pickProvider(ImportPkg ip) {
00568     if (Debug.packages) {
00569       Debug.println("pickProvider: for - " + ip);
00570     }
00571     ExportPkg provider = null;
00572     for (Iterator i = ip.pkg.exporters.iterator(); i.hasNext(); ) {
00573       ExportPkg ep = (ExportPkg)i.next();
00574       tempBlackListChecks++;
00575       if (tempBlackList.contains(ep)) {
00576         tempBlackListHits++;
00577         continue;
00578       }
00579       if (!checkAttributes(ep, ip)) {
00580         if (Debug.packages) {
00581           Debug.println("pickProvider: attribute match failed for - " + ep);
00582         }
00583         continue;
00584       }
00585       if (tempResolved.contains(ep.bpkgs.bundle)) {
00586         provider = ep;
00587         break;
00588       }
00589       if ((ep.bpkgs.bundle.state & BundleImpl.RESOLVED_FLAGS) != 0) {
00590         HashMap oldTempProvider = (HashMap)tempProvider.clone();
00591         if (checkUses(ep)) {
00592           provider = ep;
00593           break;
00594         } else {
00595           tempProvider = oldTempProvider;
00596           tempBlackList.add(ep);
00597           continue;
00598         }
00599       }
00600       if (ep.bpkgs.bundle.state == Bundle.INSTALLED && checkResolve(ep.bpkgs.bundle)) { 
00601         provider = ep;
00602         break;
00603       }
00604     }
00605     if (Debug.packages) {
00606       if (provider != null) {
00607         Debug.println("pickProvider: " + ip + " - got provider - " + provider);
00608       } else {
00609         Debug.println("pickProvider: " + ip + " - found no provider");
00610       }
00611     }
00612     return provider;
00613   }
00614 
00615 
00623   private boolean checkAttributes(ExportPkg ep, ImportPkg ip) {
00624     /* Mandatory attributes */
00625     if (!ip.checkMandatory(ep.mandatory)) {
00626       return false;
00627     }
00628     /* Predefined attributes */
00629     if (!ip.okPackageVersion(ep.version) ||
00630         (ip.bundleSymbolicName != null &&
00631          !ip.bundleSymbolicName.equals(ep.bpkgs.bundle.symbolicName)) ||
00632         !ip.bundleRange.withinRange(ep.bpkgs.bundle.version)) {
00633       return false;
00634     }
00635     /* Other attributes */
00636     for (Iterator i = ip.attributes.entrySet().iterator(); i.hasNext(); ) {
00637       Map.Entry e = (Map.Entry)i.next();
00638       String a = (String)ep.attributes.get(e.getKey());
00639       if (a == null || !a.equals(e.getValue())) {
00640         return false;
00641       }
00642     }
00643     return true;
00644   }
00645 
00646 
00655   private boolean checkResolve(BundleImpl b) {
00656     ArrayList okImports = new ArrayList();
00657     if (framework.perm.missingMandatoryPackagePermissions(b.bpkgs, okImports) == null &&
00658         checkBundleSingleton(b) == null) {
00659       HashSet oldTempResolved = (HashSet)tempResolved.clone();
00660       HashMap oldTempProvider = (HashMap)tempProvider.clone();
00661       HashMap oldTempRequired = (HashMap)tempRequired.clone();
00662       HashSet oldTempBlackList = (HashSet)tempBlackList.clone();
00663       tempResolved.add(b);
00664       if (checkRequireBundle(b) == null) {
00665         List r = resolvePackages(okImports.iterator());
00666         if (r.size() == 0) {
00667           return true;
00668         }
00669       }
00670       tempResolved = oldTempResolved;
00671       tempProvider = oldTempProvider;
00672       tempRequired = oldTempRequired;
00673       tempBlackList = oldTempBlackList;
00674     }
00675     return false;
00676   }
00677 
00678 
00687   private boolean checkUses(ExportPkg pkg) {
00688     Iterator ui = null;
00689     String next_uses = null;
00690     if (Debug.packages) {
00691       Debug.println("checkUses: check if packages used by " + pkg + " is okay.");
00692     }
00693     if (pkg.uses != null) {
00694       ui = pkg.uses.iterator();
00695       if (ui.hasNext()) {
00696         next_uses = (String)ui.next();
00697       }
00698     }
00699     if (Debug.packages) {
00700       Debug.println("checkUses: provider with bpkgs=" + pkg.bpkgs);
00701     }
00702     ArrayList checkList = new ArrayList();
00703     for (Iterator i = pkg.bpkgs.getActiveImports(); i.hasNext(); ) {
00704       ImportPkg ip = (ImportPkg)i.next();
00705       if (ui != null) {
00706         if (next_uses == null || !ip.pkg.pkg.equals(next_uses)) {
00707           continue;
00708         }
00709         if (ui.hasNext()) {
00710           next_uses = (String)ui.next();
00711         } else {
00712           next_uses = null;
00713         }
00714       }
00715       ExportPkg ep = (ExportPkg)tempProvider.get(ip.pkg.pkg);
00716       if (Debug.packages) {
00717         Debug.println("checkUses: check import, " + ip +
00718                       " with provider, " + ip.provider);
00719       }
00720       if (ep == null) {
00721         tempProvider.put(ip.pkg.pkg, ip.provider);
00722         checkList.add(ip.provider);
00723       } else if (ep != ip.provider) {
00724         if (Debug.packages) {
00725           Debug.println("checkUses: mismatch in providers for, " +
00726                         ip.pkg.pkg);
00727         }
00728         return false;
00729       }
00730     }
00731     for (Iterator i = checkList.iterator(); i.hasNext(); ) {
00732       if (!checkUses((ExportPkg)i.next())) {
00733         return false;
00734       }
00735     }
00736     if (Debug.packages) {
00737       Debug.println("checkUses: package " + pkg + " is okay.");
00738     }
00739     return true;
00740   }
00741 
00742 
00750   private BundleImpl checkBundleSingleton(BundleImpl b) {
00751     // NYI! More speed?
00752     if (b.symbolicName != null && b.singleton) {
00753       if (Debug.packages) {
00754         Debug.println("checkBundleSingleton: check singleton bundle " + b);
00755       }
00756       List bl = framework.bundles.getBundles(b.symbolicName);
00757       if (bl.size() > 1) {
00758         for (Iterator i = bl.iterator(); i.hasNext(); ) {
00759           BundleImpl b2 = (BundleImpl)i.next();
00760           if (b2.singleton && ((b2.state & BundleImpl.RESOLVED_FLAGS) != 0 ||
00761                                tempResolved.contains(b2))) {
00762             if (Debug.packages) {
00763               Debug.println("checkBundleSingleton: Reject resolve because of bundle: " + b2);
00764             }
00765             return b2;
00766           }
00767         }
00768       }
00769     }
00770     return null;
00771   }
00772 
00773 
00780   private String checkRequireBundle(BundleImpl b) {
00781     // NYI! More speed?
00782     if (b.bpkgs.require != null) {
00783       if (Debug.packages) {
00784         Debug.println("checkRequireBundle: check requiring bundle " + b);
00785       }
00786       if (!framework.perm.okRequireBundlePerm(b)) {
00787         return b.symbolicName;
00788       }
00789       HashMap res = new HashMap();
00790       for (Iterator i = b.bpkgs.require.iterator(); i.hasNext(); ) {
00791         RequireBundle br = (RequireBundle)i.next();
00792         List bl = framework.bundles.getBundles(br.name, br.bundleRange);
00793         BundleImpl ok = null;
00794         for (Iterator bci = bl.iterator(); bci.hasNext() && ok == null; ) {
00795           BundleImpl b2 = (BundleImpl)bci.next();
00796           if (tempResolved.contains(b2)) {
00797             ok = b2;
00798           } else if ((b2.state & BundleImpl.RESOLVED_FLAGS) != 0) {
00799             HashMap oldTempProvider = (HashMap)tempProvider.clone();
00800             ok = b2;
00801             for (Iterator epi = b2.bpkgs.getExports(); epi.hasNext(); ) {
00802               ExportPkg ep = (ExportPkg)epi.next();
00803               if (!checkUses(ep)) {
00804                 tempProvider = oldTempProvider;
00805                 tempBlackList.add(ep);
00806                 ok = null;
00807               }
00808             }
00809           } else if (b2.state == Bundle.INSTALLED &&
00810                      framework.perm.okProvideBundlePerm(b2) &&
00811                      checkResolve(b2)) {
00812             ok = b2;
00813           }
00814         }
00815         if (ok != null) {
00816           if (Debug.packages) {
00817             Debug.println("checkRequireBundle: added required bundle " + ok);
00818           }
00819           res.put(br, ok.bpkgs);
00820         } else if (br.resolution == Constants.RESOLUTION_MANDATORY) {
00821           if (Debug.packages) {
00822             Debug.println("checkRequireBundle: failed to satisfy: " + br.name);
00823           }
00824           return br.name;
00825         }
00826       }
00827       tempRequired.putAll(res);
00828     }
00829     return null;
00830   }
00831 
00832 
00836   private void registerNewProviders(BundleImpl bundle) {
00837     for (Iterator i = tempProvider.values().iterator(); i.hasNext();) {
00838       ExportPkg ep = (ExportPkg)i.next();
00839       ep.pkg.addProvider(ep);
00840     }
00841     for (Iterator i = tempRequired.entrySet().iterator(); i.hasNext();) {
00842       Map.Entry e = (Map.Entry)i.next();
00843       BundlePackages bpkgs = (BundlePackages)e.getValue();
00844       RequireBundle br = (RequireBundle)e.getKey();
00845       br.bpkgs = bpkgs;
00846       if (bpkgs.requiredBy == null) {
00847         bpkgs.requiredBy = new ArrayList(1);
00848       }
00849       bpkgs.requiredBy.add(br.requestor);
00850       if (br.visibility == Constants.VISIBILITY_REEXPORT) {
00851         // Create necessary re-export entries
00852         for (Iterator be = bpkgs.getExports(); be.hasNext(); ) {
00853           br.requestor.checkReExport((ExportPkg)be.next());
00854         }
00855       }
00856     }
00857     for (Iterator i = tempResolved.iterator(); i.hasNext();) {
00858       BundleImpl bs = (BundleImpl)i.next();
00859       if (bs.getState() == Bundle.INSTALLED) {
00860         for (Iterator bi = bs.bpkgs.getImports(); bi.hasNext(); ) {
00861           ImportPkg ip = (ImportPkg)bi.next();
00862           ip.provider = (ExportPkg)tempProvider.get(ip.name);
00863         }
00864         if (bs != bundle) {
00865           if (bs.getUpdatedState() == Bundle.INSTALLED) {
00866             framework.listeners.frameworkError(bs,
00867                new Exception("registerNewProviders: InternalError!"));
00868           }
00869         }
00870       }
00871     }
00872   }
00873 
00874 }

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