blob: a0145f672c778d53f7b19fa3fe7894797d0598ff [file] [log] [blame]
/*
* 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;
}
}