1 22 package org.jboss.mx.metadata; 23 24 import java.lang.reflect.Constructor ; 25 import java.lang.reflect.Method ; 26 import java.util.ArrayList ; 27 import java.util.HashMap ; 28 import java.util.Iterator ; 29 import java.util.List ; 30 31 import javax.management.IntrospectionException ; 32 import javax.management.MBeanAttributeInfo ; 33 import javax.management.MBeanConstructorInfo ; 34 import javax.management.MBeanInfo ; 35 import javax.management.MBeanNotificationInfo ; 36 import javax.management.MBeanOperationInfo ; 37 import javax.management.NotCompliantMBeanException ; 38 import javax.management.NotificationBroadcaster ; 39 40 58 public class StandardMetaData extends AbstractBuilder 59 { 60 61 63 67 private Object mbeanInstance = null; 68 69 72 private Class mbeanClass = null; 73 74 77 private Class mbeanInterface = null; 78 79 80 82 90 public static Class findStandardInterface(Class mbeanClass) 91 { 92 Class concrete = mbeanClass; 93 Class stdInterface = null; 94 while (null != concrete) 95 { 96 stdInterface = findStandardInterface(concrete, concrete.getInterfaces()); 97 if (null != stdInterface) 98 { 99 return stdInterface; 100 } 101 concrete = concrete.getSuperclass(); 102 } 103 return null; 104 } 105 106 private static Class findStandardInterface(Class concrete, Class [] interfaces) 107 { 108 String stdName = concrete.getName() + "MBean"; 109 Class retval = null; 110 111 for (int i = 0; i < interfaces.length; ++i) 113 { 114 if (interfaces[i].getName().equals(stdName)) 115 { 116 retval = interfaces[i]; 117 break; 118 } 119 } 120 121 return retval; 122 } 123 124 125 127 133 public StandardMetaData(Object mbeanInstance) throws NotCompliantMBeanException 134 { 135 this(mbeanInstance.getClass()); 136 this.mbeanInstance = mbeanInstance; 137 } 138 139 146 public StandardMetaData(Class mbeanClass) throws NotCompliantMBeanException 147 { 148 this.mbeanClass = mbeanClass; 149 this.mbeanInterface = StandardMetaData.findStandardInterface(mbeanClass); 150 if (this.mbeanInterface == null) 151 throw new NotCompliantMBeanException ("Cannot obtain management interface for: " + mbeanClass); 152 } 153 154 161 public StandardMetaData(Object mbInstance, Class mbInterface) throws NotCompliantMBeanException 162 { 163 this.mbeanInstance = mbInstance; 164 this.mbeanClass = mbInstance.getClass(); 165 this.mbeanInterface = mbInterface; 166 167 if (this.mbeanInterface == null) 169 this.mbeanInterface = StandardMetaData.findStandardInterface(mbeanClass); 170 171 if (this.mbeanInterface == null) 172 throw new NotCompliantMBeanException ("Cannot obtain management interface for: " + mbeanClass); 173 if (this.mbeanInterface.isInterface() == false) 174 throw new NotCompliantMBeanException ("Management interface is not an interface: " + mbeanInterface); 175 } 176 177 180 public Class getMBeanInterface() 181 { 182 return mbeanInterface; 183 } 184 185 187 public MBeanInfo build() throws NotCompliantMBeanException 188 { 189 try 190 { 191 if (mbeanInterface == null) 193 throw new NotCompliantMBeanException ("The mbean does not implement a management interface"); 194 if (mbeanInstance != null && mbeanInterface.isInstance(mbeanInstance) == false) 195 throw new NotCompliantMBeanException ("The mbean does not implement its management interface " + 196 mbeanInterface.getName()); 197 198 Constructor [] constructors = mbeanClass.getConstructors(); 200 MBeanConstructorInfo [] constructorInfo = new MBeanConstructorInfo [constructors.length]; 201 for (int i = 0; i < constructors.length; ++i) 202 { 203 constructorInfo[i] = new MBeanConstructorInfo ("MBean Constructor.", constructors[i]); 204 } 205 206 Method [] methods = mbeanInterface.getMethods(); 209 HashMap getters = new HashMap (); 210 HashMap setters = new HashMap (); 211 212 HashMap operInfo = new HashMap (); 213 List attrInfo = new ArrayList (); 214 215 for (int i = 0; i < methods.length; ++i) 216 { 217 String methodName = methods[i].getName(); 218 Class [] signature = methods[i].getParameterTypes(); 219 Class returnType = methods[i].getReturnType(); 220 221 if (methodName.startsWith("set") && methodName.length() > 3 222 && signature.length == 1 && returnType == Void.TYPE) 223 { 224 String key = methodName.substring(3, methodName.length()); 225 Method setter = (Method ) setters.get(key); 226 if (setter != null && setter.getParameterTypes()[0].equals(signature[0]) == false) 227 { 228 throw new IntrospectionException ("overloaded type for attribute set: " + key); 229 } 230 setters.put(key, methods[i]); 231 } 232 else if (methodName.startsWith("get") && methodName.length() > 3 233 && signature.length == 0 && returnType != Void.TYPE) 234 { 235 String key = methodName.substring(3, methodName.length()); 236 Method getter = (Method ) getters.get(key); 237 if (getter != null && getter.getName().startsWith("is")) 238 { 239 throw new IntrospectionException ("mixed use of get/is for attribute " + key); 240 } 241 getters.put(key, methods[i]); 242 } 243 else if (methodName.startsWith("is") && methodName.length() > 2 244 && signature.length == 0 && isBooleanReturn(returnType)) 245 { 246 String key = methodName.substring(2, methodName.length()); 247 Method getter = (Method ) getters.get(key); 248 if (getter != null && getter.getName().startsWith("get")) 249 { 250 throw new IntrospectionException ("mixed use of get/is for attribute " + key); 251 } 252 getters.put(key, methods[i]); 253 } 254 else 255 { 256 MBeanOperationInfo info = new MBeanOperationInfo ("MBean Operation.", methods[i]); 257 operInfo.put(getSignatureString(methods[i]), info); 258 } 259 } 260 261 Object [] keys = getters.keySet().toArray(); 262 for (int i = 0; i < keys.length; ++i) 263 { 264 String attrName = (String ) keys[i]; 265 Method getter = (Method ) getters.remove(attrName); 266 Method setter = (Method ) setters.remove(attrName); 267 MBeanAttributeInfo info = new MBeanAttributeInfo (attrName, "MBean Attribute.", getter, setter); 268 attrInfo.add(info); 269 } 270 271 Iterator it = setters.keySet().iterator(); 272 while (it.hasNext()) 273 { 274 String attrName = (String ) it.next(); 275 Method setter = (Method ) setters.get(attrName); 276 MBeanAttributeInfo info = new MBeanAttributeInfo (attrName, "MBean Attribute.", null, setter); 277 attrInfo.add(info); 278 } 279 280 MBeanAttributeInfo [] attributeInfo = (MBeanAttributeInfo []) attrInfo.toArray(new MBeanAttributeInfo [0]); 282 MBeanOperationInfo [] operationInfo = (MBeanOperationInfo []) operInfo.values().toArray(new MBeanOperationInfo [0]); 283 284 MBeanNotificationInfo [] notifications = null; 288 if (mbeanInstance instanceof NotificationBroadcaster ) 289 { 290 notifications = ((NotificationBroadcaster ) mbeanInstance).getNotificationInfo(); 291 } 292 else 293 { 294 notifications = new MBeanNotificationInfo [0]; 295 } 296 297 return new MBeanInfo (mbeanClass.getName(), "Management Bean.", 298 attributeInfo, constructorInfo, operationInfo, notifications); 299 300 } 301 catch (IntrospectionException e) 302 { 303 throw new NotCompliantMBeanException (e.getMessage()); 304 } 305 } 306 307 311 private boolean isBooleanReturn(Class returnType) 312 { 313 return returnType == Boolean.TYPE; 314 } 315 316 protected String getSignatureString(Method method) 317 { 318 String name = method.getName(); 319 Class [] signature = method.getParameterTypes(); 320 StringBuffer buffer = new StringBuffer (512); 321 buffer.append(name); 322 buffer.append("("); 323 if (signature != null) 324 { 325 for (int i = 0; i < signature.length; i++) 326 { 327 buffer.append(signature[i].getName()); 328 if (i < signature.length-1) 329 buffer.append(","); 330 } 331 } 332 buffer.append(")"); 333 return buffer.toString(); 334 } 335 } 336 337 | Popular Tags |