1 22 package org.jboss.varia.deployment; 23 24 import java.io.InputStream ; 25 import java.lang.reflect.InvocationTargetException ; 26 import java.lang.reflect.Method ; 27 import java.util.ArrayList ; 28 import java.util.Arrays ; 29 import java.util.HashMap ; 30 import java.util.Iterator ; 31 32 import javax.management.Attribute ; 33 import javax.management.AttributeNotFoundException ; 34 import javax.management.IntrospectionException ; 35 import javax.management.InvalidAttributeValueException ; 36 import javax.management.MBeanAttributeInfo ; 37 import javax.management.MBeanException ; 38 import javax.management.MBeanInfo ; 39 import javax.management.MBeanOperationInfo ; 40 import javax.management.ObjectName ; 41 import javax.management.ReflectionException ; 42 43 import org.jboss.deployment.DeploymentException; 44 import org.jboss.deployment.DeploymentInfo; 45 import org.jboss.system.ServiceDynamicMBeanSupport; 46 import org.jboss.util.Classes; 47 48 import bsh.EvalError; 49 import bsh.Interpreter; 50 51 60 public class BeanShellScript extends ServiceDynamicMBeanSupport 61 { 62 63 protected DeploymentInfo deploymentInfo = null; 64 protected String name = null; 65 66 protected ScriptService scriptService = null; 67 68 protected ObjectName preferedObjectName = null; 69 protected ObjectName [] dependsServices = null; 70 protected HashMap supportedInterfaces = new HashMap (); 71 72 protected MBeanInfo mbeanInfo = null; 73 74 76 78 public BeanShellScript(final DeploymentInfo di) 79 throws DeploymentException 80 { 81 try 82 { 83 this.deploymentInfo = di; 84 String name = deploymentInfo.url.toString(); 85 if (name.endsWith("/")) 86 { 87 name = name.substring(0, name.length() - 1); 88 } 89 this.name = name; 90 91 loadScript (di.url); 92 } 93 catch (Exception e) 94 { 95 throw new DeploymentException (e); 96 } 97 } 98 99 101 103 105 protected Object getInternalAttribute(String attribute) 106 throws AttributeNotFoundException , MBeanException , ReflectionException 107 { 108 try 109 { 110 String action = "get" + attribute.substring(0, 1).toUpperCase() + attribute.substring(1); 111 112 InvocationCouple invoc = retrieveCompatibleInvocation 113 (action, new Class [0]); 114 if (invoc == null) 115 throw new AttributeNotFoundException (attribute + " getter not implemented on target script"); 116 117 return invoc.method.invoke(invoc.proxy, null); 118 119 } 120 catch (ClassNotFoundException cnfe) 121 { 122 throw new javax.management.ReflectionException (cnfe, "A signature class couldn't be loaded"); 123 } 124 catch (IllegalAccessException iae) 125 { 126 throw new javax.management.ReflectionException (iae, "Problem while invoking gettter for field " + attribute); 127 } 128 catch (InvocationTargetException ite) 129 { 130 throw new MBeanException (ite, "Problem while invoking gettter for field " + attribute); 131 } 132 } 133 134 protected void setInternalAttribute(Attribute attribute) 135 throws 136 AttributeNotFoundException , 137 InvalidAttributeValueException , 138 MBeanException , 139 ReflectionException 140 { 141 String field = attribute.getName(); 142 try 143 { 144 String action = "set" + field.substring(0, 1).toUpperCase() + field.substring(1); 145 Object value = attribute.getValue(); 146 Class clazz = value.getClass(); 147 Class tmp = Classes.getPrimitive(clazz); 148 if (tmp != null) 149 clazz = tmp; 150 151 InvocationCouple invoc = retrieveCompatibleInvocation 152 (action, new Class [] {clazz}); 153 if (invoc == null) 154 throw new AttributeNotFoundException (field + " setter not implemented on target script"); 155 156 invoc.method.invoke(invoc.proxy, new Object [] {value}); 157 158 } 159 catch (ClassNotFoundException cnfe) 160 { 161 throw new javax.management.ReflectionException (cnfe, "A signature class couldn't be loaded"); 162 } 163 catch (IllegalAccessException iae) 164 { 165 throw new javax.management.ReflectionException (iae, "Problem while invoking setter for field " + field); 166 } 167 catch (InvocationTargetException ite) 168 { 169 throw new MBeanException (ite, "Problem while invoking setter for field " + field); 170 } 171 } 172 173 protected Object internalInvoke(String actionName, Object [] params, String [] signature) 174 throws MBeanException , ReflectionException 175 { 176 try 177 { 178 InvocationCouple invoc = retrieveCompatibleInvocation (actionName, signature); 179 if (invoc == null) 180 throw new javax.management.ReflectionException (new Exception (), actionName + " not implemented on target script"); 181 182 Object value = invoc.method.invoke(invoc.proxy, params); 183 return value; 184 185 } 186 catch (ClassNotFoundException cnfe) 187 { 188 throw new javax.management.ReflectionException (cnfe, "A signature class couldn't be loaded"); 189 } 190 catch (IllegalAccessException iae) 191 { 192 throw new javax.management.ReflectionException (iae, "Problem while invoking " + actionName); 193 } 194 catch (InvocationTargetException ite) 195 { 196 throw new MBeanException (ite, "Problem while invoking " + actionName); 197 } 198 } 199 200 public MBeanInfo getMBeanInfo() 201 { 202 return this.mbeanInfo; 203 } 204 205 207 protected void createService() throws Exception 208 { 209 try 210 { 211 this.scriptService.setCtx(this); 212 } 213 catch (Exception e) 214 { 215 log.trace("setCtx", e); 216 } 217 218 try 219 { 220 this.scriptService.create(); 221 } 222 catch (EvalError e) 223 { 224 log.trace("start", e); 225 } 226 } 227 228 protected void startService() throws Exception 229 { 230 try 231 { 232 this.scriptService.start(); 233 } 234 catch (EvalError e) 235 { 236 log.trace("start", e); 237 } 238 } 239 240 protected void stopService() throws Exception 241 { 242 try 243 { 244 this.scriptService.stop(); 245 } 246 catch (Exception e) 247 { 248 log.trace("stop", e); 249 } 250 } 251 252 protected void destroyService() throws Exception 253 { 254 try 255 { 256 this.scriptService.destroy(); 257 } 258 catch (Exception e) 259 { 260 log.trace("destroy", e); 261 } 262 } 263 264 266 268 protected InvocationCouple retrieveCompatibleInvocation 269 (String name, String [] signature) 270 throws ClassNotFoundException 271 { 272 ClassLoader ucl = Thread.currentThread().getContextClassLoader(); 273 Class [] realSignature = null; 276 if (signature != null) 277 { 278 realSignature = new Class [signature.length]; 279 for (int i=0; i<signature.length;i++) 280 realSignature[i] = ucl.loadClass(signature[i]); 281 } 282 283 return retrieveCompatibleInvocation (name, realSignature); 284 } 285 286 protected InvocationCouple retrieveCompatibleInvocation 287 (String name, Class [] signature) 288 throws ClassNotFoundException 289 { 290 Iterator keys = supportedInterfaces.keySet().iterator(); 291 while (keys.hasNext()) 292 { 293 Class key = (Class )keys.next(); 294 try 295 { 296 Method method = key.getMethod(name, signature); 297 298 Object targetProxy = supportedInterfaces.get(key); 299 return new InvocationCouple (targetProxy, method); 300 } 301 catch (NoSuchMethodException ok) {} 302 } 303 304 return null; 307 308 309 } 310 311 protected void loadScript (java.net.URL url) throws Exception 312 { 313 Interpreter interpreter = new Interpreter (); 314 interpreter.setClassLoader(Thread.currentThread().getContextClassLoader()); 315 InputStream stream = url.openStream(); 316 try 317 { 318 interpreter.eval (new java.io.InputStreamReader (stream)); 319 } 320 finally 321 { 322 try 323 { 324 stream.close(); 325 } 326 catch (Exception strange) { log.info(strange); } 327 } 328 329 scriptService = (ScriptService)interpreter.getInterface(ScriptService.class); 330 331 String [] depends = null; 334 try 335 { 336 depends = scriptService.dependsOn(); 337 } 338 catch (Exception e) 339 { 340 log.trace("dependsOn", e); 341 } 342 if (depends != null) 343 { 344 dependsServices = new ObjectName [depends.length]; 345 for (int i=0; i<depends.length; i++) 346 dependsServices[i] = new ObjectName (depends[i]); 347 } 348 349 String myName = null; 350 try 351 { 352 myName = scriptService.objectName (); 353 } 354 catch (Exception e) 355 { 356 log.trace("objectName", e); 357 } 358 if (myName != null) 359 this.preferedObjectName = new ObjectName (myName); 360 361 Class [] intfs = null; 362 try 363 { 364 intfs = scriptService.getInterfaces (); 365 if (intfs != null) 366 log.debug("getInterfaces=" + Arrays.asList(intfs)); 367 } 368 catch (Exception e) 369 { 370 log.trace("getInterfaces", e); 371 } 372 if (intfs != null) 373 { 374 for (int i=0; i<intfs.length; i++) 375 { 376 Object iface = interpreter.getInterface(intfs[i]); 377 supportedInterfaces.put (intfs[i], iface); 378 } 379 } 380 381 this.mbeanInfo = generateMBeanInfo (intfs); 382 log.debug("mbeanInfo=" + mbeanInfo); 383 384 } 385 386 protected MBeanInfo generateMBeanInfo (Class [] intfs) 387 throws IntrospectionException 388 { 389 MBeanInfo result = super.getMBeanInfo(); 390 391 if (intfs != null && intfs.length > 0) 392 { 393 ArrayList attrs = new ArrayList (Arrays.asList(result.getAttributes())); 394 ArrayList ops = new ArrayList (Arrays.asList(result.getOperations())); 395 396 HashMap readAttr = new HashMap (); 397 HashMap writeAttr = new HashMap (); 398 399 for (int i=0; i<intfs.length; i++) 402 { 403 Class clazz = intfs[i]; 404 Method [] methods = clazz.getMethods(); 405 for (int m=0; m<methods.length; m++) 406 { 407 Method meth = methods[m]; 408 String name = meth.getName(); 409 Class [] params = meth.getParameterTypes(); 410 411 if (name.startsWith("get") && params.length == 0) 412 { 413 readAttr.put (name, meth); 414 } 415 else if (name.startsWith("set") && params.length == 1) 416 { 417 writeAttr.put (name, meth); 418 } 419 else 420 { 421 ops.add(new MBeanOperationInfo 422 ( 423 "Method " + name + " from class/interface " + clazz.getName(), meth 424 ) 425 ); 426 427 } 428 } 429 } 430 431 Iterator readKeys = readAttr.keySet().iterator(); 434 while (readKeys.hasNext()) 435 { 436 String getter = (String )readKeys.next(); 437 Method getterMethod = (Method )readAttr.get( getter ); 438 439 String attribute = getter.substring(3); 440 String setter = "set" + attribute; 441 442 Method setterMethod = (Method )writeAttr.remove(setter); 443 attrs.add (new MBeanAttributeInfo (attribute, "", getterMethod, setterMethod)); 444 } 445 446 Iterator writeKeys = writeAttr.keySet().iterator(); 449 while (writeKeys.hasNext()) 450 { 451 String setter = (String )writeKeys.next(); 452 Method setterMethod = (Method )writeAttr.get( setter ); 453 String attribute = setter.substring(3); 454 455 attrs.add (new MBeanAttributeInfo (attribute, "", null, setterMethod)); 456 } 457 458 459 result = new MBeanInfo (this.name, 460 "Dynamic MBean Service around BSH script " + this.name, 461 (MBeanAttributeInfo [])attrs.toArray(new MBeanAttributeInfo [attrs.size()]), 462 result.getConstructors(), 463 (MBeanOperationInfo [])ops.toArray(new MBeanOperationInfo [ops.size()]), 464 result.getNotifications()); 465 } 466 467 return result; 468 } 469 470 public ObjectName getPreferedObjectName () 471 { 472 return this.preferedObjectName; 473 } 474 475 public ObjectName [] getDependsServices () 476 { 477 return this.dependsServices; 478 } 479 480 482 484 public class InvocationCouple 485 { 486 public Object proxy = null; 487 public Method method = null; 488 489 public InvocationCouple (Object proxy, Method m) 490 { 491 this.proxy = proxy; 492 this.method = m; 493 } 494 495 } 496 } 497 | Popular Tags |