Package org.apache.felix.jmood.utils

Source Code of org.apache.felix.jmood.utils.InstrumentationSupport

/*
*   Copyright 2005 The Apache Software Foundation
*
*   Licensed under the Apache License, Version 2.0 (the "License");
*   you may not use this file except in compliance with the License.
*   You may obtain a copy of the License at
*
*       http://www.apache.org/licenses/LICENSE-2.0
*
*   Unless required by applicable law or agreed to in writing, software
*   distributed under the License is distributed on an "AS IS" BASIS,
*   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*   See the License for the specific language governing permissions and
*   limitations under the License.
*
*/

package org.apache.felix.jmood.utils;

import java.util.Dictionary;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

import org.apache.felix.jmood.AgentContext;
import org.apache.felix.jmood.core.BundleNotAvailableException;
import org.apache.felix.jmood.core.ServiceNotAvailableException;
import org.osgi.framework.Bundle;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
import org.osgi.service.packageadmin.ExportedPackage;
import org.osgi.service.packageadmin.PackageAdmin;
import org.osgi.service.packageadmin.RequiredBundle;


/**
* This class contains helper methods
*
*
*/
public class InstrumentationSupport {
  private AgentContext ac;
  public InstrumentationSupport(AgentContext ac){
    this.ac=ac;
  }
    /**
     * <p>For each BundleInfo, this method returns the symbolic name String, which we define as the concatenation of 
     * the getSymbolicName of the <code>Bundle</code> interface and the bundle version as specified
     * in the bundle header. Both parts are divided by a semicolon. An example would be:</p>
     * <p>
     * <code>com.acme.foo;1.0.0</code>
     * </p>
     * @param bundles The <code>Bundle</code> array to be converted
     * @return The String array
     * @see org.osgi.framework.Bundle#getSymbolicName()
     */
    public static String[] getSymbolicNames(Bundle[] bundles) {
        if(bundles==null) return null;
        String[] names=new String[bundles.length];
        for (int i = 0; i < names.length; i++) {
            names[i]=getSymbolicName(bundles[i]);
        }
        return names;
    }
    public static String getSymbolicName(Bundle bundle){
        return bundle.getSymbolicName()+";"+bundle.getHeaders().get(Constants.BUNDLE_VERSION);
     
    }

    /**
     * <p>
     *
     * OSGi exported packages can be uniquely identified by the tuple (packageName, packageVersion).
     * This methods returns a String array representing those packages with the following syntax:
     * </p>
     * <p>
     * <i>packageName</i>;<i>packageVersion</i>
     * </p><p>
     * where packageName is as returned by the method <i>getName()</i> and packageVersion as returned by the method <i>getVersion()</i>
     * in package admin's <code>ExportedPackage</code> class.
     * </p>
     * @param packages The <code>ExportedPackage</code> array to be converted
     * @return The String array
     * @see org.osgi.service.packageadmin.ExportedPackage
     */
    public static String[] getPackageNames(ExportedPackage[] packages) {
        if (packages==null) return null;
        String[] names=new String[packages.length];
        for (int i = 0; i < names.length; i++) {
            names[i]=getPackageName(packages[i]);
        }
        return names;
   
    }
  public static String getPackageName(ExportedPackage pkg) {
    return pkg.getName()+";"+pkg.getVersion().toString();
  }


