1 22 package org.jboss.ejb3.service; 23 24 import java.lang.reflect.Method ; 25 import java.util.HashMap ; 26 import java.util.HashSet ; 27 import java.util.Iterator ; 28 import javax.management.Attribute ; 29 import javax.management.AttributeList ; 30 import javax.management.AttributeNotFoundException ; 31 import javax.management.DynamicMBean ; 32 import javax.management.InstanceNotFoundException ; 33 import javax.management.InvalidAttributeValueException ; 34 import javax.management.MBeanAttributeInfo ; 35 import javax.management.MBeanException ; 36 import javax.management.MBeanInfo ; 37 import javax.management.MBeanOperationInfo ; 38 import javax.management.MBeanParameterInfo ; 39 import javax.management.MBeanServer ; 40 import javax.management.ObjectName ; 41 import javax.management.ReflectionException ; 42 import javax.management.StandardMBean ; 43 import javax.management.NotCompliantMBeanException ; 44 45 import org.jboss.logging.Logger; 46 import org.jboss.util.Classes; 47 48 52 public class ServiceMBeanDelegate implements DynamicMBean 53 { 54 private static final Logger log = Logger.getLogger(ServiceMBeanDelegate.class); 55 56 MBeanServer server; 57 ServiceContainer container; 58 ObjectName serviceOn; 59 MBeanInfo mbeanInfo; 60 61 HashMap <String , Method > getterMethods = new HashMap <String , Method >(); 62 HashSet <String > getterBlackList = new HashSet <String >(); 63 HashMap <String , Method > setterMethods = new HashMap <String , Method >(); 64 HashSet <String > setterBlackList = new HashSet <String >(); 65 HashMap <String , Method > operations = new HashMap <String , Method >(); 66 HashSet <String > operationBlackList = new HashSet <String >(); 67 68 public ServiceMBeanDelegate(MBeanServer server, ServiceContainer container, Class intf, ObjectName on) 69 { 70 this.container = container; 71 this.server = server; 72 serviceOn = on; 73 StandardMBean mbean = null; 74 try 75 { 76 mbean = new StandardMBean (container.getSingleton(), intf); 77 } 78 catch (NotCompliantMBeanException e) 79 { 80 throw new RuntimeException (e); 81 } 82 mbeanInfo = mbean.getMBeanInfo(); 83 } 84 85 public ObjectName getObjectName() 86 { 87 return serviceOn; 88 } 89 90 public void register(ObjectName on, Class intf) throws Exception 91 { 92 server.registerMBean(this, serviceOn); 93 } 94 95 public void unregister() throws Exception 96 { 97 server.unregisterMBean(serviceOn); 98 } 99 100 public Object getAttribute(String attribute) throws AttributeNotFoundException , 101 MBeanException , ReflectionException 102 { 103 Method getter = getGetter(attribute); 104 105 try 106 { 107 return container.localInvoke(getter, new Object [0]); 108 } 109 catch (Throwable t) 110 { 111 if (t instanceof Exception ) throw new MBeanException ((Exception ) t); 112 else throw new RuntimeException (t); 113 } 114 } 115 116 public void setAttribute(Attribute attribute) throws AttributeNotFoundException , 117 InvalidAttributeValueException , MBeanException , ReflectionException 118 { 119 Method setter = getSetter(attribute); 120 try 121 { 122 container.localInvoke(setter, new Object []{attribute.getValue()}); 123 } 124 catch (Throwable t) 125 { 126 if (t instanceof Exception ) throw new MBeanException ((Exception ) t); 127 else throw new RuntimeException (t); 128 } 129 } 130 131 public AttributeList getAttributes(String [] attributes) 132 { 133 AttributeList list = new AttributeList (); 134 135 for (int i = 0; i < attributes.length; i++) 136 { 137 try 138 { 139 Object obj = getAttribute(attributes[i]); 140 list.add(new Attribute (attributes[i], obj)); 141 } 142 catch (Exception e) 143 { 144 throw new RuntimeException ("Error reading attribute: " + attributes[i], e); 145 } 146 } 147 return list; 148 } 149 150 public AttributeList setAttributes(AttributeList attributes) 151 { 152 for (Iterator it = attributes.iterator(); it.hasNext();) 153 { 154 Attribute attribute = (Attribute ) it.next(); 155 try 156 { 157 setAttribute(attribute); 158 } 159 catch (Exception e) 160 { 161 throw new RuntimeException ("Error setting attribute: " + attribute, e); 162 } 163 } 164 return attributes; 165 } 166 167 public Object invoke(String actionName, Object params[], String signature[]) 168 throws MBeanException , ReflectionException 169 { 170 if(log.isTraceEnabled()) 171 log.trace("invoke: " + actionName); 172 173 try 174 { 175 182 Method operation = getOperation(actionName, signature); 183 return container.localInvoke(operation, params); 184 } 185 catch (Throwable t) 186 { 187 if (t instanceof Exception ) throw new MBeanException ((Exception ) t); 188 else throw new RuntimeException (t); 189 } 190 } 191 192 public MBeanInfo getMBeanInfo() 193 { 194 return mbeanInfo; 195 } 196 197 private String getOperationSignature(String actionName, String [] types) 198 { 199 StringBuffer sig = new StringBuffer (); 201 sig.append(actionName); 202 203 if (types != null) 204 { 205 for (int i = 0; i < types.length; i++) 206 { 207 sig.append(" "); 208 sig.append(types[i]); 209 } 210 } 211 return sig.toString(); 212 } 213 214 private Method getGetter(String attribute) throws AttributeNotFoundException 215 { 216 Method getter = getterMethods.get(attribute); 217 218 if (getter == null && !getterBlackList.contains(attribute)) 219 { 220 synchronized (getterMethods) 221 { 222 getter = getterMethods.get(attribute); 223 if (getter == null) 224 { 225 try 226 { 227 MBeanAttributeInfo [] attrInfos = mbeanInfo.getAttributes(); 228 for (int i = 0; i < attrInfos.length; i++) 229 { 230 MBeanAttributeInfo attrInfo = attrInfos[i]; 231 if (attrInfo.getName().equals(attribute)) 232 { 233 if (!attrInfo.isReadable()) 234 { 235 throw new AttributeNotFoundException ("Attribute '" + attribute + "' is not writable in " + container.getBeanClass().getName()); 236 } 237 238 String getterName = ((attrInfo.isIs()) ? "is" : "get") + attribute; 239 getter = container.getBeanClass().getMethod(getterName); 240 getterMethods.put(attribute, getter); 241 } 242 } 243 244 if (getter == null) 245 { 246 throw new AttributeNotFoundException ("No attribute called '" + attribute + "' in " + container.getBeanClass()); 247 } 248 } 249 catch (NoSuchMethodException e) 250 { 251 throw new AttributeNotFoundException ("Could not find getter for attribute '" + attribute + "' on " + container.getBeanClass().getName()); 252 } 253 finally 254 { 255 if (getter == null) 256 { 257 getterBlackList.add(attribute); 258 } 259 } 260 } 261 } 262 } 263 264 return getter; 265 } 266 267 private Method getSetter(Attribute attribute) throws AttributeNotFoundException 268 { 269 String attrName = attribute.getName(); 270 Method setter = setterMethods.get(attrName); 271 272 if (setter == null && !setterBlackList.contains(attrName)) 273 { 274 synchronized (setterMethods) 275 { 276 setter = setterMethods.get(attrName); 277 if (setter == null) 278 { 279 try 280 { 281 MBeanAttributeInfo [] attrInfos = mbeanInfo.getAttributes(); 282 for (int i = 0; i < attrInfos.length; i++) 283 { 284 MBeanAttributeInfo attrInfo = attrInfos[i]; 285 if (attrInfo.getName().equals(attrName)) 286 { 287 if (!attrInfo.isWritable()) 288 { 289 throw new AttributeNotFoundException ("Attribute '" + attrName + "' is not readable in " + container.getBeanClass().getName()); 290 } 291 292 String setterName = "set" + attrName; 293 Class type = Classes.loadClass(attrInfo.getType()); 294 setter = container.getBeanClass().getMethod(setterName, type); 295 setterMethods.put(attrName, setter); 296 } 297 } 298 299 if (setter == null) 300 { 301 throw new AttributeNotFoundException ("No attribute called '" + attribute + "' in " + container.getBeanClass()); 302 } 303 } 304 catch (ClassNotFoundException e) 305 { 306 throw new AttributeNotFoundException ("Could not load setter type for attribute '" + attrName + "' on " + container.getBeanClass().getName()); 307 } 308 catch (NoSuchMethodException e) 309 { 310 throw new AttributeNotFoundException ("Could not find setter for attribute '" + attrName + "' on " + container.getBeanClass().getName()); 311 } 312 finally 313 { 314 if (setter == null) 315 { 316 setterBlackList.add(attrName); 317 } 318 } 319 } 320 } 321 } 322 323 return setter; 324 } 325 326 private Method getOperation(String actionName, String [] signature) throws ReflectionException 327 { 328 String opSig = getOperationSignature(actionName, signature); 329 Method operation = operations.get(actionName); 330 331 if (operation == null && !setterBlackList.contains(opSig)) 332 { 333 synchronized (setterMethods) 334 { 335 operation = operations.get(opSig); 336 if (operation == null) 337 { 338 try 339 { 340 MBeanOperationInfo [] opInfos = mbeanInfo.getOperations(); 341 for (int i = 0; i < opInfos.length; i++) 342 { 343 MBeanOperationInfo op = opInfos[i]; 344 if (op.getName().equals(actionName)) 345 { 346 boolean match = true; 347 MBeanParameterInfo [] sigTypes = op.getSignature(); 348 if (sigTypes.length == signature.length) 349 { 350 for (int j = 0; j < sigTypes.length; j++) 351 { 352 if (!sigTypes[j].getType().equals(signature[j])) 353 { 354 match = false; 355 break; 356 } 357 } 358 } 359 360 if (match) 361 { 362 Class [] types = null; 363 if (signature.length > 0) 364 { 365 types = new Class [signature.length]; 366 for (int j = 0; j < signature.length; j++) 367 { 368 types[j] = Classes.loadClass(signature[j]); 369 } 370 } 371 else 372 { 373 types = new Class [0]; 374 } 375 operation = container.getBeanClass().getMethod(actionName, types); 376 operations.put(opSig, operation); 377 } 378 } 379 } 380 381 if (operation == null) 382 { 383 throw new RuntimeException ("No operation called '" + actionName + "' in " + container.getBeanClass()); 384 } 385 386 } 387 catch (ClassNotFoundException e) 388 { 389 throw new RuntimeException ("Could not find type for operation '" + actionName + "' on " + container.getBeanClass().getName()); 390 } 391 catch (NoSuchMethodException e) 392 { 393 throw new RuntimeException ("Could not find method for operation '" + actionName + "' on " + container.getBeanClass().getName()); 394 } 395 finally 396 { 397 if (operation == null) 398 { 399 operationBlackList.add(opSig); 400 } 401 } 402 } 403 } 404 } 405 406 return operation; 407 } 408 409 437 } 438 | Popular Tags |