1
2
3
4
5 package org.neo.swarm.interceptor.jmx;
6
7 import java.io.Serializable;
8 import java.lang.reflect.AccessibleObject;
9 import java.lang.reflect.Field;
10 import java.lang.reflect.Method;
11
12 import javax.management.InstanceAlreadyExistsException;
13 import javax.management.MBeanAttributeInfo;
14 import javax.management.MBeanOperationInfo;
15 import javax.management.MBeanRegistrationException;
16 import javax.management.MBeanServer;
17 import javax.management.MalformedObjectNameException;
18 import javax.management.NotCompliantMBeanException;
19 import javax.management.ObjectName;
20
21 import mx4j.AbstractDynamicMBean;
22
23 import org.aopalliance.intercept.MethodInvocation;
24 import org.neo.swarm.core.aop.Aspect;
25 import org.neo.swarm.core.aop.AspectComponent;
26 import org.neo.swarm.core.aop.silc.comp.MethodInterceptor;
27 import org.neo.swarm.core.aop.silc.comp.Perspective;
28 import org.neo.swarm.core.aop.silc.comp.Pointcut;
29 import org.neo.swarm.core.aop.silc.comp.RegexPointCut;
30
31 /***
32 * Handle JMX Management by reflecting aspect targets as they are weaved
33 *
34 * @author neil.avery
35 */
36 public class Jmx implements Serializable, Aspect {
37
38 Pointcut pointcut = new RegexPointCut("(.*)");
39
40 private MethodInterceptor interceptor;
41 transient private MBeanServer jmxServer;
42 private Object tempObjectHandle;
43 transient private String type;
44 transient private String classification;
45
46 public Jmx(String classification, String type, MBeanServer jmxServer) {
47 this.type = type;
48 this.classification = classification;
49 this.jmxServer = jmxServer;
50 this.interceptor = new MethodInterceptor() {
51
52 public Object invoke(MethodInvocation invocation) throws Throwable {
53 return invocation.proceed();
54 }
55 };
56 }
57
58
59
60
61
62
63 public MethodInterceptor getInterceptor() {
64 return this.interceptor;
65 }
66
67 public void advise(AspectComponent componentInstance) {
68
69 pointcut.advise(Perspective.DEFAULT, componentInstance, interceptor);
70
71
72 ObjectName objectName = null;
73 try {
74 objectName = new ObjectName(classification, type, componentInstance.getProxy().toString());
75 } catch (MalformedObjectNameException e1) {
76 e1.printStackTrace();
77 }
78 if (jmxServer.isRegistered(objectName))
79 return;
80
81
82 tempObjectHandle = componentInstance.getTarget();
83
84
85 AbstractDynamicMBean delegate = new AbstractDynamicMBean() {
86
87 protected MBeanAttributeInfo[] createMBeanAttributeInfo() {
88 try {
89
90 Field[] fields = tempObjectHandle.getClass().getDeclaredFields();
91 AccessibleObject.setAccessible(fields, true);
92 MBeanAttributeInfo[] retVal = new MBeanAttributeInfo[fields.length];
93
94 for (int j = 0; j < fields.length; j++) {
95 retVal[j] = new MBeanAttributeInfo(fields[j].getName(), fields[j].getType().toString(), "init value["+ fields[j].get(tempObjectHandle) + "]", false, false, false);
96 }
97 return retVal;
98 } catch (IllegalArgumentException e) {
99 e.printStackTrace();
100 } catch (IllegalAccessException e) {
101 e.printStackTrace();
102 }
103 return new MBeanAttributeInfo[0];
104
105 }
106
107 protected MBeanOperationInfo[] createMBeanOperationInfo() {
108 Method[] methods = tempObjectHandle.getClass().getDeclaredMethods();
109 MBeanOperationInfo[] retVal = new MBeanOperationInfo[methods.length];
110 for (int j = 0; j < methods.length; j++) {
111 retVal[j] = new MBeanOperationInfo("[generated]", methods[j]);
112 }
113 return retVal;
114 }
115
116 protected String getMBeanDescription() {
117 return tempObjectHandle.getClass().getInterfaces()[0].toString();
118 }
119 };
120 delegate.setResource(componentInstance.getProxy());
121
122 System.out.println("JMX registering:" + componentInstance.getProxy().toString());
123
124 try {
125 this.jmxServer.registerMBean(delegate, objectName);
126 } catch (InstanceAlreadyExistsException e) {
127 e.printStackTrace();
128 } catch (MBeanRegistrationException e) {
129 e.printStackTrace();
130 } catch (NotCompliantMBeanException e) {
131 e.printStackTrace();
132 }
133 }
134
135 public void replaceInterceptor(MethodInterceptor interceptor) {
136 this.interceptor = interceptor;
137 }
138 }