Package org.knopflerfish.bundle.desktop.swing

Source Code of org.knopflerfish.bundle.desktop.swing.PackageManager$PackageFilter

/*
* Copyright (c) 2003-2010, KNOPFLERFISH project All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above copyright
*   notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above
*   copyright notice, this list of conditions and the following
*   disclaimer in the documentation and/or other materials
*   provided with the distribution.
*
* - Neither the name of the KNOPFLERFISH project nor the names of its
*   contributors may be used to endorse or promote products derived
*   from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.knopflerfish.bundle.desktop.swing;


import java.util.*;
import java.awt.geom.Point2D;
import java.awt.Color;
import org.osgi.framework.*;
import org.knopflerfish.bundle.desktop.swing.Util;
import org.knopflerfish.bundle.desktop.swing.Activator;

import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Version;
import org.osgi.service.packageadmin.ExportedPackage;
import org.osgi.service.packageadmin.PackageAdmin;
import org.osgi.service.packageadmin.RequiredBundle;
import org.osgi.util.tracker.ServiceTracker;
import org.knopflerfish.util.Text;

public class PackageManager  {
  final ServiceTracker pkgTracker;

  public PackageManager(ServiceTracker pkgTracker) {
    this.pkgTracker = pkgTracker;
    refresh();
  }

  final Map bundleExports = new HashMap();
  final Map bundleImports = new HashMap();
  final Map bundleReqs    = new HashMap();
  final Map manifestImports = new HashMap();
  final Map missingImports = new HashMap();


  // Bundle -> RequiredBundle
  final Map requiredBundleMap = new HashMap();

  // RequiredBundle -> Boolean
  final Map isRequiringMap = new HashMap();

  // int maxSize = 0;

  final Object lock = new Object();

  /*
  public int getMaxSize() {
    synchronized(lock) {
      return maxSize;
    }
  }
  */

  public PackageAdmin getPackageAdmin() {
    return (PackageAdmin) pkgTracker.getService();
  }

  static final Bundle[] EMPTY_BUNDLES = new Bundle[0];

  public Bundle[] getHosts(final Bundle b) {
    final PackageAdmin pkgAdmin = getPackageAdmin();
    final Bundle[] bl = null!=pkgAdmin ? pkgAdmin.getHosts(b) : null;
    return bl != null ? bl : EMPTY_BUNDLES;
  }

  public Bundle[] getFragments(final Bundle b) {
    final PackageAdmin pkgAdmin = getPackageAdmin();
    final Bundle[] bl = null!=pkgAdmin ? pkgAdmin.getFragments(b) : null;
    return bl != null ? bl : EMPTY_BUNDLES;
  }

  public Collection getImportedPackages(final Bundle b) {
    synchronized(lock) {
      final Collection s = (Collection) bundleImports.get(b);
      return s != null ? s : Collections.EMPTY_SET;
    }
  }

  public Collection getRequiredPackages(final Bundle b) {
    synchronized(lock) {
      final Collection s = (Collection) bundleReqs.get(b);
      return s != null ? s : Collections.EMPTY_SET;
    }
  }


  public Collection getManifestImports(final Bundle b) {
    synchronized(lock) {
      Collection c = (Collection) manifestImports.get(b);
      if(c == null) {
        c = getPackageNames(b, "Import-Package");
        manifestImports.put(b, c);
      }

      return c;
    }
  }

  public Collection getMissingImports(final Bundle b) {
    synchronized(lock) {
      Collection missing = (Collection) missingImports.get(b);
      if(missing == null) {
        missing = new TreeSet();
        missing.addAll(getManifestImports(b));

        Collection okSet  = getImportedPackages(b);

        // Remove wired imports
        for(Iterator it = okSet.iterator(); it.hasNext(); ) {
          final ExportedPackage pkg = (ExportedPackage) it.next();
          missing.remove(pkg.getName());
        }

        // Remove imports of packages exported by the bundle (self
        // imports from the current classloader will not have any
        // wires)
        okSet = getExportedPackages(b);
        for(Iterator it = okSet.iterator(); it.hasNext(); ) {
          final ExportedPackage pkg = (ExportedPackage) it.next();
          missing.remove(pkg.getName());
        }

        missingImports.put(b, missing);
      }

      return missing;
    }
  }

  /**
   * Get the specified header name from a bundle and parse the value
   * as package names (ignoring all parameters and directives).
   *
   * @return a collection of strings
   */
  protected Collection getPackageNames(final Bundle b,
                                       final String headerName)
  {
    final Set res = new TreeSet();
    final String v = (String) b.getHeaders().get(headerName);

    if(v != null && v.length() > 0) {
      // Uses the manifest entry parser from the KF-framework
      try {
        final Iterator it = org.knopflerfish.framework.Util
          .parseEntries(headerName, v, false, false, false);
        while (it.hasNext()) {
          final Map entry = (Map) it.next();
          final List pkgs = (List) entry.get("$keys");
          res.addAll(pkgs);
        }
      } catch (IllegalArgumentException iae) {
      }
    }
    return res;
  }


  public Collection getExportedPackages(final Bundle b) {
    synchronized(lock) {
      Collection r = (Collection) bundleExports.get(b);
      if(r == null) {
        r = new TreeSet(pkgComparator);
        final PackageAdmin pkgAdmin = getPackageAdmin();
        ExportedPackage[] pkgs = null!=pkgAdmin
          ? pkgAdmin.getExportedPackages(b) : null;
        for(int i = 0; pkgs != null && i < pkgs.length; i++) {
          if(accept(pkgs[i])) {
            r.add(pkgs[i]);
          }
        }
        bundleExports.put(b, r);
      }
      return r;
    }
  }

  public boolean isWired(final String pkgName, final Bundle b)
  {
    final Collection pkgs = getImportedPackages(b);
    for (Iterator it = pkgs.iterator(); it.hasNext(); ) {
      final ExportedPackage epkg = (ExportedPackage) it.next();
      if (pkgName.equals(epkg.getName())) {
        return true;
      }
    }
    return false;
  }


  PackageFilter packageFilter = null;
  // new NoCommonPackagesFilter();

  public void setPackageFilter(PackageFilter filter) {
    this.packageFilter = filter;
    refresh();
  }


  protected boolean accept(final ExportedPackage pkg) {
    if(packageFilter != null) {
      return packageFilter.accept(pkg);
    } else {
      return true;
    }
  }

  public static interface PackageFilter {
    boolean accept(ExportedPackage pkg);
  }

  public static class NoCommonPackagesFilter implements PackageFilter {
    public boolean accept(final ExportedPackage pkg) {
      String name = pkg.getName();
      if(name.startsWith("org.eclipse.swt.")) {
        return false;
      }
      if(name.startsWith("org.eclipse.ui.")) {
        return false;
      }
      if(name.startsWith("org.eclipse.")) {
        if(-1 != name.indexOf(".internal")) {
          return false;
        }
      }
      if(name.startsWith("javax.")) {
        return false;
      }
      if(name.startsWith("org.omg.")) {
        return false;
      }
      if(name.startsWith("org.w3c.")) {
        return false;
      }
      return true;
    }
  }


  void refresh() {
    synchronized(lock) {
      // maxSize = 0;
      long t0 = System.currentTimeMillis();

      manifestImports.clear();
      missingImports.clear();
      bundleExports.clear();
      bundleImports.clear();
      bundleReqs.clear();
      requiredBundleMap.clear();

      // makeBundleIndex();

      final PackageAdmin pkgAdmin = getPackageAdmin();
      if (null!=pkgAdmin) {
        final ExportedPackage[] pkgs
          = pkgAdmin.getExportedPackages((Bundle)null);
        final RequiredBundle[] rbl = pkgAdmin.getRequiredBundles(null);

        for(int i = 0; pkgs != null && i < pkgs.length; i++) {

          if(accept(pkgs[i])) {
            Bundle   fromB = pkgs[i].getExportingBundle();
            if (null==fromB) continue; // Ignore STALE epkgs

            Collection r = (Collection)bundleExports.get(fromB);
            if(r == null) {
              r = new TreeSet(pkgComparator);
              bundleExports.put(fromB, r);
            }
            if(accept(pkgs[i])) {
              r.add(pkgs[i]);
            }

            Bundle[] bl    = pkgs[i].getImportingBundles();
            for(int j = 0; bl != null && j < bl.length; j++) {
              if (isBundleRequiredBy(rbl, fromB, bl[j])) {
                Set reqs = (Set)bundleReqs.get(bl[j]);
                if(reqs == null) {
                  reqs = new TreeSet(pkgComparator);
                  bundleReqs.put(bl[j], reqs);
                }

                reqs.add(pkgs[i]);
              } else {
                Set imports = (Set)bundleImports.get(bl[j]);
                if(imports == null) {
                  imports = new TreeSet(pkgComparator);
                  bundleImports.put(bl[j], imports);
                }
                imports.add(pkgs[i]);
              }
            }
          }
        }
      }
      long t1 = System.currentTimeMillis();
    }
  }



  /**
   * Check if one given bundle is required by another specified bundle.
   *
   * @param rbl List of required bundles as returend by package admin.
   * @param requiredBundle The bundle to check if it is required.
   * @param requiringBundle The bundle to check that it requires.
   * @return <tt>true</tt> if requiredbundle is required by
   *         requiringBundle, <tt>false</tt> otherwsie.
   */
  public boolean isBundleRequiredBy(final RequiredBundle[] rbl,
                                    final Bundle requiredBundle,
                                    final Bundle requiringBundle)
  {
    final RequiredBundle rb = getRequiredBundle(rbl, requiredBundle);

    final Bundle[] requiringBundles
      = rb!=null ? rb.getRequiringBundles() : null;
    for (int j=0; requiringBundles!=null && j<requiringBundles.length;j++){
      if (requiringBundles[j].getBundleId()==requiringBundle.getBundleId()){
        return true;
      }
    }
    return false;
  }



  /**
   * Get the RequiredBundle object for this bundle.
   *
   * @param rbl List of required bundles as returend by package admin.
   * @param bundle The bundle to get requiring bundles for.
   * @return The RequiredBundle object for the given bundle or
   *         <tt>null</tt> if the bundle is not required.
   */
  public RequiredBundle getRequiredBundle(final RequiredBundle[] rbl,
                                          final Bundle b)  {
    final RequiredBundle rb = (RequiredBundle) requiredBundleMap.get(b);
    if(rb != null) {
      return rb;
    }
    for (int i=0; rbl!=null && i<rbl.length; i++) {
      final Bundle rbb = rbl[i].getBundle();
      if (rbb != null && rbb.getBundleId()==b.getBundleId()) {
        requiredBundleMap.put(b, rbl[i]);
        return rbl[i];
      }
    }
    requiredBundleMap.put(b, null);
    return null;
  }

  static public Comparator pkgComparator = new ExportedPackageComparator();

  static class ExportedPackageComparator implements Comparator
  {
    public int compare(Object o1, Object o2)
    {
      ExportedPackage ep1 = (ExportedPackage) o1;
      ExportedPackage ep2 = (ExportedPackage) o2;

      // First package name
      int res = ep1.getName().compareTo(ep2.getName());
      if (0!=res) return res;

      // Then package version
      res = ep1.getVersion().compareTo(ep2.getVersion());
      if (0!=res) return res;

      // Then pending removal
      if (ep1.isRemovalPending() && !ep2.isRemovalPending()) return -1;
      if (!ep1.isRemovalPending() && ep2.isRemovalPending()) return 1;

      // Then number of importing bundles
      res = ep2.getImportingBundles().length - ep1.getImportingBundles().length;
      if (0!=res) return res;

      // Finally object identity (hashCode is the closest approximation)
      res = ep2.hashCode() - ep1.hashCode();
      return res;
    }
    public boolean equals(Object o)
    {
      return o instanceof ExportedPackageComparator;
    }

  }

}
TOP

Related Classes of org.knopflerfish.bundle.desktop.swing.PackageManager$PackageFilter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.
reate', 'UA-20639858-1', 'auto'); ga('send', 'pageview'); script>