View Javadoc

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                 // Do nothing, it just doesn't get added to the return value.
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 }