package org.jboss.mx.modelmbean;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import javax.management.Descriptor;
import javax.management.InstanceNotFoundException;
import javax.management.ListenerNotFoundException;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MBeanNotificationInfo;
import javax.management.MBeanServer;
import javax.management.NotCompliantMBeanException;
import javax.management.NotificationBroadcaster;
import javax.management.Notification;
import javax.management.NotificationFilter;
import javax.management.NotificationListener;
import javax.management.ObjectName;
import javax.management.RuntimeOperationsException;
import javax.management.StandardMBean;
import javax.management.modelmbean.InvalidTargetObjectTypeException;
import javax.management.modelmbean.ModelMBeanAttributeInfo;
import javax.management.modelmbean.ModelMBeanConstructorInfo;
import javax.management.modelmbean.ModelMBeanInfo;
import javax.management.modelmbean.ModelMBeanInfoSupport;
import javax.management.modelmbean.ModelMBeanNotificationInfo;
import javax.management.modelmbean.ModelMBeanOperationInfo;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.jboss.mx.interceptor.StandardMBeanInfoInterceptor;
import org.jboss.mx.metadata.MBeanInfoConversion;
import org.jboss.mx.metadata.MetaDataBuilder;
import org.jboss.mx.metadata.StandardMetaData;
import org.jboss.mx.metadata.XMLMetaData;
public class XMBean
extends ModelMBeanInvoker
implements XMBeanConstants, NotificationListener
{
public XMBean() throws MBeanException
{
try
{
setManagedResource(new Object(), OBJECT_REF);
setModelMBeanInfo(new ModelMBeanInfoSupport("XMBean", "Uninitialized XMBean", new ModelMBeanAttributeInfo[0],
new ModelMBeanConstructorInfo[0], new ModelMBeanOperationInfo[0], new ModelMBeanNotificationInfo[0]));
}
catch (RuntimeException e)
{
throw new RuntimeOperationsException(e);
}
catch (Exception e)
{
throw new MBeanException(e);
}
}
public XMBean(ModelMBeanInfo info) throws MBeanException
{
super(info);
}
public XMBean(Object resource, String resourceType) throws MBeanException, NotCompliantMBeanException
{
ModelMBeanInfo minfo = null;
try
{
HashMap properties = new HashMap();
if (resourceType.equals(DESCRIPTOR))
{
Descriptor d = (Descriptor)resource;
resourceType = (String)d.getFieldValue(RESOURCE_TYPE);
resource = d.getFieldValue(RESOURCE_REFERENCE);
String[] fields = d.getFieldNames();
for (int i = 0; i < fields.length; ++i)
{
if (fields[i].startsWith(METADATA_DESCRIPTOR_PREFIX))
properties.put(fields[i], d.getFieldValue(fields[i]));
}
}
if (resourceType.equals(STANDARD_MBEAN) && resource instanceof StandardMBean)
setManagedResource(((StandardMBean)resource).getImplementation(), resourceType);
else
setManagedResource(resource, resourceType);
final boolean CREATE_ATTRIBUTE_OPERATION_MAPPING = true;
if (resourceType.equals(STANDARD_MBEAN) &&
resource instanceof StandardMBean)
{
StandardMBean standardMBean = (StandardMBean) resource;
minfo = MBeanInfoConversion.toModelMBeanInfo(standardMBean.getMBeanInfo(),
CREATE_ATTRIBUTE_OPERATION_MAPPING);
}
else if ((resourceType.equals(STANDARD_INTERFACE)) ||
(resourceType.equals(STANDARD_MBEAN)))
{
dynamicResource = false;
MetaDataBuilder builder = new StandardMetaData(resource);
for (Iterator it = properties.keySet().iterator(); it.hasNext();)
{
String key = (String)it.next();
builder.setProperty(key, properties.get(key));
}
MBeanInfo standardInfo = builder.build();
minfo = MBeanInfoConversion.toModelMBeanInfo(standardInfo, CREATE_ATTRIBUTE_OPERATION_MAPPING);
}
else if (resourceType.endsWith(".xml"))
{
MetaDataBuilder builder = new XMLMetaData(
this.getClass().getName(), resource.getClass().getName(), resourceType
);
for (Iterator it = properties.keySet().iterator(); it.hasNext();)
{
String key = (String)it.next();
builder.setProperty(key, properties.get(key));
}
minfo = (ModelMBeanInfo) builder.build();
}
this.setModelMBeanInfo(minfo);
load();
}
catch (InstanceNotFoundException e)
{
throw new MBeanException(e);
}
catch (InvalidTargetObjectTypeException e)
{
if (resourceType.endsWith(".xml"))
throw new MBeanException(e, "Malformed URL: " + resourceType);
throw new MBeanException(e, "Unsupported resource type: " + resourceType);
}
catch (MalformedURLException e)
{
throw new MBeanException(e, "Malformed URL: " + resourceType);
}
}
public XMBean(Object resource, URL interfaceURL) throws MBeanException, NotCompliantMBeanException
{
this(resource, interfaceURL.toString());
}
public XMBean(Descriptor descriptor) throws MBeanException, NotCompliantMBeanException
{
this(descriptor, DESCRIPTOR);
}
public XMBean(Object resource, org.w3c.dom.Element element, String version) throws MBeanException, NotCompliantMBeanException
{
try
{
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
org.w3c.dom.Document doc = builder.newDocument();
doc.appendChild(doc.importNode(element, true));
org.dom4j.io.DOMReader domReader = new org.dom4j.io.DOMReader();
org.dom4j.Document dom4jDoc = domReader.read(doc);
org.dom4j.Element dom4jElem = dom4jDoc.getRootElement();
dom4jElem.detach();
createXMBean(resource, dom4jElem, version);
}
catch (ParserConfigurationException e)
{
throw new MBeanException(e, "Could not convert w3c Element to dom4j Element.");
}
}
public XMBean(Object resource, org.dom4j.Element element, String version) throws MBeanException, NotCompliantMBeanException
{
createXMBean(resource, element, version);
}
private void createXMBean(Object resource, org.dom4j.Element element, String version)
throws MBeanException, NotCompliantMBeanException
{
try
{
setManagedResource(resource, OBJECT_REF);
MetaDataBuilder builder = new XMLMetaData(
this.getClass().getName(), resource.getClass().getName(), element,
version
);
ModelMBeanInfo minfo = (ModelMBeanInfo) builder.build();
this.setModelMBeanInfo(minfo);
}
catch (InstanceNotFoundException e)
{
throw new MBeanException(e);
}
catch (InvalidTargetObjectTypeException e)
{
throw new MBeanException(e, "Unsupported resource type: " + resourceType);
}
}
public boolean isSupportedResourceType(Object resource, String resourceType)
{
if (resourceType == null)
return false;
if (resourceType.equalsIgnoreCase(OBJECT_REF))
return true;
if (resourceType.equalsIgnoreCase(STANDARD_INTERFACE))
return true;
if (resourceType.equalsIgnoreCase(STANDARD_MBEAN))
return true;
if (resourceType.equalsIgnoreCase(DESCRIPTOR))
{
if (resource == null || !(resource instanceof Descriptor))
return false;
Descriptor d = (Descriptor)resource;
if (d.getFieldValue(RESOURCE_REFERENCE) == null)
return false;
if (d.getFieldValue(RESOURCE_TYPE) == null)
return false;
return true;
}
if (resourceType.endsWith(".xml"))
{
try
{
new URL(resourceType);
return true;
}
catch (MalformedURLException e)
{
return false;
}
}
return false;
}
protected void configureInterceptorStack(ModelMBeanInfo info,
MBeanServer server, ObjectName name)
throws Exception
{
super.configureInterceptorStack(info, server, name);
if (resourceType.equals(STANDARD_MBEAN))
{
List interceptors = getMBeanInfoCtx.getInterceptors();
interceptors.add(0, new StandardMBeanInfoInterceptor());
getMBeanInfoCtx.setInterceptors(interceptors);
}
}
public void addNotificationListener(NotificationListener listener,
NotificationFilter filter, Object handback)
{
if (resourceType.equals(STANDARD_MBEAN))
{
addNotificationListenerToResource(listener, filter, handback);
}
else
{
super.addNotificationListener(listener, filter, handback);
if (getResource() instanceof NotificationBroadcaster)
addNotificationListenerToResource(listener, filter, handback);
}
}
public void removeNotificationListener(NotificationListener listener)
throws ListenerNotFoundException
{
if (resourceType.equals(STANDARD_MBEAN))
{
removeNotificationListenerFromResource(listener);
}
else
{
super.removeNotificationListener(listener);
if (getResource() instanceof NotificationBroadcaster)
removeNotificationListenerFromResource(listener);
}
}
public void removeNotificationListener(NotificationListener listener,
NotificationFilter filter,
Object handback)
throws ListenerNotFoundException
{
if (resourceType.equals(STANDARD_MBEAN))
{
removeNotificationListenerFromResource(listener, filter, handback);
}
else
{
super.removeNotificationListener(listener, filter, handback);
if (getResource() instanceof NotificationBroadcaster)
removeNotificationListenerFromResource(listener, filter, handback);
}
}
public MBeanNotificationInfo[] getNotificationInfo()
{
if (resourceType.equals(STANDARD_MBEAN))
return getNotificationInfoFromResource();
else
return super.getNotificationInfo();
}
public void handleNotification(Notification notification, Object handback)
{
Object resource = getResource();
if (resource instanceof NotificationListener)
((NotificationListener)resource).handleNotification(notification, handback);
}
}