1 package org.jmux.app.component.jmx;
2
3 import javax.management.*;
4 import java.lang.reflect.Field;
5 import java.lang.reflect.InvocationTargetException;
6 import java.lang.reflect.Method;
7 import java.util.ArrayList;
8 import java.util.HashMap;
9 import java.util.List;
10 import java.util.Map;
11
12 /******************************************************************************
13 jmux - Java Modules Using XML
14 Copyright © 2006 jmux.org
15
16 This library is free software; you can redistribute it and/or
17 modify it under the terms of the GNU Lesser General Public
18 License as published by the Free Software Foundation; either
19 version 2.1 of the License, or (at your option) any later version.
20
21 This library is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 Lesser General Public License for more details.
25
26 You should have received a copy of the GNU Lesser General Public
27 License along with this library; if not, write to the Free Software
28 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29 *****************************************************************************/
30
31 /***
32 * @author donaldw
33 */
34 public class JMXObjectAdapter implements DynamicMBean {
35 private Object target;
36
37 private Map<String, Method> methods = new HashMap<String, Method>();
38 private List<MBeanOperationInfo> mBeanOperationInfos = new ArrayList<MBeanOperationInfo>();
39 private String description;
40 private List<MBeanAttributeInfo> mBeanAttributeInfos = new ArrayList<MBeanAttributeInfo>();
41 private Map<String, Field> writeableField = new HashMap<String, Field>();
42 private Map<String, Field> readableField = new HashMap<String, Field>();
43 private MBeanInfo mBeanInfo;
44
45 public JMXObjectAdapter(String description, Object target) {
46 this.description = description;
47 this.target = target;
48
49 registerMethods(target.getClass());
50 registerFields(target.getClass());
51 }
52
53 private void registerFields(Class clazz) {
54 Field[] fields = clazz.getDeclaredFields();
55
56 for (Field field : fields) {
57 if (field.isAnnotationPresent(JMX.class)) {
58 JMX jmx = field.getAnnotation(JMX.class);
59 field.setAccessible(true);
60 this.setNameForField(field.getName(), field, jmx);
61 }
62 }
63
64 if (clazz.getSuperclass() != null) {
65 registerFields(clazz.getSuperclass());
66 }
67 }
68
69 private void registerMethods(Class clazz) {
70 Method[] methods = clazz.getDeclaredMethods();
71
72 for (Method method : methods) {
73 if (method.isAnnotationPresent(JMX.class)) {
74 method.setAccessible(true);
75 this.setNameForMethod(method.getName(), method);
76 }
77 }
78
79 if (clazz.getSuperclass() != null) {
80 registerMethods(clazz.getSuperclass());
81 }
82 }
83
84 private void setNameForField(String name, Field field, JMX jmx) {
85 if (jmx.value() != Access.READ) {
86 writeableField.put(name, field);
87 }
88 if (jmx.value() != Access.WRITE) {
89 readableField.put(name, field);
90 }
91 mBeanAttributeInfos.add(
92 new MBeanAttributeInfo(
93 name, field.getType().getName(),
94 "Description for " + name, jmx.value() != Access.WRITE, jmx.value() != Access.READ, false));
95 }
96
97 private void setNameForMethod(String name, Method method) {
98 methods.put(name, method);
99 mBeanOperationInfos.add(new MBeanOperationInfo(name, method));
100 }
101
102 public Object getAttribute(String string) throws AttributeNotFoundException, MBeanException, ReflectionException {
103 Field field = readableField.get(string);
104 if (field == null) {
105 throw new AttributeNotFoundException();
106 }
107 try {
108 return field.get(target);
109 } catch (IllegalAccessException e) {
110 throw new ReflectionException(e);
111 }
112 }
113
114 public void setAttribute(Attribute attribute)
115 throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException {
116
117 Field field = writeableField.get(attribute.getName());
118 if (field == null) {
119 throw new AttributeNotFoundException(attribute.getName());
120 }
121 try {
122 field.set(target, attribute.getValue());
123 } catch (IllegalAccessException e) {
124 throw new ReflectionException(e);
125 }
126 }
127
128 public AttributeList getAttributes(String[] strings) {
129 AttributeList attributeList = new AttributeList();
130 for (String s : strings) {
131 Field field = readableField.get(s);
132 try {
133 Object value = field.get(target);
134 attributeList.add(new Attribute(s, value));
135 } catch (IllegalAccessException e) {
136 attributeList.add(new Attribute(s, null));
137 }
138
139 }
140 return attributeList;
141 }
142
143 public AttributeList setAttributes(AttributeList attributeList) {
144 AttributeList retVal = new AttributeList();
145 for (Object o : attributeList) {
146 Attribute attribute = (Attribute) o;
147 Field field = writeableField.get(attribute.getName());
148 retVal.add(attribute);
149 try {
150 field.set(target, attribute.getValue());
151 } catch (IllegalAccessException e) {
152
153 }
154
155 }
156 return retVal;
157 }
158
159 public Object invoke(String string, Object[] objects, String[] strings) throws MBeanException, ReflectionException {
160 Method method = methods.get(string);
161 try {
162 return method.invoke(target, objects);
163 } catch (IllegalAccessException e) {
164 throw new ReflectionException(e);
165 } catch (InvocationTargetException e) {
166 throw new ReflectionException(e);
167 }
168 }
169
170 public MBeanInfo getMBeanInfo() {
171 if (mBeanInfo == null) {
172
173
174 MBeanOperationInfo[] mBeanOperationInfo = new MBeanOperationInfo[mBeanOperationInfos.size()];
175 int i = 0;
176 for (MBeanOperationInfo mBeanOperation : mBeanOperationInfos) {
177 mBeanOperationInfo[i++] = mBeanOperation;
178 }
179
180 MBeanAttributeInfo[] mBeanAttributeInfo = new MBeanAttributeInfo[mBeanAttributeInfos.size()];
181 int j = 0;
182 for (MBeanAttributeInfo mBeanAttribute : mBeanAttributeInfos) {
183 mBeanAttributeInfo[j++] = mBeanAttribute;
184 }
185
186 mBeanInfo = new MBeanInfo(
187 target.getClass().getName(),
188 description,
189 mBeanAttributeInfo,
190 new MBeanConstructorInfo[0],
191 mBeanOperationInfo,
192 new MBeanNotificationInfo[0]);
193 }
194
195 return mBeanInfo;
196 }
197 }