1 7 8 package com.sun.jmx.remote.util; 9 10 import java.io.IOException ; 11 import java.io.ObjectOutputStream ; 12 import java.io.OutputStream ; 13 import java.util.Collection ; 14 import java.util.HashMap ; 15 import java.util.Hashtable ; 16 import java.util.Iterator ; 17 import java.util.Map ; 18 import java.util.SortedMap ; 19 import java.util.SortedSet ; 20 import java.util.StringTokenizer ; 21 import java.util.TreeMap ; 22 import java.util.TreeSet ; 23 24 import java.security.AccessController ; 25 import java.security.PrivilegedAction ; 26 import java.security.PrivilegedActionException ; 27 import java.security.PrivilegedExceptionAction ; 28 29 import javax.management.ObjectName ; 30 import javax.management.MBeanServer ; 31 import javax.management.InstanceNotFoundException ; 32 import javax.management.remote.JMXConnectorFactory ; 33 import javax.management.remote.JMXConnectorServerFactory ; 34 import com.sun.jmx.mbeanserver.GetPropertyAction; 35 36 public class EnvHelp { 37 38 43 private static final String DEFAULT_CLASS_LOADER = 44 JMXConnectorFactory.DEFAULT_CLASS_LOADER; 45 46 51 private static final String DEFAULT_CLASS_LOADER_NAME = 52 JMXConnectorServerFactory.DEFAULT_CLASS_LOADER_NAME; 53 54 102 public static ClassLoader resolveServerClassLoader(Map env, 103 MBeanServer mbs) 104 throws InstanceNotFoundException { 105 106 if (env == null) 107 return Thread.currentThread().getContextClassLoader(); 108 109 Object loader = env.get(DEFAULT_CLASS_LOADER); 110 Object name = env.get(DEFAULT_CLASS_LOADER_NAME); 111 112 if (loader != null && name != null) { 113 final String msg = "Only one of " + 114 DEFAULT_CLASS_LOADER + " or " + 115 DEFAULT_CLASS_LOADER_NAME + 116 " should be specified."; 117 throw new IllegalArgumentException (msg); 118 } 119 120 if (loader == null && name == null) 121 return Thread.currentThread().getContextClassLoader(); 122 123 if (loader != null) { 124 if (loader instanceof ClassLoader ) { 125 return (ClassLoader ) loader; 126 } else { 127 final String msg = 128 "ClassLoader object is not an instance of " + 129 ClassLoader .class.getName() + " : " + 130 loader.getClass().getName(); 131 throw new IllegalArgumentException (msg); 132 } 133 } 134 135 ObjectName on; 136 if (name instanceof ObjectName ) { 137 on = (ObjectName ) name; 138 } else { 139 final String msg = 140 "ClassLoader name is not an instance of " + 141 ObjectName .class.getName() + " : " + 142 name.getClass().getName(); 143 throw new IllegalArgumentException (msg); 144 } 145 146 if (mbs == null) 147 throw new IllegalArgumentException ("Null MBeanServer object"); 148 149 return mbs.getClassLoader(on); 150 } 151 152 179 public static ClassLoader resolveClientClassLoader(Map env) { 180 181 if (env == null) 182 return Thread.currentThread().getContextClassLoader(); 183 184 Object loader = env.get(DEFAULT_CLASS_LOADER); 185 186 if (loader == null) 187 return Thread.currentThread().getContextClassLoader(); 188 189 if (loader instanceof ClassLoader ) { 190 return (ClassLoader ) loader; 191 } else { 192 final String msg = 193 "ClassLoader object is not an instance of " + 194 ClassLoader .class.getName() + " : " + 195 loader.getClass().getName(); 196 throw new IllegalArgumentException (msg); 197 } 198 } 199 200 207 public static <T extends Throwable > T initCause(T throwable, 208 Throwable cause) { 209 throwable.initCause(cause); 210 return throwable; 211 } 212 213 221 public static Throwable getCause(Throwable t) { 222 Throwable ret = t; 223 224 try { 225 java.lang.reflect.Method getCause = 226 t.getClass().getMethod("getCause", (Class []) null); 227 ret = (Throwable )getCause.invoke(t, (Object []) null); 228 229 } catch (Exception e) { 230 } 233 return (ret != null) ? ret: t; 234 } 235 236 237 241 public static final String BUFFER_SIZE_PROPERTY = 242 "jmx.remote.x.notification.buffer.size"; 243 244 245 249 public static int getNotifBufferSize(Map env) { 250 int defaultQueueSize = 1000; 252 final String oldP = "jmx.remote.x.buffer.size"; 256 257 try { 259 GetPropertyAction act = new GetPropertyAction(BUFFER_SIZE_PROPERTY); 260 String s = (String )AccessController.doPrivileged(act); 261 if (s != null) { 262 defaultQueueSize = Integer.parseInt(s); 263 } else { act = new GetPropertyAction(oldP); 265 s = (String )AccessController.doPrivileged(act); 266 if (s != null) { 267 defaultQueueSize = Integer.parseInt(s); 268 } 269 } 270 } catch (RuntimeException e) { 271 logger.warning("getNotifBufferSize", 272 "Can't use System property "+ 273 BUFFER_SIZE_PROPERTY+ ": " + e); 274 logger.debug("getNotifBufferSize", e); 275 } 276 277 int queueSize = defaultQueueSize; 278 279 try { 280 if (env.containsKey(BUFFER_SIZE_PROPERTY)) { 281 queueSize = (int)EnvHelp.getIntegerAttribute(env,BUFFER_SIZE_PROPERTY, 282 defaultQueueSize,0, 283 Integer.MAX_VALUE); 284 } else { queueSize = (int)EnvHelp.getIntegerAttribute(env,oldP, 286 defaultQueueSize,0, 287 Integer.MAX_VALUE); 288 } 289 } catch (RuntimeException e) { 290 logger.warning("getNotifBufferSize", 291 "Can't determine queuesize (using default): "+ 292 e); 293 logger.debug("getNotifBufferSize", e); 294 } 295 296 return queueSize; 297 } 298 299 305 public static final String MAX_FETCH_NOTIFS = 306 "jmx.remote.x.notification.fetch.max"; 307 308 312 public static int getMaxFetchNotifNumber(Map env) { 313 return (int) getIntegerAttribute(env, MAX_FETCH_NOTIFS, 1000, 1, 314 Integer.MAX_VALUE); 315 } 316 317 323 public static final String FETCH_TIMEOUT = 324 "jmx.remote.x.notification.fetch.timeout"; 325 326 329 public static long getFetchTimeout(Map env) { 330 return getIntegerAttribute(env, FETCH_TIMEOUT, 60000L, 0, 331 Long.MAX_VALUE); 332 } 333 334 346 public static long getIntegerAttribute(Map env, String name, 347 long defaultValue, long minValue, 348 long maxValue) { 349 final Object o; 350 351 if (env == null || (o = env.get(name)) == null) 352 return defaultValue; 353 354 final long result; 355 356 if (o instanceof Number ) 357 result = ((Number ) o).longValue(); 358 else if (o instanceof String ) { 359 result = Long.parseLong((String ) o); 360 362 } else { 363 final String msg = 364 "Attribute " + name + " value must be Integer or String: " + o; 365 throw new IllegalArgumentException (msg); 366 } 367 368 if (result < minValue) { 369 final String msg = 370 "Attribute " + name + " value must be at least " + minValue + 371 ": " + result; 372 throw new IllegalArgumentException (msg); 373 } 374 375 if (result > maxValue) { 376 final String msg = 377 "Attribute " + name + " value must be at most " + maxValue + 378 ": " + result; 379 throw new IllegalArgumentException (msg); 380 } 381 382 return result; 383 } 384 385 public static final String DEFAULT_ORB="java.naming.corba.orb"; 386 387 389 public static void checkAttributes(Map attributes) { 390 for (Iterator it = attributes.keySet().iterator(); it.hasNext(); ) { 391 Object key = it.next(); 392 if (!(key instanceof String )) { 393 final String msg = 394 "Attributes contain key that is not a string: " + key; 395 throw new IllegalArgumentException (msg); 396 } 397 } 398 } 399 400 404 public static Map filterAttributes(Map attributes) { 405 if (logger.traceOn()) { 406 logger.trace("filterAttributes", "starts"); 407 } 408 409 SortedMap map = new TreeMap (attributes); 410 purgeUnserializable(map.values()); 411 hideAttributes(map); 412 return map; 413 } 414 415 419 private static void purgeUnserializable(Collection objects) { 420 logger.trace("purgeUnserializable", "starts"); 421 ObjectOutputStream oos = null; 422 int i = 0; 423 for (Iterator it = objects.iterator(); it.hasNext(); i++) { 424 Object v = it.next(); 425 426 if (v == null || v instanceof String ) { 427 if (logger.traceOn()) { 428 logger.trace("purgeUnserializable", 429 "Value trivially serializable: " + v); 430 } 431 continue; 432 } 433 434 try { 435 if (oos == null) 436 oos = new ObjectOutputStream (new SinkOutputStream()); 437 oos.writeObject(v); 438 if (logger.traceOn()) { 439 logger.trace("purgeUnserializable", 440 "Value serializable: " + v); 441 } 442 } catch (IOException e) { 443 if (logger.traceOn()) { 444 logger.trace("purgeUnserializable", 445 "Value not serializable: " + v + ": " + 446 e); 447 } 448 it.remove(); 449 oos = null; } 451 } 452 } 453 454 467 public static final String HIDDEN_ATTRIBUTES = 468 "jmx.remote.x.hidden.attributes"; 469 470 474 479 public static final String DEFAULT_HIDDEN_ATTRIBUTES = 480 "java.naming.security.* " + 481 "jmx.remote.authenticator " + 482 "jmx.remote.context " + 483 "jmx.remote.default.class.loader " + 484 "jmx.remote.message.connection.server " + 485 "jmx.remote.object.wrapping " + 486 "jmx.remote.rmi.client.socket.factory " + 487 "jmx.remote.rmi.server.socket.factory " + 488 "jmx.remote.sasl.callback.handler " + 489 "jmx.remote.tls.socket.factory " + 490 "jmx.remote.x.access.file " + 491 "jmx.remote.x.password.file "; 492 493 private static final SortedSet defaultHiddenStrings = new TreeSet (); 494 private static final SortedSet defaultHiddenPrefixes = new TreeSet (); 495 496 private static void hideAttributes(SortedMap map) { 497 if (map.isEmpty()) 498 return; 499 500 final SortedSet hiddenStrings; 501 final SortedSet hiddenPrefixes; 502 503 String hide = (String ) map.get(HIDDEN_ATTRIBUTES); 504 if (hide != null) { 505 if (hide.startsWith("=")) 506 hide = hide.substring(1); 507 else 508 hide += " " + DEFAULT_HIDDEN_ATTRIBUTES; 509 hiddenStrings = new TreeSet (); 510 hiddenPrefixes = new TreeSet (); 511 parseHiddenAttributes(hide, hiddenStrings, hiddenPrefixes); 512 } else { 513 hide = DEFAULT_HIDDEN_ATTRIBUTES; 514 synchronized (defaultHiddenStrings) { 515 if (defaultHiddenStrings.isEmpty()) { 516 parseHiddenAttributes(hide, 517 defaultHiddenStrings, 518 defaultHiddenPrefixes); 519 } 520 hiddenStrings = defaultHiddenStrings; 521 hiddenPrefixes = defaultHiddenPrefixes; 522 } 523 } 524 525 529 String sentinelKey = map.lastKey() + "X"; 530 Iterator keyIterator = map.keySet().iterator(); 531 Iterator stringIterator = hiddenStrings.iterator(); 532 Iterator prefixIterator = hiddenPrefixes.iterator(); 533 534 String nextString; 535 if (stringIterator.hasNext()) 536 nextString = (String ) stringIterator.next(); 537 else 538 nextString = sentinelKey; 539 String nextPrefix; 540 if (prefixIterator.hasNext()) 541 nextPrefix = (String ) prefixIterator.next(); 542 else 543 nextPrefix = sentinelKey; 544 545 547 keys: 548 while (keyIterator.hasNext()) { 549 String key = (String ) keyIterator.next(); 550 551 554 int cmp = +1; 555 while ((cmp = nextString.compareTo(key)) < 0) { 556 if (stringIterator.hasNext()) 557 nextString = (String ) stringIterator.next(); 558 else 559 nextString = sentinelKey; 560 } 561 if (cmp == 0) { 562 keyIterator.remove(); 563 continue keys; 564 } 565 566 569 while (nextPrefix.compareTo(key) <= 0) { 570 if (key.startsWith(nextPrefix)) { 571 keyIterator.remove(); 572 continue keys; 573 } 574 if (prefixIterator.hasNext()) 575 nextPrefix = (String ) prefixIterator.next(); 576 else 577 nextPrefix = sentinelKey; 578 } 579 } 580 } 581 582 private static void parseHiddenAttributes(String hide, 583 SortedSet hiddenStrings, 584 SortedSet hiddenPrefixes) { 585 final StringTokenizer tok = new StringTokenizer (hide); 586 while (tok.hasMoreTokens()) { 587 String s = tok.nextToken(); 588 if (s.endsWith("*")) 589 hiddenPrefixes.add(s.substring(0, s.length() - 1)); 590 else 591 hiddenStrings.add(s); 592 } 593 } 594 595 600 public static final String SERVER_CONNECTION_TIMEOUT = 601 "jmx.remote.x.server.connection.timeout"; 602 603 606 public static long getServerConnectionTimeout(Map env) { 607 return getIntegerAttribute(env, SERVER_CONNECTION_TIMEOUT, 120000L, 608 0, Long.MAX_VALUE); 609 } 610 611 616 public static final String CLIENT_CONNECTION_CHECK_PERIOD = 617 "jmx.remote.x.client.connection.check.period"; 618 619 622 public static long getConnectionCheckPeriod(Map env) { 623 return getIntegerAttribute(env, CLIENT_CONNECTION_CHECK_PERIOD, 60000L, 624 0, Long.MAX_VALUE); 625 } 626 627 631 public static Hashtable mapToHashtable(Map map) { 632 HashMap m = new HashMap (map); 633 if (m.containsKey(null)) m.remove(null); 634 for (Iterator i = m.values().iterator(); i.hasNext(); ) 635 if (i.next() == null) i.remove(); 636 return new Hashtable (m); 637 } 638 639 private static final class SinkOutputStream extends OutputStream { 640 public void write(byte[] b, int off, int len) {} 641 public void write(int b) {} 642 } 643 644 private static final ClassLogger logger = 645 new ClassLogger("javax.management.remote.misc", "EnvHelp"); 646 } 647 | Popular Tags |