KickJava   Java API By Example, From Geeks To Geeks.

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


1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. 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.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 JavaDoc;
35 import java.lang.reflect.Modifier JavaDoc;
36
37 /**
38  * @version $Rev: 476049 $ $Date: 2006-11-16 23:35:17 -0500 (Thu, 16 Nov 2006) $
39  */

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

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

49     private final AbstractName objectName;
50
51     /**
52      * GBeanInvokers keyed on the proxy interface method index
53      */

54     private ProxyInvoker[] gbeanInvokers;
55
56     public JMXProxyMethodInterceptor(Class JavaDoc 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 JavaDoc intercept(final Object JavaDoc object, final Method JavaDoc method, final Object JavaDoc[] args, final MethodProxy proxy) throws Throwable JavaDoc {
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 JavaDoc("No implementation method: objectName=" + objectName + ", method=" + method);
87         }
88
89         return gbeanInvoker.invoke(objectName, args);
90     }
91
92     private ProxyInvoker[] createGBeanInvokers(Kernel kernel) {
93         // build the method lookup table
94
FastClass fastClass = FastClass.create(proxyType);
95         ProxyInvoker[] invokers = new ProxyInvoker[fastClass.getMaxIndex() + 1];
96         Method JavaDoc[] methods = proxyType.getMethods();
97         for (int i = 0; i < methods.length; i++) {
98             Method JavaDoc method = methods[i];
99             int interfaceIndex = getSuperIndex(proxyType, method);
100             if (interfaceIndex >= 0) {
101                 invokers[interfaceIndex] = createProxyInvoker(kernel, method);
102             }
103         }
104
105         // handle equals, hashCode and toString directly here
106
try {
107             invokers[getSuperIndex(proxyType, proxyType.getMethod("equals", new Class JavaDoc[]{Object JavaDoc.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 JavaDoc e) {
120             // this can not happen... all classes must implement equals, hashCode and toString
121
throw new AssertionError JavaDoc(e);
122         }
123
124         return invokers;
125     }
126
127     private ProxyInvoker createProxyInvoker(Kernel kernel, Method JavaDoc method) {
128         String JavaDoc methodName = method.getName();
129         if (!Modifier.isPublic(method.getModifiers()) || Modifier.isStatic(method.getModifiers())) {
130             return null;
131         }
132
133         // is this a getter is "is" method
134
if (method.getParameterTypes().length == 0 && method.getReturnType() != Void.TYPE) {
135             if (methodName.length() > 3 && methodName.startsWith("get") && !methodName.equals("getClass")) {
136                 String JavaDoc propertyName = decapitalizePropertyName(methodName.substring(3));
137                 return new KernelGetAttributeInvoker(kernel, propertyName);
138             } else if (methodName.length() > 2 && methodName.startsWith("is")) {
139                 String JavaDoc propertyName = decapitalizePropertyName(methodName.substring(2));
140                 return new KernelGetAttributeInvoker(kernel, propertyName);
141             }
142         }
143
144         // is this a setter method
145
if (method.getParameterTypes().length == 1 &&
146                 method.getReturnType() == Void.TYPE &&
147                 methodName.length() > 3 &&
148                 methodName.startsWith("set")) {
149             String JavaDoc propertyName = decapitalizePropertyName(methodName.substring(3));
150             return new KernelSetAttributeInvoker(kernel, propertyName);
151         }
152
153         // it is just a plain old opertaion
154
return new KernelOperationInvoker(kernel, method);
155     }
156
157     private static int getSuperIndex(Class JavaDoc proxyType, Method JavaDoc 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 JavaDoc decapitalizePropertyName(String JavaDoc 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 JavaDoc invoke(AbstractName abstractName, Object JavaDoc[] arguments) throws Throwable JavaDoc {
175             return new Integer JavaDoc(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 JavaDoc invoke(AbstractName abstractName, Object JavaDoc[] arguments) throws Throwable JavaDoc {
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 JavaDoc interfaceName;
194
195         public ToStringInvoke(String JavaDoc interfaceName) {
196             this.interfaceName = "[" + interfaceName + ": ";
197         }
198
199         public Object JavaDoc invoke(AbstractName abstractName, Object JavaDoc[] arguments) throws Throwable JavaDoc {
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 JavaDoc invoke(AbstractName abstractName, Object JavaDoc[] arguments) throws Throwable JavaDoc {
212             return new Integer JavaDoc(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 JavaDoc invoke(AbstractName abstractName, Object JavaDoc[] arguments) throws Throwable JavaDoc {
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 JavaDoc invoke(AbstractName abstractName, Object JavaDoc[] arguments) throws Throwable JavaDoc {
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 JavaDoc invoke(AbstractName abstractName, Object JavaDoc[] arguments) throws Throwable JavaDoc {
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 JavaDoc invoke(AbstractName abstractName, Object JavaDoc[] arguments) throws Throwable JavaDoc {
262             return new Long JavaDoc(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 JavaDoc invoke(AbstractName abstractName, Object JavaDoc[] arguments) throws Throwable JavaDoc {
274             kernel.stopGBean(abstractName);
275             return null;
276         }
277     }
278
279     static final class GetObjectNameInvoke implements ProxyInvoker {
280         public Object JavaDoc invoke(AbstractName abstractName, Object JavaDoc[] arguments) throws Throwable JavaDoc {
281             return abstractName.getObjectName().getCanonicalName();
282         }
283     }
284 }
285
Popular Tags