1 17 package org.apache.geronimo.kernel.jmx; 18 19 import java.lang.reflect.Method ; 20 import java.lang.reflect.Modifier ; 21 import javax.management.ObjectName ; 22 23 import net.sf.cglib.asm.Type; 24 import net.sf.cglib.core.Signature; 25 import net.sf.cglib.proxy.MethodInterceptor; 26 import net.sf.cglib.proxy.MethodProxy; 27 import net.sf.cglib.reflect.FastClass; 28 import org.apache.geronimo.kernel.Kernel; 29 import org.apache.geronimo.kernel.basic.KernelGetAttributeInvoker; 30 import org.apache.geronimo.kernel.basic.KernelOperationInvoker; 31 import org.apache.geronimo.kernel.basic.KernelSetAttributeInvoker; 32 import org.apache.geronimo.kernel.basic.ProxyInvoker; 33 import org.apache.geronimo.kernel.proxy.DeadProxyException; 34 import org.apache.geronimo.kernel.proxy.ProxyManager; 35 36 39 public class JMXProxyMethodInterceptor implements MethodInterceptor { 40 43 private final Class proxyType; 44 45 48 private final ObjectName objectName; 49 50 53 private ProxyInvoker[] gbeanInvokers; 54 55 public JMXProxyMethodInterceptor(Class proxyType, Kernel kernel, ObjectName objectName) { 56 assert proxyType != null; 57 assert kernel != null; 58 assert objectName != null; 59 60 this.proxyType = proxyType; 61 this.objectName = objectName; 62 gbeanInvokers = createGBeanInvokers(kernel); 63 } 64 65 public synchronized void destroy() { 66 gbeanInvokers = null; 67 } 68 69 public ObjectName getObjectName() { 70 return objectName; 71 } 72 73 public final Object intercept(final Object object, final Method method, final Object [] args, final MethodProxy proxy) throws Throwable { 74 ProxyInvoker gbeanInvoker; 75 76 int interfaceIndex = proxy.getSuperIndex(); 77 synchronized (this) { 78 if (gbeanInvokers == null) { 79 throw new DeadProxyException("Proxy is no longer valid"); 80 } 81 gbeanInvoker = gbeanInvokers[interfaceIndex]; 82 } 83 84 if (gbeanInvoker == null) { 85 throw new UnsupportedOperationException ("No implementation method: objectName=" + objectName + ", method=" + method); 86 } 87 88 return gbeanInvoker.invoke(objectName, args); 89 } 90 91 private ProxyInvoker[] createGBeanInvokers(Kernel kernel) { 92 FastClass fastClass = FastClass.create(proxyType); 94 ProxyInvoker[] invokers = new ProxyInvoker[fastClass.getMaxIndex() + 1]; 95 Method [] methods = proxyType.getMethods(); 96 for (int i = 0; i < methods.length; i++) { 97 Method method = methods[i]; 98 int interfaceIndex = getSuperIndex(proxyType, method); 99 if (interfaceIndex >= 0) { 100 invokers[interfaceIndex] = createProxyInvoker(kernel, method); 101 } 102 } 103 104 try { 106 invokers[getSuperIndex(proxyType, proxyType.getMethod("equals", new Class []{Object .class}))] = new EqualsInvoke(kernel.getProxyManager()); 107 invokers[getSuperIndex(proxyType, proxyType.getMethod("hashCode", null))] = new HashCodeInvoke(); 108 invokers[getSuperIndex(proxyType, proxyType.getMethod("toString", null))] = new ToStringInvoke(proxyType.getName()); 109 } catch (Exception e) { 110 throw new AssertionError (e); 112 } 113 114 return invokers; 115 } 116 117 private ProxyInvoker createProxyInvoker(Kernel kernel, Method method) { 118 String methodName = method.getName(); 119 if (!Modifier.isPublic(method.getModifiers()) || Modifier.isStatic(method.getModifiers())) { 120 return null; 121 } 122 123 if (method.getParameterTypes().length == 0 && method.getReturnType() != Void.TYPE) { 125 if (methodName.length() > 3 && methodName.startsWith("get") && !methodName.equals("getClass")) { 126 String propertyName = decapitalizePropertyName(methodName.substring(3)); 127 return new KernelGetAttributeInvoker(kernel, propertyName); 128 } else if (methodName.length() > 2 && methodName.startsWith("is")) { 129 String propertyName = decapitalizePropertyName(methodName.substring(2)); 130 return new KernelGetAttributeInvoker(kernel, propertyName); 131 } 132 } 133 134 if (method.getParameterTypes().length == 1 && 136 method.getReturnType() == Void.TYPE && 137 methodName.length() > 3 && 138 methodName.startsWith("set")) { 139 String propertyName = decapitalizePropertyName(methodName.substring(3)); 140 return new KernelSetAttributeInvoker(kernel, propertyName); 141 } 142 143 return new KernelOperationInvoker(kernel, method); 145 } 146 147 private static int getSuperIndex(Class proxyType, Method method) { 148 Signature signature = new Signature(method.getName(), Type.getReturnType(method), Type.getArgumentTypes(method)); 149 MethodProxy methodProxy = MethodProxy.find(proxyType, signature); 150 if (methodProxy != null) { 151 return methodProxy.getSuperIndex(); 152 } 153 return -1; 154 } 155 156 private static String decapitalizePropertyName(String propertyName) { 157 if (Character.isUpperCase(propertyName.charAt(0))) { 158 return Character.toLowerCase(propertyName.charAt(0)) + propertyName.substring(1); 159 } 160 return propertyName; 161 } 162 163 static final class HashCodeInvoke implements ProxyInvoker { 164 public Object invoke(ObjectName objectName, Object [] arguments) throws Throwable { 165 return new Integer (objectName.hashCode()); 166 } 167 } 168 169 static final class EqualsInvoke implements ProxyInvoker { 170 private final ProxyManager proxyManager; 171 172 public EqualsInvoke(ProxyManager proxyManager) { 173 this.proxyManager = proxyManager; 174 } 175 176 public Object invoke(ObjectName objectName, Object [] arguments) throws Throwable { 177 ObjectName proxyTarget = proxyManager.getProxyTarget(arguments[0]); 178 return Boolean.valueOf(objectName.equals(proxyTarget)); 179 } 180 } 181 182 static final class ToStringInvoke implements ProxyInvoker { 183 private final String interfaceName; 184 185 public ToStringInvoke(String interfaceName) { 186 this.interfaceName = "[" + interfaceName + ": "; 187 } 188 189 public Object invoke(ObjectName objectName, Object [] arguments) throws Throwable { 190 return interfaceName + objectName + "]"; 191 } 192 } 193 } 194 | Popular Tags |