dain 2003/11/09 12:04:45
Modified: modules/kernel/src/java/org/apache/geronimo/kernel/service
GeronimoMBeanInfo.java
Log:
Added support for targets that have the GeronimoMBeanTarget methods as
protected
methods. The target does not need to implement the GeronimoMBeanTarget
interface
and we can still invoke the call backs, because we now code generate a
subclass that
adds in the GeronimoMBeanTarget interface.
Revision Changes Path
1.4 +98 -17
incubator-geronimo/modules/kernel/src/java/org/apache/geronimo/kernel/service/GeronimoMBeanInfo.java
Index: GeronimoMBeanInfo.java
===================================================================
RCS file:
/home/cvs/incubator-geronimo/modules/kernel/src/java/org/apache/geronimo/kernel/service/GeronimoMBeanInfo.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- GeronimoMBeanInfo.java 6 Nov 2003 19:58:45 -0000 1.3
+++ GeronimoMBeanInfo.java 9 Nov 2003 20:04:45 -0000 1.4
@@ -55,6 +55,8 @@
*/
package org.apache.geronimo.kernel.service;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -67,9 +69,13 @@
import javax.management.MBeanNotificationInfo;
import javax.management.MBeanOperationInfo;
-import org.apache.geronimo.kernel.service.ParserUtil;
-import org.apache.geronimo.kernel.service.GeronimoAttributeInfo;
-
+import net.sf.cglib.proxy.CallbackFilter;
+import net.sf.cglib.proxy.Callbacks;
+import net.sf.cglib.proxy.Enhancer;
+import net.sf.cglib.proxy.Factory;
+import net.sf.cglib.proxy.MethodInterceptor;
+import net.sf.cglib.proxy.MethodProxy;
+import net.sf.cglib.proxy.SimpleCallbacks;
import net.sf.cglib.reflect.FastClass;
/**
@@ -139,21 +145,20 @@
Map.Entry entry = (Map.Entry) i.next();
className = (String) entry.getValue();
Class clazz = ParserUtil.loadClass(className);
- Object target = clazz.newInstance();
+
+ if(Modifier.isFinal(clazz.getModifiers())) {
+ throw new IllegalArgumentException("Target class cannot
be final: " + className);
+ }
+
+ // Insert Magic Here
+ GeronimoMBeanTarget target = createTarget(clazz);
+ //Object target = clazz.newInstance();
targets.put(entry.getKey(), target);
FastClass fastClass = FastClass.create(clazz);
targetFastClasses.put(entry.getKey(), fastClass);
}
} catch (ClassNotFoundException e) {
throw new IllegalArgumentException("Target class could not be
loaded: className=" + className);
- } catch (InstantiationException e) {
- IllegalArgumentException exception = new
IllegalArgumentException("Target class could not be loaded: className=" +
className);
- exception.initCause(e);
- throw exception;
- } catch (IllegalAccessException e) {
- IllegalArgumentException exception = new
IllegalArgumentException("Cound not access target class default constructor:
className=" + className);
- exception.initCause(e);
- throw exception;
}
//
@@ -220,14 +225,14 @@
}
FastClass getTargetFastClass() {
- return (FastClass)targetFastClasses.get(DEFAULT_TARGET_NAME);
+ return (FastClass) targetFastClasses.get(DEFAULT_TARGET_NAME);
}
FastClass getTargetFastClass(String name) {
- if(GERONIMO_MBEAN_TARGET_NAME.equals(name)) {
+ if (GERONIMO_MBEAN_TARGET_NAME.equals(name)) {
return GeronimoMBean.fastClass;
}
- return (FastClass)targetFastClasses.get(name);
+ return (FastClass) targetFastClasses.get(name);
}
public String getName() {
@@ -317,6 +322,82 @@
endpoints.add(endpoint);
}
+ private GeronimoMBeanTarget createTarget(Class superClass) {
+ Enhancer enhancer = new Enhancer();
+ enhancer.setSuperclass(superClass);
+ enhancer.setInterfaces(new Class[]{GeronimoMBeanTarget.class});
+ enhancer.setCallbackFilter(new TargetCallbackFilter(superClass));
+ enhancer.setCallbacks(new SimpleCallbacks());
+ Factory factory = enhancer.create();
+ return (GeronimoMBeanTarget)
factory.newInstance(NO_OP_METHOD_INTERCEPTOR);
+ }
+
+ private static final class TargetCallbackFilter implements
CallbackFilter {
+ private final Class superClass;
+
+ public TargetCallbackFilter(Class superClass) {
+ this.superClass = superClass;
+ }
+
+ public int accept(Method method) {
+ String name = method.getName();
+ Class[] parameterTypes = method.getParameterTypes();
+ if (parameterTypes.length == 0 &&
+ method.getReturnType() == Void.TYPE &&
+ method.getExceptionTypes().length == 0 &&
+ ("doStart".equals(name) || "doStop".equals(name) ||
"doFail".equals(name))) {
+
+ try {
+ superClass.getMethod(name, null);
+ return Callbacks.NO_OP;
+ } catch (Exception e) {
+ return Callbacks.INTERCEPT;
+ }
+ }
+
+ if (parameterTypes.length == 0 &&
+ method.getReturnType() == Boolean.TYPE &&
+ method.getExceptionTypes().length == 0 &&
+ ("canStart".equals(name) || "canStop".equals(name))) {
+
+ try {
+ superClass.getMethod(name, null);
+ return Callbacks.NO_OP;
+ } catch (Exception e) {
+ return Callbacks.INTERCEPT;
+ }
+ }
+
+ if (parameterTypes.length == 1 && parameterTypes[0] ==
GeronimoMBeanContext.class &&
+ "setMBeanContext".equals(name) &&
+ method.getReturnType() == Void.TYPE &&
+ method.getExceptionTypes().length == 0) {
+
+ try {
+ superClass.getMethod("setContext", parameterTypes);
+ return Callbacks.NO_OP;
+ } catch (Exception e) {
+ return Callbacks.INTERCEPT;
+ }
+ }
+ return Callbacks.NO_OP;
+ }
+ }
+
+ private static final MethodInterceptor NO_OP_METHOD_INTERCEPTOR = new
MethodInterceptor() {
+ public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
+ if (Modifier.isAbstract(method.getModifiers())) {
+ if(method.getReturnType() == Boolean.TYPE) {
+ return Boolean.TRUE;
+ } else {
+ return null;
+ }
+ }
+ return proxy.invokeSuper(obj, args);
+ }
+ };
+
+
public int hashCode() {
return hashCode;
}
@@ -328,4 +409,4 @@
public String toString() {
return "[GeronimoMBeanInfo: name=" + name + " description=" +
description + "]";
}
-}
+}
\ No newline at end of file