1 22 package org.jboss.mx.util; 23 24 import java.beans.PropertyEditor ; 25 import java.beans.PropertyEditorManager ; 26 import java.io.InputStream ; 27 import java.util.Date ; 28 import java.util.HashMap ; 29 import java.util.List ; 30 import java.util.Map ; 31 32 import javax.management.InstanceNotFoundException ; 33 import javax.management.MBeanException ; 34 import javax.management.MBeanServer ; 35 import javax.management.MalformedObjectNameException ; 36 import javax.management.ObjectInstance ; 37 import javax.management.ObjectName ; 38 import javax.management.ReflectionException ; 39 40 import org.jboss.logging.Logger; 41 import org.jboss.mx.loading.MBeanElement; 42 import org.jboss.mx.server.ObjectInputStreamWithClassLoader; 43 import org.jboss.mx.server.ServerConstants; 44 import org.jboss.util.UnreachableStatementException; 45 46 99 public class MBeanInstaller 100 { 101 103 public static final String VERSIONS = "versions"; 104 public static final String DATE = "date"; 105 106 107 109 112 private static final Logger log = Logger.getLogger(MBeanInstaller.class); 113 114 118 static 119 { 120 Class c = org.jboss.util.propertyeditor.PropertyEditors.class; 121 if (c == null) 122 throw new UnreachableStatementException(); 123 } 124 125 126 128 131 private MBeanServer server; 132 133 137 private ClassLoader ctxClassLoader; 138 139 147 private ObjectName loaderName; 148 149 152 private ObjectName registryName; 153 154 155 157 171 public MBeanInstaller(MBeanServer server, ClassLoader ctxClassLoader, ObjectName loaderName) 172 throws Exception 173 { 174 this.server = server; 175 this.ctxClassLoader = ctxClassLoader; 176 this.loaderName = loaderName; 177 this.registryName = new ObjectName (ServerConstants.MBEAN_REGISTRY); 178 } 179 180 181 183 190 public ObjectInstance installMBean(MBeanElement element) 191 throws MBeanException , 192 ReflectionException , 193 InstanceNotFoundException , 194 MalformedObjectNameException 195 { 196 log.debug("Installing MBean: " + element); 197 198 ObjectInstance instance = null; 199 ObjectName elementName = getElementName(element); 200 201 if (element.getVersions().isEmpty() || !server.isRegistered(elementName)) 202 { 203 if (element.getCode() != null) 204 instance = createMBean(element); 205 else if (element.getObject() != null) 206 instance = deserialize(element); 207 else 208 throw new MBeanException (new IllegalArgumentException ("No code or object tag")); 209 } 210 else 211 instance = updateMBean(element); 212 213 return instance; 214 } 215 216 public ObjectInstance createMBean(MBeanElement element) 217 throws MBeanException , 218 ReflectionException , 219 InstanceNotFoundException , 220 MalformedObjectNameException 221 { 222 log.debug("Creating MBean.. "); 223 224 ObjectName elementName = getElementName(element); 225 226 Map valueMap = createValueMap(element); 229 230 232 236 String [] classes = element.getConstructorTypes(); 237 String [] paramStrings = element.getConstructorValues(); 238 Object [] params = new Object [paramStrings.length]; 239 for (int i = 0; i < paramStrings.length; ++i) 240 { 241 try 242 { 243 Class typeClass = server.getClassLoaderRepository().loadClass(classes[i]); 244 PropertyEditor editor = PropertyEditorManager.findEditor(typeClass); 245 if (editor == null) 246 throw new IllegalArgumentException ("No property editor for type=" + typeClass); 247 248 editor.setAsText(paramStrings[i]); 249 params[i] = editor.getValue(); 250 } 251 catch (Exception e) 252 { 253 throw new MBeanException (e); 254 } 255 } 256 Object instance = server.instantiate( 257 element.getCode(), 258 loaderName, 259 params, 260 classes); 261 262 return registerMBean(instance, elementName, valueMap); 265 } 266 267 public ObjectInstance deserialize(MBeanElement element) throws MBeanException , 268 ReflectionException , 269 InstanceNotFoundException , 270 MalformedObjectNameException 271 { 272 InputStream is = null; 273 Object instance = null; 274 try 275 { 276 is = ctxClassLoader.getResourceAsStream(element.getObject()); 277 if (is == null) 278 throw new IllegalArgumentException ("Object not found " + element.getObject()); 279 ObjectInputStreamWithClassLoader ois = new ObjectInputStreamWithClassLoader(is, ctxClassLoader); 280 instance = ois.readObject(); 281 } 282 catch (Exception e) 283 { 284 throw new MBeanException (e); 285 } 286 finally 287 { 288 if (is != null) 289 { 290 try 291 { 292 is.close(); 293 } 294 catch (Exception ignored) 295 { 296 } 297 } 298 } 299 ObjectName elementName = getElementName(element); 300 301 Map valueMap = createValueMap(element); 304 return registerMBean(instance, elementName, valueMap); 305 } 306 307 public ObjectInstance updateMBean(MBeanElement element) 308 throws MBeanException , 309 ReflectionException , 310 InstanceNotFoundException , 311 MalformedObjectNameException 312 { 313 log.debug("updating MBean... "); 314 315 ObjectName elementName = getElementName(element); 316 317 MLetVersion preVersion = new MLetVersion(getVersions(elementName)); 319 MLetVersion newVersion = new MLetVersion(element.getVersions()); 320 321 log.debug("Installed version : " + preVersion); 322 log.debug("Loaded version : " + newVersion); 323 324 if (!preVersion.isNull() && !newVersion.isNull() && preVersion.compareTo(newVersion) < 0) 327 { 328 if (server.isRegistered(elementName)) 330 { 331 unregisterMBean(elementName); 332 333 log.debug("Unregistering previous version " + preVersion); 334 } 335 336 log.debug("Installing newer version " + newVersion); 337 338 return createMBean(element); 340 } 341 342 return server.getObjectInstance(elementName); 343 } 344 345 346 348 private ObjectName getElementName(MBeanElement element) 349 throws MalformedObjectNameException 350 { 351 return (element.getName() != null) ? new ObjectName (element.getName()) : null; 352 } 353 354 private Map createValueMap(MBeanElement element) 355 { 356 HashMap valueMap = new HashMap (); 357 358 if (element.getVersions() != null && !element.getVersions().isEmpty()) 361 valueMap.put(VERSIONS, element.getVersions()); 362 363 valueMap.put(DATE, new Date (System.currentTimeMillis())); 365 366 valueMap.put(ServerConstants.CLASSLOADER, ctxClassLoader); 368 369 return valueMap; 370 } 371 372 private List getVersions(ObjectName name) 373 throws MBeanException , ReflectionException , InstanceNotFoundException 374 { 375 if (!server.isRegistered(name)) 376 return null; 377 378 return (List ) getValue(name, VERSIONS); 379 } 380 381 382 private Object getValue(ObjectName name, String key) 383 throws MBeanException , ReflectionException , InstanceNotFoundException 384 { 385 Object value = 386 server.invoke(registryName, "getValue", 387 new Object [] 388 { 389 name, 390 key 391 }, 392 new String [] 393 { 394 ObjectName .class.getName(), 395 String .class.getName() 396 } 397 ); 398 399 return value; 400 } 401 402 private ObjectInstance registerMBean(Object object, ObjectName name, Map valueMap) 403 throws MBeanException , ReflectionException , InstanceNotFoundException 404 { 405 if (object == null) 406 { 407 throw new ReflectionException (new IllegalArgumentException ( 408 "Attempting to register a null object" 409 )); 410 } 411 412 return (ObjectInstance ) 413 server.invoke(registryName, "registerMBean", 414 new Object [] 415 { 416 object, 417 name, 418 valueMap 419 }, 420 new String [] 421 { 422 Object .class.getName(), 423 ObjectName .class.getName(), 424 Map .class.getName() 425 } 426 ); 427 } 428 429 private void unregisterMBean(ObjectName name) 430 throws MBeanException , ReflectionException , InstanceNotFoundException 431 { 432 server.invoke(registryName, "unregisterMBean", 433 new Object [] 434 { 435 name, 436 }, 437 new String [] 438 { 439 ObjectName .class.getName(), 440 } 441 ); 442 } 443 } 444 445 451 class MLetVersion implements Comparable 452 { 453 protected List versions; 454 455 public MLetVersion(List versions) 456 { 457 this.versions = versions; 458 } 459 460 public List getVersions() 461 { 462 return versions; 463 } 464 465 public boolean isNull() 466 { 467 return versions == null || versions.isEmpty(); 468 } 469 470 public int compareTo(Object o) 471 { 472 MLetVersion other = (MLetVersion) o; 473 474 if (isNull() || other.isNull()) 475 throw new IllegalArgumentException ("MLet versions is null"); 476 477 String thisVersion = (String ) versions.get(0); 480 String otherVersion = (String ) other.getVersions().get(0); 481 482 return (thisVersion.compareTo(otherVersion)); 483 } 484 485 public String toString() 486 { 487 return "Version " + versions.get(0); 488 } 489 } 490 | Popular Tags |