    /**
     * <p>
     * OSGi Services can be registered under more than one interface (objectClass in
     * the spec). Services have a mandatory unique service id (as defined in the SERVICE_ID property of the org.osgi.framework.Constants interface), during their lifetime (i.e, until they are
     * garbage collected). To show this information in a consistent way, we use the following String representation
     * of the service:
     * </p>
     * <p>
     * <i>objectClass1</i>[;<i>objectClass2</i>[;<i>objectClass3</i>...]]:<i>service.id</i>
     * </p><p>
     * where objectClass1..objectClassN are the elements of the mandatory objectClass array
     * included in the service property dictionary (and set by the framework at registration time. The property name is defined in <code>org.osgi.framework.Constants#OBJECTCLASS</code>
     * </p>
     * @param services The <code>ServiceReference</code> array to be converted
     * @return The String array
     * @see org.osgi.framework.Constants#OBJECTCLASS
     * @see org.osgi.framework.Constants#SERVICE_ID
     * @see org.osgi.framework.ServiceReference
     */
    public static String[] getServiceNames(ServiceReference[] services) {
        if(services==null) return null;
        String[] names=new String[services.length];
        for (int i = 0; i < names.length; i++) {
            String[] objectClass=(String[])services[i].getProperty(Constants.OBJECTCLASS);
            //We asume that the framework always returns a non-empty, non-null array.
            StringBuffer sb=new StringBuffer(objectClass[0]);
            for (int j = 1; j < objectClass.length; j++) {
                sb.append(";");
                sb.append(objectClass[j]);
            }
            sb.append(services[i].getProperty(Constants.SERVICE_ID));
            names[i]=sb.toString();
        }
        return names;
    }
    public static ExportedPackage[] getImportedPackages(Bundle bundle, AgentContext ac) throws ServiceNotAvailableException {
        Vector imported = new Vector();
        Bundle[] allBundles = ac.getBundleContext().getBundles();
        for (int i=0; i<allBundles.length;i++) {
          Bundle b=allBundles[i];
            ExportedPackage[] eps=ac.getPackageadmin()
            .getExportedPackages(b);
            if(eps==null) continue;
            exported: for (int j=0;j<eps.length;j++) {
              ExportedPackage ep = eps[j];
                Bundle[] imp=ep.getImportingBundles();
                if(imp==null) continue;
                for (int k=0;k<imp.length;k++) {
                  Bundle b2 =imp[k];
                    if (b2.getBundleId() == bundle.getBundleId()) {
                        imported.add(ep);
                        continue exported;
                    }
                }
            }
        }
        if (imported.size() == 0)
            return null;
        else return (ExportedPackage[])imported.toArray(new ExportedPackage[imported.size()]);

    }
    public static Bundle[] getRequiringBundles(Bundle bundle, AgentContext ac) throws ServiceNotAvailableException{
        if (bundle==null) throw new IllegalArgumentException("Bundle argument should not be null");
        if (bundle.getSymbolicName()==null) return null;
        RequiredBundle[] required=ac.getPackageadmin().getRequiredBundles(bundle.getSymbolicName());
        if (required==null) return null;
            RequiredBundle b=null;
            for (int i=0;i<required.length;i++) {
                if(bundle.getBundleId()==required[i].getBundle().getBundleId()) {
                    b=required[i];
                    break;
                }
            }
            if(b==null) {
                ac.error(InstrumentationSupport.class.getName()+": required bundle should not be null!!!!", new Exception());
                return null;
            }
            return b.getRequiringBundles();
    }
    public static Bundle[] getBundleDependencies(Bundle bundle, AgentContext ac) throws ServiceNotAvailableException{
        Bundle[] all=ac.getBundleContext().getBundles();
        Vector required=new Vector();
        for (int i = 0; i < all.length; i++) {
            Bundle[] requiring=getRequiringBundles(all[i], ac);
            if (requiring==null) continue;
            for (int j = 0; j < requiring.length; j++) {
              //If the solicited bundle is requiring the bundle all[i] we mark it as required
        if (requiring[j].getBundleId()==bundle.getBundleId()) required.add(all[i]);
      }
        }
        if (required.size()==0) return null;
        return (Bundle[])required.toArray(new Bundle[required.size()]);
    }
    public static boolean isBundleRequired(Bundle bundle, AgentContext ac) throws ServiceNotAvailableException {
      if (getRequiredBundle(bundle, ac)==null) return false;
      return true;
    }
    public static boolean isRequiredBundleRemovalPending(Bundle bundle, AgentContext ac)throws ServiceNotAvailableException{
      RequiredBundle r=getRequiredBundle(bundle, ac);
      if (r==null) return false;
      return r.isRemovalPending();
    }
    public static RequiredBundle getRequiredBundle(Bundle bundle, AgentContext ac)throws ServiceNotAvailableException{
        RequiredBundle[] required=ac.getPackageadmin().getRequiredBundles(bundle.getSymbolicName());
        if(required==null) return null;
        for (int i = 0; i < required.length; i++) {
      if (required[i].getBundle().getBundleId()==bundle.getBundleId()) return required[i];
    }
      return null;
    }
  public static String getState(int state) {
    switch (state) {
    case Bundle.ACTIVE:
      return "ACTIVE";
    case Bundle.INSTALLED:
      return "INSTALLED";
    case Bundle.RESOLVED:
      return "RESOLVED";
    case Bundle.STARTING:
      return "STARTING";
    case Bundle.STOPPING:
      return "STOPPING";
    case Bundle.UNINSTALLED:
      return "UNINSTALLED";
    }
    return null;
  }
  public static boolean isBundlePersistentlyStarted(Bundle bundle, AgentContext ac)throws ServiceNotAvailableException{
            // BUG in KNOPFLERFISH: isPersistentlyStarted throws NPE if called
      // on System bundle
            // Workaround: system bundle should always be persistently started, return true
            if (bundle.getBundleId()==0) return true;
            else
            return ac.getStartLevel().isBundlePersistentlyStarted(bundle);
            // End workaround
  }

