1 17 package org.apache.geronimo.system.jmx; 18 19 import net.sf.cglib.asm.Type; 20 import net.sf.cglib.core.Signature; 21 import net.sf.cglib.proxy.MethodInterceptor; 22 import net.sf.cglib.proxy.MethodProxy; 23 import net.sf.cglib.reflect.FastClass; 24 import org.apache.geronimo.gbean.AbstractName; 25 import org.apache.geronimo.kernel.Kernel; 26 import org.apache.geronimo.kernel.basic.KernelGetAttributeInvoker; 27 import org.apache.geronimo.kernel.basic.KernelOperationInvoker; 28 import org.apache.geronimo.kernel.basic.KernelSetAttributeInvoker; 29 import org.apache.geronimo.kernel.basic.ProxyInvoker; 30 import org.apache.geronimo.kernel.management.State; 31 import org.apache.geronimo.kernel.proxy.DeadProxyException; 32 import org.apache.geronimo.kernel.proxy.GeronimoManagedBean; 33 34 import java.lang.reflect.Method ; 35 import java.lang.reflect.Modifier ; 36 37 40 public class JMXProxyMethodInterceptor implements MethodInterceptor { 41 44 private final Class proxyType; 45 46 49 private final AbstractName objectName; 50 51 54 private ProxyInvoker[] gbeanInvokers; 55 56 public JMXProxyMethodInterceptor(Class proxyType, Kernel kernel, AbstractName targetName) { 57 assert proxyType != null; 58 assert kernel != null; 59 assert targetName != null; 60 61 this.proxyType = proxyType; 62 this.objectName = targetName; 63 gbeanInvokers = createGBeanInvokers(kernel); 64 } 65 66 public synchronized void destroy() { 67 gbeanInvokers = null; 68 } 69 70 public AbstractName getAbstractName() { 71 return objectName; 72 } 73 74 public final Object intercept(final Object object, final Method method, final Object [] args, final MethodProxy proxy) throws Throwable { 75 ProxyInvoker gbeanInvoker; 76 77 int interfaceIndex = proxy.getSuperIndex(); 78 synchronized (this) { 79 if (gbeanInvokers == null) { 80 throw new DeadProxyException("Proxy is no longer valid"); 81 } 82 gbeanInvoker = gbeanInvokers[interfaceIndex]; 83 } 84 85 if (gbeanInvoker == null) { 86 throw new UnsupportedOperationException ("No implementation method: objectName=" + objectName + ", method=" + method); 87 } 88 89 return gbeanInvoker.invoke(objectName, args); 90 } 91 92 private ProxyInvoker[] createGBeanInvokers(Kernel kernel) { 93 FastClass fastClass = FastClass.create(proxyType); 95 ProxyInvoker[] invokers = new ProxyInvoker[fastClass.getMaxIndex() + 1]; 96 Method [] methods = proxyType.getMethods(); 97 for (int i = 0; i < methods.length; i++) { 98 Method method = methods[i]; 99 int interfaceIndex = getSuperIndex(proxyType, method); 100 if (interfaceIndex >= 0) { 101 invokers[interfaceIndex] = createProxyInvoker(kernel, method); 102 } 103 } 104 105 try { 107 invokers[getSuperIndex(proxyType, proxyType.getMethod("equals", new Class []{Object .class}))] = new EqualsInvoke(kernel); 108 invokers[getSuperIndex(proxyType, proxyType.getMethod("hashCode", null))] = new HashCodeInvoke(); 109 invokers[getSuperIndex(proxyType, proxyType.getMethod("toString", null))] = new ToStringInvoke(proxyType.getName()); 110 if(GeronimoManagedBean.class.isAssignableFrom(proxyType)) { 111 invokers[getSuperIndex(proxyType, proxyType.getMethod("getState", null))] = new GetStateInvoke(kernel); 112 invokers[getSuperIndex(proxyType, proxyType.getMethod("getStateInstance", null))] = new GetStateInstanceInvoke(kernel); 113 invokers[getSuperIndex(proxyType, proxyType.getMethod("start", null))] = new StartInvoke(kernel); 114 invokers[getSuperIndex(proxyType, proxyType.getMethod("startRecursive", null))] = new StartRecursiveInvoke(kernel); 115 invokers[getSuperIndex(proxyType, proxyType.getMethod("stop", null))] = new StopInvoke(kernel); 116 invokers[getSuperIndex(proxyType, proxyType.getMethod("getStartTime", null))] = new GetStartTimeInvoke(kernel); 117 invokers[getSuperIndex(proxyType, proxyType.getMethod("getObjectName", null))] = new GetObjectNameInvoke(); 118 } 119 } catch (Exception e) { 120 throw new AssertionError (e); 122 } 123 124 return invokers; 125 } 126 127 private ProxyInvoker createProxyInvoker(Kernel kernel, Method method) { 128 String methodName = method.getName(); 129 if (!Modifier.isPublic(method.getModifiers()) || Modifier.isStatic(method.getModifiers())) { 130 return null; 131 } 132 133 if (method.getParameterTypes().length == 0 && method.getReturnType() != Void.TYPE) { 135 if (methodName.length() > 3 && methodName.startsWith("get") && !methodName.equals("getClass")) { 136 String propertyName = decapitalizePropertyName(methodName.substring(3)); 137 return new KernelGetAttributeInvoker(kernel, propertyName); 138 } else if (methodName.length() > 2 && methodName.startsWith("is")) { 139 String propertyName = decapitalizePropertyName(methodName.substring(2)); 140 return new KernelGetAttributeInvoker(kernel, propertyName); 141 } 142 } 143 144 if (method.getParameterTypes().length == 1 && 146 method.getReturnType() == Void.TYPE && 147 methodName.length() > 3 && 148 methodName.startsWith("set")) { 149 String propertyName = decapitalizePropertyName(methodName.substring(3)); 150 return new KernelSetAttributeInvoker(kernel, propertyName); 151 } 152 153 return new KernelOperationInvoker(kernel, method); 155 } 156 157 private static int getSuperIndex(Class proxyType, Method method) { 158 Signature signature = new Signature(method.getName(), Type.getReturnType(method), Type.getArgumentTypes(method)); 159 MethodProxy methodProxy = MethodProxy.find(proxyType, signature); 160 if (methodProxy != null) { 161 return methodProxy.getSuperIndex(); 162 } 163 return -1; 164 } 165 166 private static String decapitalizePropertyName(String propertyName) { 167 if (Character.isUpperCase(propertyName.charAt(0))) { 168 return Character.toLowerCase(propertyName.charAt(0)) + propertyName.substring(1); 169 } 170 return propertyName; 171 } 172 173 static final class HashCodeInvoke implements ProxyInvoker { 174 public Object invoke(AbstractName abstractName, Object [] arguments) throws Throwable { 175 return new Integer (abstractName.hashCode()); 176 } 177 } 178 179 static final class EqualsInvoke implements ProxyInvoker { 180 private final Kernel kernel; 181 182 public EqualsInvoke(Kernel kernel) { 183 this.kernel = kernel; 184 } 185 186 public Object invoke(AbstractName abstractName, Object [] arguments) throws Throwable { 187 AbstractName proxyTarget = kernel.getAbstractNameFor(arguments[0]); 188 return Boolean.valueOf(abstractName.equals(proxyTarget)); 189 } 190 } 191 192 static final class ToStringInvoke implements ProxyInvoker { 193 private final String interfaceName; 194 195 public ToStringInvoke(String interfaceName) { 196 this.interfaceName = "[" + interfaceName + ": "; 197 } 198 199 public Object invoke(AbstractName abstractName, Object [] arguments) throws Throwable { 200 return interfaceName + abstractName + "]"; 201 } 202 } 203 204 static final class GetStateInvoke implements ProxyInvoker { 205 private Kernel kernel; 206 207 public GetStateInvoke(Kernel kernel) { 208 this.kernel = kernel; 209 } 210 211 public Object invoke(AbstractName abstractName, Object [] arguments) throws Throwable { 212 return new Integer (kernel.getGBeanState(abstractName)); 213 } 214 } 215 216 static final class GetStateInstanceInvoke implements ProxyInvoker { 217 private Kernel kernel; 218 219 public GetStateInstanceInvoke(Kernel kernel) { 220 this.kernel = kernel; 221 } 222 223 public Object invoke(AbstractName abstractName, Object [] arguments) throws Throwable { 224 return State.fromInt(kernel.getGBeanState(abstractName)); 225 } 226 } 227 228 static final class StartInvoke implements ProxyInvoker { 229 private Kernel kernel; 230 231 public StartInvoke(Kernel kernel) { 232 this.kernel = kernel; 233 } 234 235 public Object invoke(AbstractName abstractName, Object [] arguments) throws Throwable { 236 kernel.startGBean(abstractName); 237 return null; 238 } 239 } 240 241 static final class StartRecursiveInvoke implements ProxyInvoker { 242 private Kernel kernel; 243 244 public StartRecursiveInvoke(Kernel kernel) { 245 this.kernel = kernel; 246 } 247 248 public Object invoke(AbstractName abstractName, Object [] arguments) throws Throwable { 249 kernel.startRecursiveGBean(abstractName); 250 return null; 251 } 252 } 253 254 static final class GetStartTimeInvoke implements ProxyInvoker { 255 private Kernel kernel; 256 257 public GetStartTimeInvoke(Kernel kernel) { 258 this.kernel = kernel; 259 } 260 261 public Object invoke(AbstractName abstractName, Object [] arguments) throws Throwable { 262 return new Long (kernel.getGBeanStartTime(abstractName)); 263 } 264 } 265 266 static final class StopInvoke implements ProxyInvoker { 267 private Kernel kernel; 268 269 public StopInvoke(Kernel kernel) { 270 this.kernel = kernel; 271 } 272 273 public Object invoke(AbstractName abstractName, Object [] arguments) throws Throwable { 274 kernel.stopGBean(abstractName); 275 return null; 276 } 277 } 278 279 static final class GetObjectNameInvoke implements ProxyInvoker { 280 public Object invoke(AbstractName abstractName, Object [] arguments) throws Throwable { 281 return abstractName.getObjectName().getCanonicalName(); 282 } 283 } 284 } 285 | Popular Tags |