/* * 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.core.instrumentation; import java.util.Enumeration; import java.util.Hashtable; import org.apache.felix.jmood.AgentContext; import org.apache.felix.jmood.core.ServiceNotAvailableException; import org.apache.felix.jmood.utils.InstrumentationSupport; import org.osgi.framework.Bundle; import org.osgi.framework.Constants; import org.osgi.framework.ServiceReference; import org.osgi.service.packageadmin.ExportedPackage; public class FrameworkSnapshot { private Hashtable bundles = new Hashtable(); //<Long, BundleInfo> private Hashtable services = new Hashtable();//<Long, ServiceInfo> private Hashtable packages = new Hashtable();//<String, PackageInfo> private AgentContext ac; private long timestamp; public FrameworkSnapshot(AgentContext ac) { super(); this.ac = ac; this.populate(); } public long getShotTime() { return timestamp; } public void refreshSnapshot() { bundles = new Hashtable(); services = new Hashtable(); packages = new Hashtable(); this.populate(); ac.debug("factory-bundles found: " + bundles.size()); ac.debug("factory-services found: " + services.size()); ac.debug("factory-packages found: " + packages.size()); } public BundleInfo[] getAllBundles() { Enumeration b = bundles.elements(); BundleInfo[] binfo = new BundleInfo[bundles.size()]; for (int i = 0; i < binfo.length; i++) { binfo[i] = (BundleInfo) b.nextElement(); } return binfo; } public ServiceInfo[] getAllServiceInfo() { Enumeration s = services.elements(); ServiceInfo[] sinfo = new ServiceInfo[services.size()]; for (int i = 0; i < sinfo.length; i++) { sinfo[i] = (ServiceInfo) s.nextElement(); } return sinfo; } public PackageInfo[] getAllPackageInfo() { Enumeration p = packages.elements(); PackageInfo[] pinfo = new PackageInfo[packages.size()]; for (int i = 0; i < pinfo.length; i++) { pinfo[i] = (PackageInfo) p.nextElement(); } return pinfo; } // ///////////PRIVATE METHODS////////////////////////// private void populate() { Bundle[] bundles = ac.getBundleContext().getBundles(); BundleInfo[] binfo = new BundleInfo[bundles.length]; for (int i = 0; i < binfo.length; i++) { binfo[i] = getBundleInfo(bundles[i]); } this.timestamp = System.currentTimeMillis(); } private BundleInfo getBundleInfo(Bundle bundle) { if (bundle==null) return null; ac.debug("creating R4 bundleinfo: "+bundle.getSymbolicName()); Long key = new Long(bundle.getBundleId()); if (bundles.containsKey(key)) return (BundleInfo) bundles.get(key); BundleInfo b = new BundleInfo(); b.setBundleId(bundle.getBundleId()); bundles.put(key, b); try{ b.setFragments(this.getFragments(bundle)); b.setHeaders(InstrumentationSupport.getHashtable(bundle.getHeaders())); b.setLastModified(bundle.getLastModified()); b.setRegisteredServices(this.getSvcsInfo(bundle.getRegisteredServices())); b.setBundlePersistentlyStarted(InstrumentationSupport.isBundlePersistentlyStarted(bundle, ac)); b.setStartLevel(InstrumentationSupport.getBundleStartLevel(bundle, ac)); b.setExportedPackages(this.getPkgInfo(InstrumentationSupport.getExportedPackages(bundle, ac))); b.setFragment(InstrumentationSupport.isFragment(bundle, ac)); b.setRequired(InstrumentationSupport.isBundleRequired(bundle, ac)); b.setRemovalPending(InstrumentationSupport.isRequiredBundleRemovalPending(bundle, ac)); b.setRequiredBundles(this.getBundleDependencies(bundle)); b.setRequiringBundles(this.getBInfos(InstrumentationSupport.getRequiringBundles(bundle, ac))); b.setImportedPackages(this.getImportedPackages(bundle)); }catch(ServiceNotAvailableException sae){ //Not needed, since they are default values, placed for clarity b.setBundlePersistentlyStarted(false); b.setStartLevel(-1); b.setExportedPackages(null); b.setFragment(false); b.setRequired(false); b.setRemovalPending(false); b.setRequiredBundles(null); b.setRequiringBundles(null); b.setImportedPackages(null); ac.warning(sae.getMessage()); } b.setServicesInUse(this.getSvcsInfo(bundle.getServicesInUse())); b.setState(InstrumentationSupport.getState(bundle.getState())); b.setSymbolicName(bundle.getSymbolicName()); return b; } private ServiceInfo getServiceInfo(ServiceReference svc) { if (svc == null) return null; ac.debug("Creating R4service for service id " + svc.getProperty(Constants.SERVICE_ID)); Long key = (Long) svc.getProperty(Constants.SERVICE_ID); if (services.containsKey(key)) return (ServiceInfo) services.get(key); ServiceInfo s = new ServiceInfo(); services.put(key, s); // now we set the atts s.setBundle(this.getBundleInfo(svc.getBundle())); Bundle[] using = svc.getUsingBundles(); if (using != null) { BundleInfo[] r4Using = new BundleInfo[using.length]; for (int i = 0; i < r4Using.length; i++) { r4Using[i] = getBundleInfo(using[i]); } s.setUsingBundles(r4Using); } Hashtable props = new Hashtable();//<String, Object> String[] keys=svc.getPropertyKeys(); for (int i=0; i<keys.length;i++) { props.put(keys[i], svc.getProperty(keys[i])); } s.setProperties(props); return s; } private PackageInfo getPackageInfo(ExportedPackage pkg) { if (pkg == null) return null; ac.debug("Creating PackageInfo for package " + pkg.getName()); String key = pkg.getName(); if (packages.containsKey(key)) return (PackageInfo) packages.get(key); PackageInfo p = new PackageInfo(); packages.put(key, p); p.setExportingBundle(getBundleInfo(pkg.getExportingBundle())); Bundle[] importing = pkg.getImportingBundles(); if (importing != null) { BundleInfo[] r4importing = new BundleInfo[importing.length]; for (int i = 0; i < r4importing.length; i++) { r4importing[i] = getBundleInfo(importing[i]); } p.setImportingBundles(r4importing); } p.setName(pkg.getName()); p.setRemovalPending(pkg.isRemovalPending()); p.setVersion(pkg.getVersion().toString()); return p; } private BundleInfo[] getFragments(Bundle bundle) throws ServiceNotAvailableException{ Bundle[] fragments = ac.getPackageadmin().getFragments(bundle); if (fragments == null) return null; BundleInfo[] r4fragments = new BundleInfo[fragments.length]; for (int i = 0; i < fragments.length; i++) { r4fragments[i] = getBundleInfo(fragments[i]); } return r4fragments; } private ServiceInfo[] getSvcsInfo(ServiceReference[] svcs) { if (svcs == null) return null; ServiceInfo[] r4svcs = new ServiceInfo[svcs.length]; for (int i = 0; i < svcs.length; i++) { r4svcs[i] = getServiceInfo(svcs[i]); } return r4svcs; } private PackageInfo[] getImportedPackages(Bundle bundle) throws ServiceNotAvailableException { return this.getPkgInfo(InstrumentationSupport.getImportedPackages(bundle, ac)); } private PackageInfo[] getPkgInfo(ExportedPackage[] pkgs) { if (pkgs == null) return null; PackageInfo[] r4pkgs = new PackageInfo[pkgs.length]; for (int i = 0; i < pkgs.length; i++) { r4pkgs[i] = getPackageInfo(pkgs[i]); } return r4pkgs; } private BundleInfo[] getBundleDependencies(Bundle bundle) throws ServiceNotAvailableException { Bundle[] required = InstrumentationSupport.getBundleDependencies(bundle, ac); return this.getBInfos(required); } private BundleInfo[] getBInfos(Bundle[] bundles){ if(bundles==null) return null; BundleInfo[] info = new BundleInfo[bundles.length]; for (int i = 0; i < info.length; i++) { info[i] = getBundleInfo(bundles[i]); } return info; } }