📄 basemodelmbean.java
字号:
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.tomcat.util.modeler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Iterator;
import javax.management.Attribute;
import javax.management.AttributeChangeNotification;
import javax.management.AttributeList;
import javax.management.AttributeNotFoundException;
import javax.management.DynamicMBean;
import javax.management.InstanceNotFoundException;
import javax.management.InvalidAttributeValueException;
import javax.management.ListenerNotFoundException;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MBeanNotificationInfo;
import javax.management.MBeanRegistration;
import javax.management.MBeanServer;
import javax.management.Notification;
import javax.management.NotificationFilter;
import javax.management.NotificationListener;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import javax.management.RuntimeErrorException;
import javax.management.RuntimeOperationsException;
import javax.management.modelmbean.InvalidTargetObjectTypeException;
import javax.management.modelmbean.ModelMBeanNotificationBroadcaster;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
/*
* Changes from commons.modeler:
*
* - use DynamicMBean
* - remove methods not used in tomcat and redundant/not very generic
* - must be created from the ManagedBean - I don't think there were any direct
* uses, but now it is required.
* - some of the gratuituous flexibility removed - instead this is more predictive and
* strict with the use cases.
* - all Method and metadata is stored in ManagedBean. BaseModelBMean and ManagedBean act
* like Object and Class.
* - setModelMBean is no longer called on resources ( not used in tomcat )
* - no caching of Methods for now - operations and setters are not called repeatedly in most
* management use cases. Getters should't be called very frequently either - and even if they
* are, the overhead of getting the method should be small compared with other JMX costs ( RMI, etc ).
* We can add getter cache if needed.
* - removed unused constructor, fields
*
* TODO:
* - clean up catalina.mbeans, stop using weird inheritance
*/
/**
* <p>Basic implementation of the <code>DynamicMBean</code> interface, which
* supports the minimal requirements of the interface contract.</p>
*
* <p>This can be used directly to wrap an existing java bean, or inside
* an mlet or anywhere an MBean would be used.
*
* Limitations:
* <ul>
* <li>Only managed resources of type <code>objectReference</code> are
* supportd.</li>
* <li>Caching of attribute values and operation results is not supported.
* All calls to <code>invoke()</code> are immediately executed.</li>
* <li>Persistence of MBean attributes and operations is not supported.</li>
* <li>All classes referenced as attribute types, operation parameters, or
* operation return values must be one of the following:
* <ul>
* <li>One of the Java primitive types (boolean, byte, char, double,
* float, integer, long, short). Corresponding value will be wrapped
* in the appropriate wrapper class automatically.</li>
* <li>Operations that return no value should declare a return type of
* <code>void</code>.</li>
* </ul>
* <li>Attribute caching is not supported</li>
* </ul>
*
* @author Craig R. McClanahan
* @author Costin Manolache
*/
public class BaseModelMBean implements DynamicMBean, MBeanRegistration, ModelMBeanNotificationBroadcaster {
private static Log log = LogFactory.getLog(BaseModelMBean.class);
// ----------------------------------------------------------- Constructors
/**
* Construct a <code>ModelMBean</code> with default
* <code>ModelMBeanInfo</code> information.
*
* @exception MBeanException if the initializer of an object
* throws an exception
* @exception RuntimeOperationsException if an IllegalArgumentException
* occurs
*/
protected BaseModelMBean() throws MBeanException, RuntimeOperationsException {
super();
}
// ----------------------------------------------------- Instance Variables
protected ObjectName oname=null;
/**
* Notification broadcaster for attribute changes.
*/
protected BaseNotificationBroadcaster attributeBroadcaster = null;
/**
* Notification broadcaster for general notifications.
*/
protected BaseNotificationBroadcaster generalBroadcaster = null;
/** Metadata for the mbean instance.
*/
protected ManagedBean managedBean = null;
/**
* The managed resource this MBean is associated with (if any).
*/
protected Object resource = null;
// --------------------------------------------------- DynamicMBean Methods
// TODO: move to ManagedBean
static final Object[] NO_ARGS_PARAM=new Object[0];
static final Class[] NO_ARGS_PARAM_SIG=new Class[0];
protected String resourceType = null;
// key: operation val: invoke method
//private Hashtable invokeAttMap=new Hashtable();
/**
* Obtain and return the value of a specific attribute of this MBean.
*
* @param name Name of the requested attribute
*
* @exception AttributeNotFoundException if this attribute is not
* supported by this MBean
* @exception MBeanException if the initializer of an object
* throws an exception
* @exception ReflectionException if a Java reflection exception
* occurs when invoking the getter
*/
public Object getAttribute(String name)
throws AttributeNotFoundException, MBeanException,
ReflectionException {
// Validate the input parameters
if (name == null)
throw new RuntimeOperationsException
(new IllegalArgumentException("Attribute name is null"),
"Attribute name is null");
if( (resource instanceof DynamicMBean) &&
! ( resource instanceof BaseModelMBean )) {
return ((DynamicMBean)resource).getAttribute(name);
}
Method m=managedBean.getGetter(name, this, resource);
Object result = null;
try {
Class declaring=m.getDeclaringClass();
// workaround for catalina weird mbeans - the declaring class is BaseModelMBean.
// but this is the catalina class.
if( declaring.isAssignableFrom(this.getClass()) ) {
result = m.invoke(this, NO_ARGS_PARAM );
} else {
result = m.invoke(resource, NO_ARGS_PARAM );
}
} catch (InvocationTargetException e) {
Throwable t = e.getTargetException();
if (t == null)
t = e;
if (t instanceof RuntimeException)
throw new RuntimeOperationsException
((RuntimeException) t, "Exception invoking method " + name);
else if (t instanceof Error)
throw new RuntimeErrorException
((Error) t, "Error invoking method " + name);
else
throw new MBeanException
(e, "Exception invoking method " + name);
} catch (Exception e) {
throw new MBeanException
(e, "Exception invoking method " + name);
}
// Return the results of this method invocation
// FIXME - should we validate the return type?
return (result);
}
/**
* Obtain and return the values of several attributes of this MBean.
*
* @param names Names of the requested attributes
*/
public AttributeList getAttributes(String names[]) {
// Validate the input parameters
if (names == null)
throw new RuntimeOperationsException
(new IllegalArgumentException("Attribute names list is null"),
"Attribute names list is null");
// Prepare our response, eating all exceptions
AttributeList response = new AttributeList();
for (int i = 0; i < names.length; i++) {
try {
response.add(new Attribute(names[i],getAttribute(names[i])));
} catch (Exception e) {
; // Not having a particular attribute in the response
; // is the indication of a getter problem
}
}
return (response);
}
public void setManagedBean(ManagedBean managedBean) {
this.managedBean = managedBean;
}
/**
* Return the <code>MBeanInfo</code> object for this MBean.
*/
public MBeanInfo getMBeanInfo() {
return managedBean.getMBeanInfo();
}
/**
* Invoke a particular method on this MBean, and return any returned
* value.
*
* <p><strong>IMPLEMENTATION NOTE</strong> - This implementation will
* attempt to invoke this method on the MBean itself, or (if not
* available) on the managed resource object associated with this
* MBean.</p>
*
* @param name Name of the operation to be invoked
* @param params Array containing the method parameters of this operation
* @param signature Array containing the class names representing
* the signature of this operation
*
* @exception MBeanException if the initializer of an object
* throws an exception
* @exception ReflectioNException if a Java reflection exception
* occurs when invoking a method
*/
public Object invoke(String name, Object params[], String signature[])
throws MBeanException, ReflectionException
{
if( (resource instanceof DynamicMBean) &&
! ( resource instanceof BaseModelMBean )) {
return ((DynamicMBean)resource).invoke(name, params, signature);
}
// Validate the input parameters
if (name == null)
throw new RuntimeOperationsException
(new IllegalArgumentException("Method name is null"),
"Method name is null");
if( log.isDebugEnabled()) log.debug("Invoke " + name);
MethodKey mkey = new MethodKey(name, signature);
Method method= managedBean.getInvoke(name, params, signature, this, resource);
// Invoke the selected method on the appropriate object
Object result = null;
try {
if( method.getDeclaringClass().isAssignableFrom( this.getClass()) ) {
result = method.invoke(this, params );
} else {
result = method.invoke(resource, params);
}
} catch (InvocationTargetException e) {
Throwable t = e.getTargetException();
log.error("Exception invoking method " + name , t );
if (t == null)
t = e;
if (t instanceof RuntimeException)
throw new RuntimeOperationsException
((RuntimeException) t, "Exception invoking method " + name);
else if (t instanceof Error)
throw new RuntimeErrorException
((Error) t, "Error invoking method " + name);
else
throw new MBeanException
((Exception)t, "Exception invoking method " + name);
} catch (Exception e) {
log.error("Exception invoking method " + name , e );
throw new MBeanException
(e, "Exception invoking method " + name);
}
// Return the results of this method invocation
// FIXME - should we validate the return type?
return (result);
}
static Class getAttributeClass(String signature)
throws ReflectionException
{
if (signature.equals(Boolean.TYPE.getName()))
return Boolean.TYPE;
else if (signature.equals(Byte.TYPE.getName()))
return Byte.TYPE;
else if (signature.equals(Character.TYPE.getName()))
return Character.TYPE;
else if (signature.equals(Double.TYPE.getName()))
return Double.TYPE;
else if (signature.equals(Float.TYPE.getName()))
return Float.TYPE;
else if (signature.equals(Integer.TYPE.getName()))
return Integer.TYPE;
else if (signature.equals(Long.TYPE.getName()))
return Long.TYPE;
else if (signature.equals(Short.TYPE.getName()))
return Short.TYPE;
else {
try {
ClassLoader cl=Thread.currentThread().getContextClassLoader();
if( cl!=null )
return cl.loadClass(signature);
} catch( ClassNotFoundException e ) {
}
try {
return Class.forName(signature);
} catch (ClassNotFoundException e) {
throw new ReflectionException
(e, "Cannot find Class for " + signature);
}
}
}
/**
* Set the value of a specific attribute of this MBean.
*
* @param attribute The identification of the attribute to be set
* and the new value
*
* @exception AttributeNotFoundException if this attribute is not
* supported by this MBean
* @exception MBeanException if the initializer of an object
* throws an exception
* @exception ReflectionException if a Java reflection exception
* occurs when invoking the getter
*/
public void setAttribute(Attribute attribute)
throws AttributeNotFoundException, MBeanException,
ReflectionException
{
if( log.isDebugEnabled() )
log.debug("Setting attribute " + this + " " + attribute );
if( (resource instanceof DynamicMBean) &&
! ( resource instanceof BaseModelMBean )) {
try {
((DynamicMBean)resource).setAttribute(attribute);
} catch (InvalidAttributeValueException e) {
throw new MBeanException(e);
}
return;
}
// Validate the input parameters
if (attribute == null)
throw new RuntimeOperationsException
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -