KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > geronimo > kernel > jmx > JMXProxyMethodInterceptor


1 /**
2  *
3  * Copyright 2004 The Apache Software Foundation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17 package org.apache.geronimo.kernel.jmx;
18
19 import java.lang.reflect.Method JavaDoc;
20 import java.lang.reflect.Modifier JavaDoc;
21 import javax.management.ObjectName JavaDoc;
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 /**
37  * @version $Rev: 106345 $ $Date: 2004-11-23 12:37:03 -0800 (Tue, 23 Nov 2004) $
38  */

39 public class JMXProxyMethodInterceptor implements MethodInterceptor {
40     /**
41      * Type of the proxy interface
42      */

43     private final Class JavaDoc proxyType;
44
45     /**
46      * The object name to which we are connected.
47      */

48     private final ObjectName JavaDoc objectName;
49
50     /**
51      * GBeanInvokers keyed on the proxy interface method index
52      */

53     private ProxyInvoker[] gbeanInvokers;
54
55     public JMXProxyMethodInterceptor(Class JavaDoc proxyType, Kernel kernel, ObjectName JavaDoc 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 JavaDoc getObjectName() {
70         return objectName;
71     }
72
73     public final Object JavaDoc intercept(final Object JavaDoc object, final Method JavaDoc method, final Object JavaDoc[] args, final MethodProxy proxy) throws Throwable JavaDoc {
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 JavaDoc("No implementation method: objectName=" + objectName + ", method=" + method);
86         }
87
88         return gbeanInvoker.invoke(objectName, args);
89     }
90
91     private ProxyInvoker[] createGBeanInvokers(Kernel kernel) {
92         // build the method lookup table
93
FastClass fastClass = FastClass.create(proxyType);
94         ProxyInvoker[] invokers = new ProxyInvoker[fastClass.getMaxIndex() + 1];
95         Method JavaDoc[] methods = proxyType.getMethods();
96         for (int i = 0; i < methods.length; i++) {
97             Method JavaDoc method = methods[i];
98             int interfaceIndex = getSuperIndex(proxyType, method);
99             if (interfaceIndex >= 0) {
100                 invokers[interfaceIndex] = createProxyInvoker(kernel, method);
101             }
102         }
103
104         // handle equals, hashCode and toString directly here
105
try {
106             invokers[getSuperIndex(proxyType, proxyType.getMethod("equals", new Class JavaDoc[]{Object JavaDoc.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 JavaDoc e) {
110             // this can not happen... all classes must implement equals, hashCode and toString
111
throw new AssertionError JavaDoc(e);
112         }
113
114         return invokers;
115     }
116
117     private ProxyInvoker createProxyInvoker(Kernel kernel, Method JavaDoc method) {
118         String JavaDoc methodName = method.getName();
119         if (!Modifier.isPublic(method.getModifiers()) || Modifier.isStatic(method.getModifiers())) {
120             return null;
121         }
122
123         // is this a getter is "is" method
124
if (method.getParameterTypes().length == 0 && method.getReturnType() != Void.TYPE) {
125             if (methodName.length() > 3 && methodName.startsWith("get") && !methodName.equals("getClass")) {
126                 String JavaDoc propertyName = decapitalizePropertyName(methodName.substring(3));
127                 return new KernelGetAttributeInvoker(kernel, propertyName);
128             } else if (methodName.length() > 2 && methodName.startsWith("is")) {
129                 String JavaDoc propertyName = decapitalizePropertyName(methodName.substring(2));
130                 return new KernelGetAttributeInvoker(kernel, propertyName);
131             }
132         }
133
134         // is this a setter method
135
if (method.getParameterTypes().length == 1 &&
136                 method.getReturnType() == Void.TYPE &&
137                 methodName.length() > 3 &&
138                 methodName.startsWith("set")) {
139             String JavaDoc propertyName = decapitalizePropertyName(methodName.substring(3));
140             return new KernelSetAttributeInvoker(kernel, propertyName);
141         }
142
143         // it is just a plain old opertaion
144
return new KernelOperationInvoker(kernel, method);
145     }
146
147     private static int getSuperIndex(Class JavaDoc proxyType, Method JavaDoc 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 JavaDoc decapitalizePropertyName(String JavaDoc 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 JavaDoc invoke(ObjectName JavaDoc objectName, Object JavaDoc[] arguments) throws Throwable JavaDoc {
165             return new Integer JavaDoc(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 JavaDoc invoke(ObjectName JavaDoc objectName, Object JavaDoc[] arguments) throws Throwable JavaDoc {
177             ObjectName JavaDoc 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 JavaDoc interfaceName;
184
185         public ToStringInvoke(String JavaDoc interfaceName) {
186             this.interfaceName = "[" + interfaceName + ": ";
187         }
188
189         public Object JavaDoc invoke(ObjectName JavaDoc objectName, Object JavaDoc[] arguments) throws Throwable JavaDoc {
190             return interfaceName + objectName + "]";
191         }
192     }
193 }
194
Popular Tags