You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by co...@apache.org on 2002/08/08 07:36:54 UTC
cvs commit: jakarta-commons/modeler/src/java/org/apache/commons/modeler BaseModelMBean.java ManagedBean.java
costin 2002/08/07 22:36:54
Modified: modeler/src/java/org/apache/commons/modeler
BaseModelMBean.java ManagedBean.java
Log:
As posted to the list, added a cache for the Method. Acording the JMX spec
you can't have multiple signatures for an attribute name - so no need to
use it in the cache key.
To keep it working with the 'dual' use of BaseModelMBean ( normal and
'extend' ) we use getDefiningClass(). That will work only for single-level
extensions of BaseModelMBean.
AFAIK RequiredModelMBean doesn't even support the 'extend' model, and
we should avoid using it ( it also makes code a bit complex ).
Revision Changes Path
1.3 +236 -115 jakarta-commons/modeler/src/java/org/apache/commons/modeler/BaseModelMBean.java
Index: BaseModelMBean.java
===================================================================
RCS file: /home/cvs/jakarta-commons/modeler/src/java/org/apache/commons/modeler/BaseModelMBean.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- BaseModelMBean.java 15 Jun 2002 18:17:02 -0000 1.2
+++ BaseModelMBean.java 8 Aug 2002 05:36:54 -0000 1.3
@@ -69,6 +69,7 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Iterator;
+import java.util.Hashtable;
import javax.management.Attribute;
import javax.management.AttributeChangeNotification;
import javax.management.AttributeList;
@@ -196,6 +197,16 @@
// --------------------------------------------------- DynamicMBean Methods
+ static final Object[] NO_ARGS_PARAM=new Object[0];
+ static final Class[] NO_ARGS_PARAM_SIG=new Class[0];
+ // key: attribute val: getter method
+ Hashtable getAttMap=new Hashtable();
+
+ // key: attribute val: setter method
+ Hashtable setAttMap=new Hashtable();
+
+ // key: operation val: invoke method
+ Hashtable invokeAttMap=new Hashtable();
/**
@@ -213,32 +224,79 @@
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");
- // Look up the actual operation to be used
- ModelMBeanAttributeInfo attrInfo = info.getAttribute(name);
- if (attrInfo == null)
- throw new AttributeNotFoundException
- ("Cannot find attribute " + name);
- Descriptor attrDesc = attrInfo.getDescriptor();
- if (attrDesc == null)
- throw new AttributeNotFoundException
- ("Cannot find attribute " + name + " descriptor");
- String getMethod = (String) attrDesc.getFieldValue("getMethod");
- if (getMethod == null)
- throw new AttributeNotFoundException
- ("Cannot find attribute " + name + " get method name");
-
- // Invoke the specified get method and return the results
- return (invoke(getMethod,
- new Object[] { },
- new String[] { }));
+ // Extract the method from cache
+ Method m=(Method)getAttMap.get( name );
+ if( m==null ) {
+ // Look up the actual operation to be used
+ ModelMBeanAttributeInfo attrInfo = info.getAttribute(name);
+ if (attrInfo == null)
+ throw new AttributeNotFoundException(" Cannot find attribute " + name);
+ Descriptor attrDesc = attrInfo.getDescriptor();
+ if (attrDesc == null)
+ throw new AttributeNotFoundException("Cannot find attribute " + name + " descriptor");
+ String getMethod = (String) attrDesc.getFieldValue("getMethod");
+
+ if (getMethod == null)
+ throw new AttributeNotFoundException("Cannot find attribute " + name + " get method name");
+
+ Object object = null;
+ NoSuchMethodException exception = null;
+ try {
+ object = this;
+ m = object.getClass().getMethod(getMethod, NO_ARGS_PARAM_SIG);
+ } catch (NoSuchMethodException e) {
+ exception = e;;
+ }
+ if( m== null && resource != null ) {
+ try {
+ object = resource;
+ m = object.getClass().getMethod(getMethod, NO_ARGS_PARAM_SIG);
+ exception=null;
+ } catch (NoSuchMethodException e) {
+ exception = e;
+ }
+ }
+ if( exception != null )
+ throw new ReflectionException(exception,
+ "Cannot find getter method " + getMethod);
+ getAttMap.put( name, m );
+ }
+
+ Object result = null;
+ try {
+ if( m.getDeclaringClass() == 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);
}
@@ -274,9 +332,8 @@
* Return the <code>MBeanInfo</code> object for this MBean.
*/
public MBeanInfo getMBeanInfo() {
-
+ // XXX Why do we have to clone ?
return ((MBeanInfo) info.clone());
-
}
@@ -307,84 +364,70 @@
throw new RuntimeOperationsException
(new IllegalArgumentException("Method name is null"),
"Method name is null");
- if (params == null)
- params = new Object[0];
- if (signature == null)
- signature = new String[0];
- if (params.length != signature.length)
- throw new RuntimeOperationsException
- (new IllegalArgumentException("Inconsistent arguments and signature"),
- "Inconsistent arguments and signature");
-
- // Acquire the ModelMBeanOperationInfo information for
- // the requested operation
- ModelMBeanOperationInfo opInfo = info.getOperation(name);
- if (opInfo == null)
- throw new MBeanException
- (new ServiceNotFoundException("Cannot find operation " + name),
- "Cannot find operation " + name);
- // Prepare the signature required by Java reflection APIs
- // FIXME - should we use the signature from opInfo?
- Class types[] = new Class[signature.length];
- for (int i = 0; i < signature.length; i++) {
- if (signature[i].equals(Boolean.TYPE.getName()))
- types[i] = Boolean.TYPE;
- else if (signature[i].equals(Byte.TYPE.getName()))
- types[i] = Byte.TYPE;
- else if (signature[i].equals(Character.TYPE.getName()))
- types[i] = Character.TYPE;
- else if (signature[i].equals(Double.TYPE.getName()))
- types[i] = Double.TYPE;
- else if (signature[i].equals(Float.TYPE.getName()))
- types[i] = Float.TYPE;
- else if (signature[i].equals(Integer.TYPE.getName()))
- types[i] = Integer.TYPE;
- else if (signature[i].equals(Long.TYPE.getName()))
- types[i] = Long.TYPE;
- else if (signature[i].equals(Short.TYPE.getName()))
- types[i] = Short.TYPE;
- else {
- try {
- types[i] = Class.forName(signature[i]);
- } catch (ClassNotFoundException e) {
- throw new ReflectionException
- (e, "Cannot find Class for " + signature[i]);
- }
+ Method method=(Method)invokeAttMap.get(name);
+ if( method==null ) {
+ if (params == null)
+ params = new Object[0];
+ if (signature == null)
+ signature = new String[0];
+ if (params.length != signature.length)
+ throw new RuntimeOperationsException
+ (new IllegalArgumentException("Inconsistent arguments and signature"),
+ "Inconsistent arguments and signature");
+
+ // Acquire the ModelMBeanOperationInfo information for
+ // the requested operation
+ ModelMBeanOperationInfo opInfo = info.getOperation(name);
+ if (opInfo == null)
+ throw new MBeanException
+ (new ServiceNotFoundException("Cannot find operation " + name),
+ "Cannot find operation " + name);
+
+ // Prepare the signature required by Java reflection APIs
+ // FIXME - should we use the signature from opInfo?
+ Class types[] = new Class[signature.length];
+ for (int i = 0; i < signature.length; i++) {
+ types[i]=getAttributeClass( signature[i] );
}
- }
- // Locate the method to be invoked, either in this MBean itself
- // or in the corresponding managed resource
- // FIXME - Accessible methods in superinterfaces?
- Method method = null;
- Object object = null;
- Exception exception = null;
- try {
- object = this;
- method = object.getClass().getMethod(name, types);
- } catch (NoSuchMethodException e) {
- exception = e;;
- }
- try {
- if ((method == null) && (resource != null)) {
- object = resource;
+ // Locate the method to be invoked, either in this MBean itself
+ // or in the corresponding managed resource
+ // FIXME - Accessible methods in superinterfaces?
+ Object object = null;
+ Exception exception = null;
+ try {
+ object = this;
method = object.getClass().getMethod(name, types);
+ } catch (NoSuchMethodException e) {
+ exception = e;;
}
- } catch (NoSuchMethodException e) {
- exception = e;
- }
- if (method == null) {
- throw new ReflectionException(exception,
- "Cannot find method " + name +
- " with this signature");
+ try {
+ if ((method == null) && (resource != null)) {
+ object = resource;
+ method = object.getClass().getMethod(name, types);
+ }
+ } catch (NoSuchMethodException e) {
+ exception = e;
+ }
+ if (method == null) {
+ throw new ReflectionException(exception,
+ "Cannot find method " + name +
+ " with this signature");
+ }
+ invokeAttMap.put( name, method );
}
-
+
// Invoke the selected method on the appropriate object
Object result = null;
try {
- result = method.invoke(object, params);
+ if( method.getDeclaringClass() == this.getClass() ) {
+ result = method.invoke(this, params );
+ } else {
+ result = method.invoke(resource, params);
+ }
} catch (InvocationTargetException e) {
+ log.error("Exception invoking method " + name , e );
Throwable t = e.getTargetException();
if (t == null)
t = e;
@@ -398,6 +441,7 @@
throw new MBeanException
(e, "Exception invoking method " + name);
} catch (Exception e) {
+ log.error("Exception invoking method " + name , e );
throw new MBeanException
(e, "Exception invoking method " + name);
}
@@ -408,6 +452,34 @@
}
+ private 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 {
+ 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.
@@ -424,13 +496,15 @@
*/
public void setAttribute(Attribute attribute)
throws AttributeNotFoundException, MBeanException,
- ReflectionException {
-
+ ReflectionException
+ {
+ // XXX Send attribute changed notification !!!
// Validate the input parameters
if (attribute == null)
throw new RuntimeOperationsException
(new IllegalArgumentException("Attribute is null"),
"Attribute is null");
+
String name = attribute.getName();
Object value = attribute.getValue();
if (name == null)
@@ -438,25 +512,72 @@
(new IllegalArgumentException("Attribute name is null"),
"Attribute name is null");
- // Look up the actual operation to be used
- ModelMBeanAttributeInfo attrInfo = info.getAttribute(name);
- if (attrInfo == null)
- throw new AttributeNotFoundException
- ("Cannot find attribute " + name);
- Descriptor attrDesc = attrInfo.getDescriptor();
- if (attrDesc == null)
- throw new AttributeNotFoundException
- ("Cannot find attribute " + name + " descriptor");
- String setMethod = (String) attrDesc.getFieldValue("setMethod");
- if (setMethod == null)
- throw new AttributeNotFoundException
- ("Cannot find attribute " + name + " set method name");
-
- // Invoke the specified set method and ignore any results
- invoke(setMethod,
- new Object[] { value },
- new String[] { attrInfo.getType() });
+ // Extract the method from cache
+ Method m=(Method)setAttMap.get( name );
+ if( m==null ) {
+ // Look up the actual operation to be used
+ ModelMBeanAttributeInfo attrInfo = info.getAttribute(name);
+ if (attrInfo == null)
+ throw new AttributeNotFoundException("Cannot find attribute " + name);
+ Descriptor attrDesc = attrInfo.getDescriptor();
+ if (attrDesc == null)
+ throw new AttributeNotFoundException("Cannot find attribute " + name + " descriptor");
+ String setMethod = (String) attrDesc.getFieldValue("setMethod");
+ if (setMethod == null)
+ throw new AttributeNotFoundException("Cannot find attribute " + name + " set method name");
+
+ String argType=attrInfo.getType();
+ Class signature[] = new Class[] { getAttributeClass( argType ) };
+
+ Object object = null;
+ NoSuchMethodException exception = null;
+ try {
+ object = this;
+ m = object.getClass().getMethod(setMethod, signature);
+ } catch (NoSuchMethodException e) {
+ exception = e;;
+ }
+ if( m== null && resource != null ) {
+ try {
+ object = resource;
+ m = object.getClass().getMethod(setMethod, signature);
+ exception=null;
+ } catch (NoSuchMethodException e) {
+ exception = e;
+ }
+ }
+ if( exception != null )
+ throw new ReflectionException(exception,
+ "Cannot find setter method " + setMethod);
+ setAttMap.put( name, m );
+ }
+
+ Object result = null;
+ try {
+ if( m.getDeclaringClass() == this.getClass() ) {
+ result = m.invoke(this, new Object[] { value });
+ } else {
+ result = m.invoke(resource, new Object[] { value });
+ }
+ } 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) {
+ log.error("Exception invoking method " + name , e );
+ throw new MBeanException
+ (e, "Exception invoking method " + name);
+ }
}
@@ -1006,10 +1127,10 @@
* @param info The <code>ModelMBeanInfo object to check
*/
protected boolean isModelMBeanInfoValid(ModelMBeanInfo info) {
-
return (true);
-
}
+ private static org.apache.commons.logging.Log log=
+ org.apache.commons.logging.LogFactory.getLog( BaseModelMBean.class );
}
1.2 +7 -6 jakarta-commons/modeler/src/java/org/apache/commons/modeler/ManagedBean.java
Index: ManagedBean.java
===================================================================
RCS file: /home/cvs/jakarta-commons/modeler/src/java/org/apache/commons/modeler/ManagedBean.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ManagedBean.java 30 Apr 2002 20:58:51 -0000 1.1
+++ ManagedBean.java 8 Aug 2002 05:36:54 -0000 1.2
@@ -308,7 +308,6 @@
* @param operation The new operation descriptor
*/
public void addOperation(OperationInfo operation) {
-
synchronized (operations) {
OperationInfo results[] =
new OperationInfo[operations.length + 1];
@@ -441,6 +440,7 @@
for (int i = 0; i < opers.length; i++)
operations[i] = opers[i].createOperationInfo();
+ /*
// Add operations for attribute getters and setters as needed
ArrayList list = new ArrayList();
for (int i = 0; i < operations.length; i++)
@@ -465,7 +465,8 @@
if (list.size() > operations.length)
operations =
(ModelMBeanOperationInfo[]) list.toArray(operations);
-
+ */
+
// Construct and return a new ModelMBeanInfo object
info = new ModelMBeanInfoSupport
(getClassName(), getDescription(),
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>