/* | |
* 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; | |
import java.util.Hashtable; | |
import java.util.Iterator; | |
import java.util.Set; | |
import javax.management.InstanceAlreadyExistsException; | |
import javax.management.InstanceNotFoundException; | |
import javax.management.MBeanRegistration; | |
import javax.management.MBeanRegistrationException; | |
import javax.management.MBeanServer; | |
import javax.management.MalformedObjectNameException; | |
import javax.management.NotCompliantMBeanException; | |
import javax.management.ObjectName; | |
import org.apache.felix.jmood.AgentContext; | |
import org.apache.felix.jmood.core.instrumentation.BundleInfo; | |
import org.apache.felix.jmood.core.instrumentation.FrameworkSnapshot; | |
import org.apache.felix.jmood.core.instrumentation.PackageInfo; | |
import org.apache.felix.jmood.core.instrumentation.ServiceInfo; | |
import org.apache.felix.jmood.utils.InstrumentationSupport; | |
import org.apache.felix.jmood.utils.ObjectNames; | |
import org.osgi.framework.Bundle; | |
import org.osgi.framework.BundleEvent; | |
import org.osgi.framework.BundleListener; | |
import org.osgi.framework.Constants; | |
import org.osgi.framework.FrameworkEvent; | |
import org.osgi.framework.FrameworkListener; | |
import org.osgi.framework.InvalidSyntaxException; | |
import org.osgi.framework.ServiceEvent; | |
import org.osgi.framework.ServiceListener; | |
import org.osgi.framework.ServiceReference; | |
import org.osgi.service.packageadmin.ExportedPackage; | |
import org.osgi.service.packageadmin.PackageAdmin; | |
public class Framework implements FrameworkMBean, MBeanRegistration { | |
private MBeanRegistrator registrator; | |
private AgentContext ac; | |
private FrameworkSnapshot snapshot; | |
public Framework(AgentContext ac) { | |
super(); | |
this.ac = ac; | |
snapshot = new FrameworkSnapshot(ac); | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see org.apache.felix.jmood.core.FrameworkMBean#getBundles() | |
*/ | |
public BundleInfo[] getBundles() { | |
snapshot.refreshSnapshot(); | |
return snapshot.getAllBundles(); | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see org.apache.felix.jmood.core.FrameworkMBean#getServiceInfo() | |
*/ | |
public ServiceInfo[] getServiceInfo() throws InvalidSyntaxException { | |
snapshot.refreshSnapshot(); | |
return snapshot.getAllServiceInfo(); | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see org.apache.felix.jmood.core.FrameworkMBean#getPackageInfo() | |
*/ | |
public PackageInfo[] getPackageInfo() throws ServiceNotAvailableException { | |
snapshot.refreshSnapshot(); | |
return snapshot.getAllPackageInfo(); | |
} | |
public Hashtable getProperties() { | |
Hashtable props = new Hashtable(); | |
// We do not cache it just in case some value changes (although | |
// unlikely) | |
props.put(Constants.FRAMEWORK_VERSION, ac.getBundleContext() | |
.getProperty(Constants.FRAMEWORK_VERSION)); | |
props.put(Constants.FRAMEWORK_VENDOR, ac.getBundleContext() | |
.getProperty(Constants.FRAMEWORK_VENDOR)); | |
props.put(Constants.FRAMEWORK_LANGUAGE, ac.getBundleContext() | |
.getProperty(Constants.FRAMEWORK_LANGUAGE)); | |
props.put(Constants.FRAMEWORK_OS_NAME, ac.getBundleContext() | |
.getProperty(Constants.FRAMEWORK_OS_NAME)); | |
props.put(Constants.FRAMEWORK_OS_VERSION, ac.getBundleContext() | |
.getProperty(Constants.FRAMEWORK_OS_VERSION)); | |
props.put(Constants.FRAMEWORK_PROCESSOR, ac.getBundleContext() | |
.getProperty(Constants.FRAMEWORK_PROCESSOR)); | |
String bootdel = ac.getBundleContext().getProperty( | |
Constants.FRAMEWORK_BOOTDELEGATION); | |
if (bootdel != null) | |
props.put(Constants.FRAMEWORK_BOOTDELEGATION, bootdel); | |
String execenv = ac.getBundleContext().getProperty( | |
Constants.FRAMEWORK_EXECUTIONENVIRONMENT); | |
if (execenv != null) | |
props.put(Constants.FRAMEWORK_EXECUTIONENVIRONMENT, execenv); | |
String syspkgs = ac.getBundleContext().getProperty( | |
Constants.FRAMEWORK_SYSTEMPACKAGES); | |
if (syspkgs != null) | |
props.put(Constants.FRAMEWORK_SYSTEMPACKAGES, syspkgs); | |
return props; | |
} | |
public String getProperty(String key) { | |
return ac.getBundleContext().getProperty(key); | |
} | |
public ObjectName preRegister(MBeanServer server, ObjectName name) | |
throws Exception { | |
registrator = new MBeanRegistrator(server, ac); | |
return name; | |
} | |
public void postRegister(Boolean registrationDone) { | |
registrator.init(); | |
} | |
public void preDeregister() throws Exception { | |
registrator.dispose(); | |
} | |
public void postDeregister() { | |
} | |
} | |
class MBeanRegistrator { | |
private MBeanServer server; | |
private AgentContext ac; | |
private FrameworkListener fl; | |
private BundleListener bl; | |
private ServiceListener sl; | |
protected MBeanRegistrator(MBeanServer server, AgentContext ac) { | |
this.server = server; | |
this.ac=ac; | |
fl = new FrameworkListener() { | |
public void frameworkEvent(FrameworkEvent event) { | |
if (event.getType() == FrameworkEvent.PACKAGES_REFRESHED) { | |
// We cannot know which are the affected packages, just refresh all | |
//However, registering mbeans is expensive, as it involves reflection | |
//TODO improve this | |
unregisterPackageMBeans(); | |
registerPackageMBeans(); | |
unregisterBundleMBeans(); | |
registerBundleMBeans(); | |
} | |
} | |
}; | |
bl = new BundleListener() { | |
public void bundleChanged(BundleEvent event) { | |
switch (event.getType()){ | |
case BundleEvent.INSTALLED: | |
registerBundleMBean(event.getBundle()); | |
break; | |
case BundleEvent.UNINSTALLED: | |
//Ignore: uninstalled bundles are not removed until refreshed | |
break; | |
case BundleEvent.UPDATED: | |
//Ignore Update | |
break; | |
default: //nothing todo for the rest of the events | |
break; | |
} | |
} | |
}; | |
sl = new ServiceListener() { | |
public void serviceChanged(ServiceEvent event) { | |
switch (event.getType()) { | |
case ServiceEvent.UNREGISTERING: | |
unregisterServiceMBean(event.getServiceReference()); | |
break; | |
case ServiceEvent.REGISTERED: | |
registerServiceMBean(event.getServiceReference()); | |
break; | |
default://nothing todo if MODIFIED | |
break; | |
} | |
} | |
}; | |
} | |
protected void init(){ | |
registerBundleMBeans(); | |
registerServiceMBeans(); | |
registerPackageMBeans(); | |
ac.getBundleContext().addFrameworkListener(fl); | |
ac.getBundleContext().addBundleListener(bl); | |
ac.getBundleContext().addServiceListener(sl); | |
} | |
protected void dispose() { | |
ac.getBundleContext().removeFrameworkListener(fl); | |
ac.getBundleContext().removeBundleListener(bl); | |
ac.getBundleContext().removeServiceListener(sl); | |
unregisterBundleMBeans(); | |
unregisterServiceMBeans(); | |
unregisterPackageMBeans(); | |
} | |
private void unregisterBundleMBeans(){ | |
try { | |
Set bundles = server.queryNames(new ObjectName( | |
ObjectNames.ALLBUNDLES), null); | |
for (Iterator iter = bundles.iterator(); iter.hasNext();) { | |
ObjectName oname = (ObjectName) iter.next(); | |
server.unregisterMBean(oname); | |
} | |
} catch (MalformedObjectNameException mone) { | |
ac.error("unexpected error:", mone); | |
} catch (NullPointerException npe) { | |
//No registered bundle mbeans | |
} catch (InstanceNotFoundException infe) { | |
ac.error("unexpected error:", infe); | |
} catch (MBeanRegistrationException mre) { | |
ac.error("unexpected error:", mre); | |
} | |
} | |
private void unregisterServiceMBeans(){ | |
try { | |
Set services = server.queryNames(new ObjectName( | |
ObjectNames.ALLSERVICES), null); | |
for (Iterator iter = services.iterator(); iter.hasNext();) { | |
ObjectName oname = (ObjectName) iter.next(); | |
server.unregisterMBean(oname); | |
} | |
} catch (MalformedObjectNameException mone) { | |
ac.error("unexpected error:", mone); | |
} catch (NullPointerException npe) { | |
//No registered service mbeans | |
} catch (InstanceNotFoundException infe) { | |
ac.error("unexpected error:", infe); | |
} catch (MBeanRegistrationException mre) { | |
ac.error("unexpected error:", mre); | |
} | |
} | |
private void unregisterPackageMBeans(){ | |
try { | |
Set pkgs = server.queryNames(new ObjectName( | |
ObjectNames.ALLPACKAGES), null); | |
for (Iterator iter = pkgs.iterator(); iter.hasNext();) { | |
ObjectName oname = (ObjectName) iter.next(); | |
server.unregisterMBean(oname); | |
} | |
} catch (MalformedObjectNameException mone) { | |
ac.error("unexpected error:", mone); | |
} catch (NullPointerException npe) { | |
//No registered package mbeans | |
} catch (InstanceNotFoundException infe) { | |
ac.error("unexpected error:", infe); | |
} catch (MBeanRegistrationException mre) { | |
ac.error("unexpected error:", mre); | |
} | |
} | |
private void unregisterServiceMBean(ServiceReference service){ | |
try { | |
server.unregisterMBean(new ObjectName(ObjectNames.SERVICE+service.getProperty(Constants.SERVICE_ID))); | |
} catch (InstanceNotFoundException infe) { | |
ac.error("Unexpected error", infe); | |
} catch (MBeanRegistrationException mre) { | |
ac.error("Unexpected error", mre); | |
} catch (MalformedObjectNameException mone) { | |
ac.error("Unexpected error", mone); | |
} | |
} | |
private void registerBundleMBean(Bundle bundle){ | |
try { | |
server.registerMBean(new ManagedBundle(bundle, ac), | |
new ObjectName(ObjectNames.BUNDLE | |
+ InstrumentationSupport | |
.getSymbolicName(bundle))); | |
ac.debug("registered mbean for " | |
+ bundle.getSymbolicName()); | |
} catch (InstanceAlreadyExistsException iaee) { | |
ac.error("unexpected error:", iaee); | |
} catch (MBeanRegistrationException mre) { | |
ac.error("unexpected error:", mre); | |
} catch (NotCompliantMBeanException ncme) { | |
ac.error("unexpected error:", ncme); | |
} catch (MalformedObjectNameException mone) { | |
ac.error("unexpected error:", mone); | |
} catch (NullPointerException npe) { | |
ac.error("unexpected error:", npe); | |
} | |
} | |
private void registerBundleMBeans(){ | |
Bundle[] bundles = ac.getBundleContext().getBundles(); | |
for (int i = 0; i < bundles.length; i++) { | |
registerBundleMBean(bundles[i]); | |
} | |
} | |
private void registerServiceMBean(ServiceReference service){ | |
try { | |
server.registerMBean(new ManagedService(service), | |
new ObjectName(ObjectNames.SERVICE | |
+ service.getProperty( | |
Constants.SERVICE_ID))); | |
ac.debug("registed mbean for " | |
+ service.getProperty( | |
Constants.SERVICE_ID)); | |
} catch (InstanceAlreadyExistsException iaee) { | |
ac.error("unexpected error:", iaee); | |
} catch (MBeanRegistrationException mre) { | |
ac.error("unexpected error:", mre); | |
} catch (NotCompliantMBeanException ncme) { | |
ac.error("unexpected error:", ncme); | |
} catch (MalformedObjectNameException mone) { | |
ac.error("unexpected error:", mone); | |
} catch (NullPointerException npe) { | |
ac.error("unexpected error:", npe); | |
} | |
} | |
private void registerServiceMBeans(){ | |
try { | |
ServiceReference[] services=ac.getBundleContext().getServiceReferences(null, null); | |
if (services != null) { | |
for (int i = 0; i < services.length; i++) { | |
registerServiceMBean(services[i]); | |
} | |
} else | |
ac.debug("no services found"); | |
} catch (InvalidSyntaxException ie) { | |
ac.error("unexpected error:", ie); | |
} | |
} | |
private void registerPackageMBeans(){ | |
try { | |
ExportedPackage[] pkgs=ac.getPackageadmin().getExportedPackages((Bundle)null); | |
if (pkgs != null) { | |
for (int i = 0; i < pkgs.length; i++) { | |
try { | |
server.registerMBean(new ManagedPackage(pkgs[i]), | |
new ObjectName(ObjectNames.PACKAGE | |
+ InstrumentationSupport.getPackageName(pkgs[i]))); | |
ac.debug("registed mbean for " + InstrumentationSupport.getPackageName(pkgs[i])); | |
} catch (InstanceAlreadyExistsException iaee) { | |
ac.error("unexpected error:", iaee); | |
} catch (MBeanRegistrationException mre) { | |
ac.error("unexpected error:", mre); | |
} catch (NotCompliantMBeanException ncme) { | |
ac.error("unexpected error:", ncme); | |
} catch (MalformedObjectNameException mone) { | |
ac.error("unexpected error:", mone); | |
} catch (NullPointerException npe) { | |
ac.error("unexpected error:", npe); | |
} | |
} | |
} else | |
ac.debug("no packages found"); | |
} catch (ServiceNotAvailableException se) { | |
ac.error("No package admin available", se); | |
} | |
} | |
} | |