FileDocCategorySizeDatePackage
EnvHelp.javaAPI DocJava SE 5 API19864Fri Aug 26 14:55:00 BST 2005com.sun.jmx.remote.util

EnvHelp

public class EnvHelp extends Object

Fields Summary
private static final String
DEFAULT_CLASS_LOADER

Name of the attribute that specifies a default class loader object. The value associated with this attribute is a ClassLoader object

private static final String
DEFAULT_CLASS_LOADER_NAME

Name of the attribute that specifies a default class loader ObjectName. The value associated with this attribute is an ObjectName object

public static final String
MAX_FETCH_NOTIFS

Name of the attribute that specifies the maximum number of notifications that a client will fetch from its server.. The value associated with this attribute should be an Integer object. The default value is 1000.

public static final String
FETCH_TIMEOUT

Name of the attribute that specifies the timeout for a client to fetch notifications from its server. The value associated with this attribute should be a Long object. The default value is 60000 milleseconds.

public static final String
DEFAULT_ORB
public static final String
HIDDEN_ATTRIBUTES
The value of this attribute, if present, is a string specifying what other attributes should not appear in JMXConnectorServer.getAttributes(). It is a space-separated list of attribute patterns, where each pattern is either an attribute name, or an attribute prefix followed by a "*" character. The "*" has no special significance anywhere except at the end of a pattern. By default, this list is added to the list defined by {@link #DEFAULT_HIDDEN_ATTRIBUTES} (which uses the same format). If the value of this attribute begins with an "=", then the remainder of the string defines the complete list of attribute patterns.
public static final String
DEFAULT_HIDDEN_ATTRIBUTES
Default list of attributes not to show.
private static final SortedSet
defaultHiddenStrings
private static final SortedSet
defaultHiddenPrefixes
public static final String
SERVER_CONNECTION_TIMEOUT

Name of the attribute that specifies the timeout to keep a server side connection after answering last client request. The default value is 120000 milliseconds.

public static final String
CLIENT_CONNECTION_CHECK_PERIOD

Name of the attribute that specifies the period in millisecond for a client to check its connection. The default value is 60000 milliseconds.

private static final ClassLogger
logger
Constructors Summary
Methods Summary
public static voidcheckAttributes(java.util.Map attributes)


    /* Check that all attributes have a key that is a String.
       Could make further checks, e.g. appropriate types for attributes.  */
         
        for (Iterator it = attributes.keySet().iterator(); it.hasNext(); ) {
            Object key = it.next();
            if (!(key instanceof String)) {
                final String msg =
                    "Attributes contain key that is not a string: " + key;
                throw new IllegalArgumentException(msg);
            }
        }
    
public static java.util.MapfilterAttributes(java.util.Map attributes)

        if (logger.traceOn()) {
            logger.trace("filterAttributes", "starts");
        }

        SortedMap map = new TreeMap(attributes);
	purgeUnserializable(map.values());
	hideAttributes(map);
        return map;
    
public static java.lang.ThrowablegetCause(java.lang.Throwable t)
Returns the cause field of a Throwable object. The cause field can be got only if t has an {@link Throwable#getCause()} method (JDK Version >= 1.4)

param
t Throwable on which the cause must be set.
return
the cause if getCause() succeeded and the got value is not null, otherwise return the t.

        Throwable ret = t;

        try {
            java.lang.reflect.Method getCause =
		t.getClass().getMethod("getCause", (Class[]) null);
            ret = (Throwable)getCause.invoke(t, (Object[]) null);

        } catch (Exception e) {
	    // OK.
            // it must be older than 1.4.
        }
        return (ret != null) ? ret: t;
    
public static longgetConnectionCheckPeriod(java.util.Map env)
Returns the client connection check oeriod.


                
         
	return getIntegerAttribute(env, CLIENT_CONNECTION_CHECK_PERIOD, 60000L,
				   0, Long.MAX_VALUE);
    
public static longgetFetchTimeout(java.util.Map env)
Returns the timeout for a client to fetch notifications.


                   
         
	return getIntegerAttribute(env, FETCH_TIMEOUT, 60000L, 0,
				   Long.MAX_VALUE);
    
public static longgetIntegerAttribute(java.util.Map env, java.lang.String name, long defaultValue, long minValue, long maxValue)
Get an integer-valued attribute with name name from env. If env is null, or does not contain an entry for name, return defaultValue. The value may be a Number, or it may be a String that is parsable as a long. It must be at least minValue and at mostmaxValue.

throws
IllegalArgumentException if env contains an entry for name but it does not meet the constraints above.

	final Object o;

	if (env == null || (o = env.get(name)) == null)
	    return defaultValue;

	final long result;

	if (o instanceof Number)
	    result = ((Number) o).longValue();
	else if (o instanceof String) {
	    result = Long.parseLong((String) o);
	    /* May throw a NumberFormatException, which is an
	       IllegalArgumentException.  */
	} else {
	    final String msg =
		"Attribute " + name + " value must be Integer or String: " + o;
	    throw new IllegalArgumentException(msg);
	}

	if (result < minValue) {
	    final String msg =
		"Attribute " + name + " value must be at least " + minValue +
		": " + result;
	    throw new IllegalArgumentException(msg);
	}

	if (result > maxValue) {
	    final String msg =
		"Attribute " + name + " value must be at most " + maxValue +
		": " + result;
	    throw new IllegalArgumentException(msg);
	}

        return result;
    
public static intgetMaxFetchNotifNumber(java.util.Map env)
Returns the maximum notification number which a client will fetch every time.


                      
         
	return (int) getIntegerAttribute(env, MAX_FETCH_NOTIFS, 1000, 1,
					 Integer.MAX_VALUE);
    
public static longgetServerConnectionTimeout(java.util.Map env)
Returns the server side connection timeout.


                
         
	return getIntegerAttribute(env, SERVER_CONNECTION_TIMEOUT, 120000L,
				   0, Long.MAX_VALUE);
    
private static voidhideAttributes(java.util.SortedMap map)


         
	if (map.isEmpty())
	    return;

	final SortedSet hiddenStrings;
	final SortedSet hiddenPrefixes;

	String hide = (String) map.get(HIDDEN_ATTRIBUTES);
	if (hide != null) {
	    if (hide.startsWith("="))
		hide = hide.substring(1);
	    else
		hide += " " + DEFAULT_HIDDEN_ATTRIBUTES;
	    hiddenStrings = new TreeSet();
	    hiddenPrefixes = new TreeSet();
	    parseHiddenAttributes(hide, hiddenStrings, hiddenPrefixes);
	} else {
	    hide = DEFAULT_HIDDEN_ATTRIBUTES;
	    synchronized (defaultHiddenStrings) {
		if (defaultHiddenStrings.isEmpty()) {
		    parseHiddenAttributes(hide,
					  defaultHiddenStrings,
					  defaultHiddenPrefixes);
		}
		hiddenStrings = defaultHiddenStrings;
		hiddenPrefixes = defaultHiddenPrefixes;
	    }
	}

	/* Construct a string that is greater than any key in the map.
	   Setting a string-to-match or a prefix-to-match to this string
	   guarantees that we will never call next() on the corresponding
	   iterator.  */
	String sentinelKey = map.lastKey() + "X";
	Iterator keyIterator = map.keySet().iterator();
	Iterator stringIterator = hiddenStrings.iterator();
	Iterator prefixIterator = hiddenPrefixes.iterator();

	String nextString;
	if (stringIterator.hasNext())
	    nextString = (String) stringIterator.next();
	else
	    nextString = sentinelKey;
	String nextPrefix;
	if (prefixIterator.hasNext())
	    nextPrefix = (String) prefixIterator.next();
	else
	    nextPrefix = sentinelKey;

	/* Read each key in sorted order and, if it matches a string
	   or prefix, remove it. */
    keys:
	while (keyIterator.hasNext()) {
	    String key = (String) keyIterator.next();

	    /* Continue through string-match values until we find one
	       that is either greater than the current key, or equal
	       to it.  In the latter case, remove the key.  */
	    int cmp = +1;
	    while ((cmp = nextString.compareTo(key)) < 0) {
		if (stringIterator.hasNext())
		    nextString = (String) stringIterator.next();
		else
		    nextString = sentinelKey;
	    }
	    if (cmp == 0) {
		keyIterator.remove();
		continue keys;
	    }

	    /* Continue through the prefix values until we find one
	       that is either greater than the current key, or a
	       prefix of it.  In the latter case, remove the key.  */
	    while (nextPrefix.compareTo(key) <= 0) {
		if (key.startsWith(nextPrefix)) {
		    keyIterator.remove();
		    continue keys;
		}
		if (prefixIterator.hasNext())
		    nextPrefix = (String) prefixIterator.next();
		else
		    nextPrefix = sentinelKey;
	    }
	}
    
public static java.lang.ThrowableinitCause(java.lang.Throwable t, java.lang.Throwable cause)
Init the cause field of a Throwable object. The cause field is set only if t has an {@link Throwable#initCause(Throwable)} method (JDK Version >= 1.4)

param
t Throwable on which the cause must be set.
param
cause The cause to set on t.
return
t with or without the cause field set.


        /* Make a best effort to set the cause, but if we don't
           succeed, too bad, you don't get that useful debugging
           information.  We jump through hoops here so that we can
           work on platforms prior to J2SE 1.4 where the
           Throwable.initCause method was introduced.  If we change
           the public interface of JMRuntimeException in a future
           version we can add getCause() so we don't need to do this.  */
        try {
            java.lang.reflect.Method initCause =
                t.getClass().getMethod("initCause",
                                       new Class[] {Throwable.class});
            initCause.invoke(t, new Object[] {cause});
        } catch (Exception e) {
	    // OK.
            // too bad, no debugging info
        }
        return t;
    
public static java.util.HashtablemapToHashtable(java.util.Map map)
Converts a map into a valid hash table, i.e. it removes all the 'null' values from the map.

        HashMap m = new HashMap(map);
        if (m.containsKey(null)) m.remove(null);
        for (Iterator i = m.values().iterator(); i.hasNext(); )
            if (i.next() == null) i.remove();
        return new Hashtable(m);
    
private static voidparseHiddenAttributes(java.lang.String hide, java.util.SortedSet hiddenStrings, java.util.SortedSet hiddenPrefixes)

	final StringTokenizer tok = new StringTokenizer(hide);
	while (tok.hasMoreTokens()) {
	    String s = tok.nextToken();
	    if (s.endsWith("*"))
		hiddenPrefixes.add(s.substring(0, s.length() - 1));
	    else
		hiddenStrings.add(s);
	}
    
private static voidpurgeUnserializable(java.util.Collection objects)
Remove from the given Collection any element that is not a serializable object.

	logger.trace("purgeUnserializable", "starts");
	ObjectOutputStream oos = null;
	int i = 0;
	for (Iterator it = objects.iterator(); it.hasNext(); i++) {
	    Object v = it.next();

	    if (v == null || v instanceof String) {
		if (logger.traceOn()) {
		    logger.trace("purgeUnserializable",
				 "Value trivially serializable: " + v);
		}
		continue;
	    }

	    try {
		if (oos == null)
		    oos = new ObjectOutputStream(new SinkOutputStream());
		oos.writeObject(v);
		if (logger.traceOn()) {
		    logger.trace("purgeUnserializable",
				 "Value serializable: " + v);
		}
	    } catch (IOException e) {
		if (logger.traceOn()) {
		    logger.trace("purgeUnserializable",
				 "Value not serializable: " + v + ": " +
				 e);
		}
		it.remove();
		oos = null; // ObjectOutputStream invalid after exception
	    }
	}
    
public static java.lang.ClassLoaderresolveClientClassLoader(java.util.Map env)
Get the Connector Client default class loader.

Returns:

  • The ClassLoader object found in env for jmx.remote.default.class.loader, if any.
  • The Thread.currentThread().getContextClassLoader() otherwise.

Usually a Connector Client will call

ClassLoader dcl = EnvHelp.resolveClientClassLoader(env);
in its connect(Map env) method.

return
The connector client default class loader.
exception
IllegalArgumentException if jmx.remote.default.class.loader is specified and is not an instance of {@link ClassLoader}.


        if (env == null)
            return Thread.currentThread().getContextClassLoader();

        Object loader = env.get(DEFAULT_CLASS_LOADER);

        if (loader == null)
            return Thread.currentThread().getContextClassLoader();

        if (loader instanceof ClassLoader) {
            return (ClassLoader) loader;
        } else {
            final String msg =
                "ClassLoader object is not an instance of " +
                ClassLoader.class.getName() + " : " +
                loader.getClass().getName();
            throw new IllegalArgumentException(msg);
        }
    
public static java.lang.ClassLoaderresolveServerClassLoader(java.util.Map env, javax.management.MBeanServer mbs)
Get the Connector Server default class loader.

Returns:

  • The ClassLoader object found in env for jmx.remote.default.class.loader, if any.
  • The ClassLoader pointed to by the ObjectName found in env for jmx.remote.default.class.loader.name, and registered in mbs if any.
  • The current thread's context classloader otherwise.

param
env Environment attributes.
param
mbs The MBeanServer for which the connector server provides remote access.
return
the connector server's default class loader.
exception
IllegalArgumentException if one of the following is true:
  • both jmx.remote.default.class.loader and jmx.remote.default.class.loader.name are specified,
  • or jmx.remote.default.class.loader is not an instance of {@link ClassLoader},
  • or jmx.remote.default.class.loader.name is not an instance of {@link ObjectName},
  • or jmx.remote.default.class.loader.name is specified but mbs is null.
exception
InstanceNotFoundException if jmx.remote.default.class.loader.name is specified and the ClassLoader MBean is not found in mbs.


                                                                                                                                                                                                         
        
                                                        
          

        if (env == null)
            return Thread.currentThread().getContextClassLoader();

        Object loader = env.get(DEFAULT_CLASS_LOADER);
        Object name   = env.get(DEFAULT_CLASS_LOADER_NAME);

        if (loader != null && name != null) {
            final String msg = "Only one of " +
                DEFAULT_CLASS_LOADER + " or " +
                DEFAULT_CLASS_LOADER_NAME +
                " should be specified.";
            throw new IllegalArgumentException(msg);
        }

        if (loader == null && name == null)
            return Thread.currentThread().getContextClassLoader();

        if (loader != null) {
            if (loader instanceof ClassLoader) {
                return (ClassLoader) loader;
            } else {
                final String msg =
                    "ClassLoader object is not an instance of " +
                    ClassLoader.class.getName() + " : " +
                    loader.getClass().getName();
                throw new IllegalArgumentException(msg);
            }
        }

        ObjectName on;
        if (name instanceof ObjectName) {
            on = (ObjectName) name;
        } else {
            final String msg = 
                "ClassLoader name is not an instance of " +
                ObjectName.class.getName() + " : " +
                name.getClass().getName();
            throw new IllegalArgumentException(msg);
        }

        if (mbs == null)
            throw new IllegalArgumentException("Null MBeanServer object");

        return mbs.getClassLoader(on);