< prev index next >

src/java.management/share/classes/com/sun/jmx/remote/util/EnvHelp.java

Print this page




  38 import java.util.SortedSet;
  39 import java.util.StringTokenizer;
  40 import java.util.TreeMap;
  41 import java.util.TreeSet;
  42 
  43 import java.security.AccessController;
  44 
  45 import javax.management.ObjectName;
  46 import javax.management.MBeanServer;
  47 import javax.management.InstanceNotFoundException;
  48 import javax.management.remote.JMXConnectorFactory;
  49 import javax.management.remote.JMXConnectorServerFactory;
  50 import com.sun.jmx.mbeanserver.GetPropertyAction;
  51 import com.sun.jmx.remote.security.NotificationAccessController;
  52 import javax.management.remote.JMXConnector;
  53 import javax.management.remote.JMXConnectorServer;
  54 
  55 public class EnvHelp {
  56 
  57     /**
  58      * <p>Name of the attribute that specifies a default class loader
  59      * object.
  60      * The value associated with this attribute is a ClassLoader object</p>
  61      */
  62     private static final String DEFAULT_CLASS_LOADER =
  63         JMXConnectorFactory.DEFAULT_CLASS_LOADER;
  64 
  65     /**
  66      * <p>Name of the attribute that specifies a default class loader
  67      *    ObjectName.
  68      * The value associated with this attribute is an ObjectName object</p>
  69      */
  70     private static final String DEFAULT_CLASS_LOADER_NAME =
  71         JMXConnectorServerFactory.DEFAULT_CLASS_LOADER_NAME;
  72 
  73     /**
  74      * Get the Connector Server default class loader.
  75      * <p>
  76      * Returns:
  77      * <p>
  78      * <ul>
  79      * <li>
  80      *     The ClassLoader object found in <var>env</var> for
  81      *     <code>jmx.remote.default.class.loader</code>, if any.
  82      * </li>
  83      * <li>
  84      *     The ClassLoader pointed to by the ObjectName found in
  85      *     <var>env</var> for <code>jmx.remote.default.class.loader.name</code>,
  86      *     and registered in <var>mbs</var> if any.
  87      * </li>
  88      * <li>
  89      *     The current thread's context classloader otherwise.
  90      * </li>
  91      * </ul>
  92      *
  93      * @param env Environment attributes.
  94      * @param mbs The MBeanServer for which the connector server provides
  95      * remote access.
  96      *
  97      * @return the connector server's default class loader.
  98      *
  99      * @exception IllegalArgumentException if one of the following is true:
 100      * <ul>
 101      * <li>both
 102      *     <code>jmx.remote.default.class.loader</code> and
 103      *     <code>jmx.remote.default.class.loader.name</code> are specified,
 104      * </li>
 105      * <li>or
 106      *     <code>jmx.remote.default.class.loader</code> is not
 107      *     an instance of {@link ClassLoader},
 108      * </li>
 109      * <li>or
 110      *     <code>jmx.remote.default.class.loader.name</code> is not
 111      *     an instance of {@link ObjectName},
 112      * </li>
 113      * <li>or
 114      *     <code>jmx.remote.default.class.loader.name</code> is specified
 115      *     but <var>mbs</var> is null.
 116      * </li>

 117      * @exception InstanceNotFoundException if
 118      * <code>jmx.remote.default.class.loader.name</code> is specified
 119      * and the ClassLoader MBean is not found in <var>mbs</var>.
 120      */
 121     public static ClassLoader resolveServerClassLoader(Map<String, ?> env,
 122                                                        MBeanServer mbs)
 123         throws InstanceNotFoundException {
 124 
 125         if (env == null)
 126             return Thread.currentThread().getContextClassLoader();
 127 
 128         Object loader = env.get(DEFAULT_CLASS_LOADER);
 129         Object name   = env.get(DEFAULT_CLASS_LOADER_NAME);
 130 
 131         if (loader != null && name != null) {
 132             final String msg = "Only one of " +
 133                 DEFAULT_CLASS_LOADER + " or " +
 134                 DEFAULT_CLASS_LOADER_NAME +
 135                 " should be specified.";
 136             throw new IllegalArgumentException(msg);


 155         if (name instanceof ObjectName) {
 156             on = (ObjectName) name;
 157         } else {
 158             final String msg =
 159                 "ClassLoader name is not an instance of " +
 160                 ObjectName.class.getName() + " : " +
 161                 name.getClass().getName();
 162             throw new IllegalArgumentException(msg);
 163         }
 164 
 165         if (mbs == null)
 166             throw new IllegalArgumentException("Null MBeanServer object");
 167 
 168         return mbs.getClassLoader(on);
 169     }
 170 
 171     /**
 172      * Get the Connector Client default class loader.
 173      * <p>
 174      * Returns:
 175      * <p>
 176      * <ul>
 177      * <li>
 178      *     The ClassLoader object found in <var>env</var> for
 179      *     <code>jmx.remote.default.class.loader</code>, if any.
 180      * </li>
 181      * <li>The <tt>Thread.currentThread().getContextClassLoader()</tt>
 182      *     otherwise.
 183      * </li>
 184      * </ul>
 185      * <p>
 186      * Usually a Connector Client will call
 187      * <pre>
 188      * ClassLoader dcl = EnvHelp.resolveClientClassLoader(env);
 189      * </pre>
 190      * in its <code>connect(Map env)</code> method.
 191      *
 192      * @return The connector client default class loader.
 193      *
 194      * @exception IllegalArgumentException if
 195      * <code>jmx.remote.default.class.loader</code> is specified


 215             throw new IllegalArgumentException(msg);
 216         }
 217     }
 218 
 219     /**
 220      * Initialize the cause field of a {@code Throwable} object.
 221      *
 222      * @param throwable The {@code Throwable} on which the cause is set.
 223      * @param cause The cause to set on the supplied {@code Throwable}.
 224      * @return the {@code Throwable} with the cause field initialized.
 225      */
 226     public static <T extends Throwable> T initCause(T throwable,
 227                                                     Throwable cause) {
 228         throwable.initCause(cause);
 229         return throwable;
 230     }
 231 
 232     /**
 233      * Returns the cause field of a {@code Throwable} object.
 234      * The cause field can be got only if <var>t</var> has an
 235      * {@link Throwable#getCause()} method (JDK Version >= 1.4)
 236      * @param t {@code Throwable} on which the cause must be set.
 237      * @return the cause if getCause() succeeded and the got value is not
 238      * null, otherwise return the <var>t</var>.
 239      */
 240     public static Throwable getCause(Throwable t) {
 241         Throwable ret = t;
 242 
 243         try {
 244             java.lang.reflect.Method getCause =
 245                 t.getClass().getMethod("getCause", (Class<?>[]) null);
 246             ret = (Throwable)getCause.invoke(t, (Object[]) null);
 247 
 248         } catch (Exception e) {
 249             // OK.
 250             // it must be older than 1.4.
 251         }
 252         return (ret != null) ? ret: t;
 253     }
 254 
 255 
 256     /**
 257      * <p>Name of the attribute that specifies the size of a notification
 258      * buffer for a connector server. The default value is 1000.
 259      */
 260     public static final String BUFFER_SIZE_PROPERTY =
 261         "jmx.remote.x.notification.buffer.size";
 262 
 263 
 264     /**
 265      * Returns the size of a notification buffer for a connector server.
 266      * The default value is 1000.
 267      */
 268     public static int getNotifBufferSize(Map<String, ?> env) {
 269         int defaultQueueSize = 1000; // default value
 270 
 271         // keep it for the compability for the fix:
 272         // 6174229: Environment parameter should be notification.buffer.size
 273         // instead of buffer.size
 274         final String oldP = "jmx.remote.x.buffer.size";
 275 
 276         // the default value re-specified in the system
 277         try {


 299             if (env.containsKey(BUFFER_SIZE_PROPERTY)) {
 300                 queueSize = (int)EnvHelp.getIntegerAttribute(env,BUFFER_SIZE_PROPERTY,
 301                                             defaultQueueSize,0,
 302                                             Integer.MAX_VALUE);
 303             } else { // try the old one
 304                 queueSize = (int)EnvHelp.getIntegerAttribute(env,oldP,
 305                                             defaultQueueSize,0,
 306                                             Integer.MAX_VALUE);
 307             }
 308         } catch (RuntimeException e) {
 309             logger.warning("getNotifBufferSize",
 310                            "Can't determine queuesize (using default): "+
 311                            e);
 312             logger.debug("getNotifBufferSize", e);
 313         }
 314 
 315         return queueSize;
 316     }
 317 
 318     /**
 319      * <p>Name of the attribute that specifies the maximum number of
 320      * notifications that a client will fetch from its server.. The
 321      * value associated with this attribute should be an
 322      * <code>Integer</code> object.  The default value is 1000.</p>
 323      */
 324     public static final String MAX_FETCH_NOTIFS =
 325         "jmx.remote.x.notification.fetch.max";
 326 
 327     /**
 328      * Returns the maximum notification number which a client will
 329      * fetch every time.
 330      */
 331     public static int getMaxFetchNotifNumber(Map<String, ?> env) {
 332         return (int) getIntegerAttribute(env, MAX_FETCH_NOTIFS, 1000, 1,
 333                                          Integer.MAX_VALUE);
 334     }
 335 
 336     /**
 337      * <p>Name of the attribute that specifies the timeout for a
 338      * client to fetch notifications from its server. The value
 339      * associated with this attribute should be a <code>Long</code>
 340      * object.  The default value is 60000 milliseconds.</p>
 341      */
 342     public static final String FETCH_TIMEOUT =
 343         "jmx.remote.x.notification.fetch.timeout";
 344 
 345     /**
 346      * Returns the timeout for a client to fetch notifications.
 347      */
 348     public static long getFetchTimeout(Map<String, ?> env) {
 349         return getIntegerAttribute(env, FETCH_TIMEOUT, 60000L, 0,
 350                 Long.MAX_VALUE);
 351     }
 352 
 353     /**
 354      * <p>Name of the attribute that specifies an object that will check
 355      * accesses to add/removeNotificationListener and also attempts to
 356      * receive notifications.  The value associated with this attribute
 357      * should be a <code>NotificationAccessController</code> object.
 358      * The default value is null.</p>

 359      * This field is not public because of its com.sun dependency.
 360      */
 361     public static final String NOTIF_ACCESS_CONTROLLER =
 362             "com.sun.jmx.remote.notification.access.controller";
 363 
 364     public static NotificationAccessController getNotificationAccessController(
 365             Map<String, ?> env) {
 366         return (env == null) ? null :
 367             (NotificationAccessController) env.get(NOTIF_ACCESS_CONTROLLER);
 368     }
 369 
 370     /**
 371      * Get an integer-valued attribute with name <code>name</code>
 372      * from <code>env</code>.  If <code>env</code> is null, or does
 373      * not contain an entry for <code>name</code>, return
 374      * <code>defaultValue</code>.  The value may be a Number, or it
 375      * may be a String that is parsable as a long.  It must be at
 376      * least <code>minValue</code> and at most<code>maxValue</code>.
 377      *
 378      * @throws IllegalArgumentException if <code>env</code> contains


 613                 else
 614                     nextPrefix = sentinelKey;
 615             }
 616         }
 617     }
 618 
 619     private static void parseHiddenAttributes(String hide,
 620                                               SortedSet<String> hiddenStrings,
 621                                               SortedSet<String> hiddenPrefixes) {
 622         final StringTokenizer tok = new StringTokenizer(hide);
 623         while (tok.hasMoreTokens()) {
 624             String s = tok.nextToken();
 625             if (s.endsWith("*"))
 626                 hiddenPrefixes.add(s.substring(0, s.length() - 1));
 627             else
 628                 hiddenStrings.add(s);
 629         }
 630     }
 631 
 632     /**
 633      * <p>Name of the attribute that specifies the timeout to keep a
 634      * server side connection after answering last client request.
 635      * The default value is 120000 milliseconds.</p>
 636      */
 637     public static final String SERVER_CONNECTION_TIMEOUT =
 638         "jmx.remote.x.server.connection.timeout";
 639 
 640     /**
 641      * Returns the server side connection timeout.
 642      */
 643     public static long getServerConnectionTimeout(Map<String, ?> env) {
 644         return getIntegerAttribute(env, SERVER_CONNECTION_TIMEOUT, 120000L,
 645                                    0, Long.MAX_VALUE);
 646     }
 647 
 648     /**
 649      * <p>Name of the attribute that specifies the period in
 650      * millisecond for a client to check its connection.  The default
 651      * value is 60000 milliseconds.</p>
 652      */
 653     public static final String CLIENT_CONNECTION_CHECK_PERIOD =
 654         "jmx.remote.x.client.connection.check.period";
 655 
 656     /**
 657      * Returns the client connection check period.
 658      */
 659     public static long getConnectionCheckPeriod(Map<String, ?> env) {
 660         return getIntegerAttribute(env, CLIENT_CONNECTION_CHECK_PERIOD, 60000L,
 661                                    0, Long.MAX_VALUE);
 662     }
 663 
 664     /**
 665      * Computes a boolean value from a string value retrieved from a
 666      * property in the given map.
 667      *
 668      * @param stringBoolean the string value that must be converted
 669      * into a boolean value.
 670      *
 671      * @return


 724             return false;
 725         else
 726             throw new IllegalArgumentException(
 727                 "Property value must be \"true\" or \"false\" instead of \"" +
 728                 stringBoolean + "\"");
 729     }
 730 
 731     /**
 732      * Converts a map into a valid hash table, i.e.
 733      * it removes all the 'null' values from the map.
 734      */
 735     public static <K, V> Hashtable<K, V> mapToHashtable(Map<K, V> map) {
 736         HashMap<K, V> m = new HashMap<K, V>(map);
 737         if (m.containsKey(null)) m.remove(null);
 738         for (Iterator<?> i = m.values().iterator(); i.hasNext(); )
 739             if (i.next() == null) i.remove();
 740         return new Hashtable<K, V>(m);
 741     }
 742 
 743     /**
 744      * <p>Name of the attribute that specifies whether a connector server
 745      * should not prevent the VM from exiting
 746      */
 747     public static final String JMX_SERVER_DAEMON = "jmx.remote.x.daemon";
 748 
 749     /**
 750      * Returns true if {@value SERVER_DAEMON} is specified in the {@code env}
 751      * as a key and its value is a String and it is equal to true ignoring case.
 752      *
 753      * @param env
 754      * @return
 755      */
 756     public static boolean isServerDaemon(Map<String, ?> env) {
 757         return (env != null) &&
 758                 ("true".equalsIgnoreCase((String)env.get(JMX_SERVER_DAEMON)));
 759     }
 760 
 761     private static final class SinkOutputStream extends OutputStream {
 762         public void write(byte[] b, int off, int len) {}
 763         public void write(int b) {}
 764     }
 765 
 766     private static final ClassLogger logger =
 767         new ClassLogger("javax.management.remote.misc", "EnvHelp");
 768 }


  38 import java.util.SortedSet;
  39 import java.util.StringTokenizer;
  40 import java.util.TreeMap;
  41 import java.util.TreeSet;
  42 
  43 import java.security.AccessController;
  44 
  45 import javax.management.ObjectName;
  46 import javax.management.MBeanServer;
  47 import javax.management.InstanceNotFoundException;
  48 import javax.management.remote.JMXConnectorFactory;
  49 import javax.management.remote.JMXConnectorServerFactory;
  50 import com.sun.jmx.mbeanserver.GetPropertyAction;
  51 import com.sun.jmx.remote.security.NotificationAccessController;
  52 import javax.management.remote.JMXConnector;
  53 import javax.management.remote.JMXConnectorServer;
  54 
  55 public class EnvHelp {
  56 
  57     /**
  58      * Name of the attribute that specifies a default class loader
  59      * object.
  60      * The value associated with this attribute is a ClassLoader object.
  61      */
  62     private static final String DEFAULT_CLASS_LOADER =
  63         JMXConnectorFactory.DEFAULT_CLASS_LOADER;
  64 
  65     /**
  66      * Name of the attribute that specifies a default class loader
  67      * ObjectName.
  68      * The value associated with this attribute is an ObjectName object.
  69      */
  70     private static final String DEFAULT_CLASS_LOADER_NAME =
  71         JMXConnectorServerFactory.DEFAULT_CLASS_LOADER_NAME;
  72 
  73     /**
  74      * Get the Connector Server default class loader.
  75      * <p>
  76      * Returns:

  77      * <ul>
  78      * <li>
  79      *     The ClassLoader object found in <var>env</var> for
  80      *     <code>jmx.remote.default.class.loader</code>, if any.
  81      * </li>
  82      * <li>
  83      *     The ClassLoader pointed to by the ObjectName found in
  84      *     <var>env</var> for <code>jmx.remote.default.class.loader.name</code>,
  85      *     and registered in <var>mbs</var> if any.
  86      * </li>
  87      * <li>
  88      *     The current thread's context classloader otherwise.
  89      * </li>
  90      * </ul>
  91      *
  92      * @param env Environment attributes.
  93      * @param mbs The MBeanServer for which the connector server provides
  94      * remote access.
  95      *
  96      * @return the connector server's default class loader.
  97      *
  98      * @exception IllegalArgumentException if one of the following is true:
  99      * <ul>
 100      * <li>both
 101      *     <code>jmx.remote.default.class.loader</code> and
 102      *     <code>jmx.remote.default.class.loader.name</code> are specified,
 103      * </li>
 104      * <li>or
 105      *     <code>jmx.remote.default.class.loader</code> is not
 106      *     an instance of {@link ClassLoader},
 107      * </li>
 108      * <li>or
 109      *     <code>jmx.remote.default.class.loader.name</code> is not
 110      *     an instance of {@link ObjectName},
 111      * </li>
 112      * <li>or
 113      *     <code>jmx.remote.default.class.loader.name</code> is specified
 114      *     but <var>mbs</var> is null.
 115      * </li>
 116      * </ul>
 117      * @exception InstanceNotFoundException if
 118      * <code>jmx.remote.default.class.loader.name</code> is specified
 119      * and the ClassLoader MBean is not found in <var>mbs</var>.
 120      */
 121     public static ClassLoader resolveServerClassLoader(Map<String, ?> env,
 122                                                        MBeanServer mbs)
 123         throws InstanceNotFoundException {
 124 
 125         if (env == null)
 126             return Thread.currentThread().getContextClassLoader();
 127 
 128         Object loader = env.get(DEFAULT_CLASS_LOADER);
 129         Object name   = env.get(DEFAULT_CLASS_LOADER_NAME);
 130 
 131         if (loader != null && name != null) {
 132             final String msg = "Only one of " +
 133                 DEFAULT_CLASS_LOADER + " or " +
 134                 DEFAULT_CLASS_LOADER_NAME +
 135                 " should be specified.";
 136             throw new IllegalArgumentException(msg);


 155         if (name instanceof ObjectName) {
 156             on = (ObjectName) name;
 157         } else {
 158             final String msg =
 159                 "ClassLoader name is not an instance of " +
 160                 ObjectName.class.getName() + " : " +
 161                 name.getClass().getName();
 162             throw new IllegalArgumentException(msg);
 163         }
 164 
 165         if (mbs == null)
 166             throw new IllegalArgumentException("Null MBeanServer object");
 167 
 168         return mbs.getClassLoader(on);
 169     }
 170 
 171     /**
 172      * Get the Connector Client default class loader.
 173      * <p>
 174      * Returns:

 175      * <ul>
 176      * <li>
 177      *     The ClassLoader object found in <var>env</var> for
 178      *     <code>jmx.remote.default.class.loader</code>, if any.
 179      * </li>
 180      * <li>The <tt>Thread.currentThread().getContextClassLoader()</tt>
 181      *     otherwise.
 182      * </li>
 183      * </ul>
 184      * <p>
 185      * Usually a Connector Client will call
 186      * <pre>
 187      * ClassLoader dcl = EnvHelp.resolveClientClassLoader(env);
 188      * </pre>
 189      * in its <code>connect(Map env)</code> method.
 190      *
 191      * @return The connector client default class loader.
 192      *
 193      * @exception IllegalArgumentException if
 194      * <code>jmx.remote.default.class.loader</code> is specified


 214             throw new IllegalArgumentException(msg);
 215         }
 216     }
 217 
 218     /**
 219      * Initialize the cause field of a {@code Throwable} object.
 220      *
 221      * @param throwable The {@code Throwable} on which the cause is set.
 222      * @param cause The cause to set on the supplied {@code Throwable}.
 223      * @return the {@code Throwable} with the cause field initialized.
 224      */
 225     public static <T extends Throwable> T initCause(T throwable,
 226                                                     Throwable cause) {
 227         throwable.initCause(cause);
 228         return throwable;
 229     }
 230 
 231     /**
 232      * Returns the cause field of a {@code Throwable} object.
 233      * The cause field can be got only if <var>t</var> has an
 234      * {@link Throwable#getCause()} method (JDK Version {@literal >=} 1.4)
 235      * @param t {@code Throwable} on which the cause must be set.
 236      * @return the cause if getCause() succeeded and the got value is not
 237      * null, otherwise return the <var>t</var>.
 238      */
 239     public static Throwable getCause(Throwable t) {
 240         Throwable ret = t;
 241 
 242         try {
 243             java.lang.reflect.Method getCause =
 244                 t.getClass().getMethod("getCause", (Class<?>[]) null);
 245             ret = (Throwable)getCause.invoke(t, (Object[]) null);
 246 
 247         } catch (Exception e) {
 248             // OK.
 249             // it must be older than 1.4.
 250         }
 251         return (ret != null) ? ret: t;
 252     }
 253 
 254 
 255     /**
 256      * Name of the attribute that specifies the size of a notification
 257      * buffer for a connector server. The default value is 1000.
 258      */
 259     public static final String BUFFER_SIZE_PROPERTY =
 260         "jmx.remote.x.notification.buffer.size";
 261 
 262 
 263     /**
 264      * Returns the size of a notification buffer for a connector server.
 265      * The default value is 1000.
 266      */
 267     public static int getNotifBufferSize(Map<String, ?> env) {
 268         int defaultQueueSize = 1000; // default value
 269 
 270         // keep it for the compability for the fix:
 271         // 6174229: Environment parameter should be notification.buffer.size
 272         // instead of buffer.size
 273         final String oldP = "jmx.remote.x.buffer.size";
 274 
 275         // the default value re-specified in the system
 276         try {


 298             if (env.containsKey(BUFFER_SIZE_PROPERTY)) {
 299                 queueSize = (int)EnvHelp.getIntegerAttribute(env,BUFFER_SIZE_PROPERTY,
 300                                             defaultQueueSize,0,
 301                                             Integer.MAX_VALUE);
 302             } else { // try the old one
 303                 queueSize = (int)EnvHelp.getIntegerAttribute(env,oldP,
 304                                             defaultQueueSize,0,
 305                                             Integer.MAX_VALUE);
 306             }
 307         } catch (RuntimeException e) {
 308             logger.warning("getNotifBufferSize",
 309                            "Can't determine queuesize (using default): "+
 310                            e);
 311             logger.debug("getNotifBufferSize", e);
 312         }
 313 
 314         return queueSize;
 315     }
 316 
 317     /**
 318      * Name of the attribute that specifies the maximum number of
 319      * notifications that a client will fetch from its server. The
 320      * value associated with this attribute should be an
 321      * {@code Integer} object.  The default value is 1000.
 322      */
 323     public static final String MAX_FETCH_NOTIFS =
 324         "jmx.remote.x.notification.fetch.max";
 325 
 326     /**
 327      * Returns the maximum notification number which a client will
 328      * fetch every time.
 329      */
 330     public static int getMaxFetchNotifNumber(Map<String, ?> env) {
 331         return (int) getIntegerAttribute(env, MAX_FETCH_NOTIFS, 1000, 1,
 332                                          Integer.MAX_VALUE);
 333     }
 334 
 335     /**
 336      * Name of the attribute that specifies the timeout for a
 337      * client to fetch notifications from its server. The value
 338      * associated with this attribute should be a <code>Long</code>
 339      * object.  The default value is 60000 milliseconds.
 340      */
 341     public static final String FETCH_TIMEOUT =
 342         "jmx.remote.x.notification.fetch.timeout";
 343 
 344     /**
 345      * Returns the timeout for a client to fetch notifications.
 346      */
 347     public static long getFetchTimeout(Map<String, ?> env) {
 348         return getIntegerAttribute(env, FETCH_TIMEOUT, 60000L, 0,
 349                 Long.MAX_VALUE);
 350     }
 351 
 352     /**
 353      * Name of the attribute that specifies an object that will check
 354      * accesses to add/removeNotificationListener and also attempts to
 355      * receive notifications.  The value associated with this attribute
 356      * should be a <code>NotificationAccessController</code> object.
 357      * The default value is null.
 358      * <p>
 359      * This field is not public because of its com.sun dependency.
 360      */
 361     public static final String NOTIF_ACCESS_CONTROLLER =
 362             "com.sun.jmx.remote.notification.access.controller";
 363 
 364     public static NotificationAccessController getNotificationAccessController(
 365             Map<String, ?> env) {
 366         return (env == null) ? null :
 367             (NotificationAccessController) env.get(NOTIF_ACCESS_CONTROLLER);
 368     }
 369 
 370     /**
 371      * Get an integer-valued attribute with name <code>name</code>
 372      * from <code>env</code>.  If <code>env</code> is null, or does
 373      * not contain an entry for <code>name</code>, return
 374      * <code>defaultValue</code>.  The value may be a Number, or it
 375      * may be a String that is parsable as a long.  It must be at
 376      * least <code>minValue</code> and at most<code>maxValue</code>.
 377      *
 378      * @throws IllegalArgumentException if <code>env</code> contains


 613                 else
 614                     nextPrefix = sentinelKey;
 615             }
 616         }
 617     }
 618 
 619     private static void parseHiddenAttributes(String hide,
 620                                               SortedSet<String> hiddenStrings,
 621                                               SortedSet<String> hiddenPrefixes) {
 622         final StringTokenizer tok = new StringTokenizer(hide);
 623         while (tok.hasMoreTokens()) {
 624             String s = tok.nextToken();
 625             if (s.endsWith("*"))
 626                 hiddenPrefixes.add(s.substring(0, s.length() - 1));
 627             else
 628                 hiddenStrings.add(s);
 629         }
 630     }
 631 
 632     /**
 633      * Name of the attribute that specifies the timeout to keep a
 634      * server side connection after answering last client request.
 635      * The default value is 120000 milliseconds.
 636      */
 637     public static final String SERVER_CONNECTION_TIMEOUT =
 638         "jmx.remote.x.server.connection.timeout";
 639 
 640     /**
 641      * Returns the server side connection timeout.
 642      */
 643     public static long getServerConnectionTimeout(Map<String, ?> env) {
 644         return getIntegerAttribute(env, SERVER_CONNECTION_TIMEOUT, 120000L,
 645                                    0, Long.MAX_VALUE);
 646     }
 647 
 648     /**
 649      * Name of the attribute that specifies the period in
 650      * millisecond for a client to check its connection. The default
 651      * value is 60000 milliseconds.
 652      */
 653     public static final String CLIENT_CONNECTION_CHECK_PERIOD =
 654         "jmx.remote.x.client.connection.check.period";
 655 
 656     /**
 657      * Returns the client connection check period.
 658      */
 659     public static long getConnectionCheckPeriod(Map<String, ?> env) {
 660         return getIntegerAttribute(env, CLIENT_CONNECTION_CHECK_PERIOD, 60000L,
 661                                    0, Long.MAX_VALUE);
 662     }
 663 
 664     /**
 665      * Computes a boolean value from a string value retrieved from a
 666      * property in the given map.
 667      *
 668      * @param stringBoolean the string value that must be converted
 669      * into a boolean value.
 670      *
 671      * @return


 724             return false;
 725         else
 726             throw new IllegalArgumentException(
 727                 "Property value must be \"true\" or \"false\" instead of \"" +
 728                 stringBoolean + "\"");
 729     }
 730 
 731     /**
 732      * Converts a map into a valid hash table, i.e.
 733      * it removes all the 'null' values from the map.
 734      */
 735     public static <K, V> Hashtable<K, V> mapToHashtable(Map<K, V> map) {
 736         HashMap<K, V> m = new HashMap<K, V>(map);
 737         if (m.containsKey(null)) m.remove(null);
 738         for (Iterator<?> i = m.values().iterator(); i.hasNext(); )
 739             if (i.next() == null) i.remove();
 740         return new Hashtable<K, V>(m);
 741     }
 742 
 743     /**
 744      * Name of the attribute that specifies whether a connector server
 745      * should not prevent the VM from exiting
 746      */
 747     public static final String JMX_SERVER_DAEMON = "jmx.remote.x.daemon";
 748 
 749     /**
 750      * Returns true if {@value JMX_SERVER_DAEMON} is specified in the {@code env}
 751      * as a key and its value is a String and it is equal to true ignoring case.
 752      *
 753      * @param env
 754      * @return
 755      */
 756     public static boolean isServerDaemon(Map<String, ?> env) {
 757         return (env != null) &&
 758                 ("true".equalsIgnoreCase((String)env.get(JMX_SERVER_DAEMON)));
 759     }
 760 
 761     private static final class SinkOutputStream extends OutputStream {
 762         public void write(byte[] b, int off, int len) {}
 763         public void write(int b) {}
 764     }
 765 
 766     private static final ClassLogger logger =
 767         new ClassLogger("javax.management.remote.misc", "EnvHelp");
 768 }
< prev index next >