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
  
  
  

Reply via email to