  public static int getBundleStartLevel(Bundle bundle, AgentContext ac) throws ServiceNotAvailableException {
        return ac.getStartLevel().getBundleStartLevel(bundle);
  }

  public static ExportedPackage[] getExportedPackages(Bundle bundle, AgentContext ac) throws ServiceNotAvailableException{
          return ac.getPackageadmin().getExportedPackages(bundle);
  }

  public static boolean isFragment(Bundle bundle, AgentContext ac) throws ServiceNotAvailableException{
        if(ac.getPackageadmin().getBundleType(bundle)==PackageAdmin.BUNDLE_TYPE_FRAGMENT) return true;
      return false;
  }
  public static Hashtable getHashtable(Dictionary dic){
      Hashtable ht = new Hashtable();
      for (Enumeration keys = dic.keys(); keys.hasMoreElements();) {
        Object key = keys.nextElement();
        // Not inmutable, but unlikely to change
        ht.put(key, dic.get(key));
      }
      return ht;
    }
    public static long getBundleId(String symbolicName, AgentContext ac) throws BundleNotAvailableException{
        if(symbolicName==null) throw new IllegalArgumentException("Symbolic name cannot be null");
        String  [] s=symbolicName.split(";");
        if(s==null||s.length==0) throw new BundleNotAvailableException("Could not find bundle identified by "+symbolicName);
      Bundle[] bundles=ac.getBundleContext().getBundles();
        long id=-1;
        Vector candidates=new Vector();
        for(int i=0;i<bundles.length;i++) {
          //First find all bundles with symbolicName
          String name=bundles[i].getSymbolicName();
          if(name==null) continue;
          if (s[0].equals(name)){
              candidates.add(new Long(bundles[i].getBundleId()));
            }
        }
        //now search the one that matches the version
        for(int i=0; i< candidates.size();i++){
          long cId=((Long)candidates.elementAt(i)).longValue();
          Bundle c=ac.getBundleContext().getBundle(cId);
          String version=(String)c.getHeaders().get(Constants.BUNDLE_VERSION);
          if(s.length==1){//no version available
            ac.debug("no version available for "+symbolicName);
            if(candidates.size()>1) throw new BundleNotAvailableException("could not distinguish among multiple candidates");
            if(candidates.size()==1) {
              id=cId;
              break;
            }
          }
          if (version.equals(s[1])) id=cId;
        }
        if(id==-1) throw new BundleNotAvailableException("No " + symbolicName+ "installed");
        return id;
    }


}
TOP

Related Classes of org.apache.felix.jmood.utils.InstrumentationSupport

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.