2111 lines · 81.6 KB · Java
RawDownload
/* * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.  Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package javax.management; import com.sun.jmx.mbeanserver.GetPropertyAction;import com.sun.jmx.mbeanserver.Util;import java.io.IOException;import java.io.InvalidObjectException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.ObjectStreamField;import java.security.AccessController;import java.util.Arrays;import java.util.Collections;import java.util.HashMap;import java.util.Hashtable;import java.util.Map; /** * <p>Represents the object name of an MBean, or a pattern that can * match the names of several MBeans.  Instances of this class are * immutable.</p> * * <p>An instance of this class can be used to represent:</p> * <ul> * <li>An object name</li> * <li>An object name pattern, within the context of a query</li> * </ul> * * <p>An object name consists of two parts, the domain and the key * properties.</p> * * <p>The <em>domain</em> is a string of characters not including * the character colon (<code>:</code>).  It is recommended that the domain * should not contain the string "{@code //}", which is reserved for future use. * * <p>If the domain includes at least one occurrence of the wildcard * characters asterisk (<code>*</code>) or question mark * (<code>?</code>), then the object name is a pattern.  The asterisk * matches any sequence of zero or more characters, while the question * mark matches any single character.</p> * * <p>If the domain is empty, it will be replaced in certain contexts * by the <em>default domain</em> of the MBean server in which the * ObjectName is used.</p> * * <p>The <em>key properties</em> are an unordered set of keys and * associated values.</p> * * <p>Each <em>key</em> is a nonempty string of characters which may * not contain any of the characters comma (<code>,</code>), equals * (<code>=</code>), colon, asterisk, or question mark.  The same key * may not occur twice in a given ObjectName.</p> * * <p>Each <em>value</em> associated with a key is a string of * characters that is either unquoted or quoted.</p> * * <p>An <em>unquoted value</em> is a possibly empty string of * characters which may not contain any of the characters comma, * equals, colon, or quote.</p> * * <p>If the <em>unquoted value</em> contains at least one occurrence * of the wildcard characters asterisk or question mark, then the object * name is a <em>property value pattern</em>. The asterisk matches any * sequence of zero or more characters, while the question mark matches * any single character.</p> * * <p>A <em>quoted value</em> consists of a quote (<code>"</code>), * followed by a possibly empty string of characters, followed by * another quote.  Within the string of characters, the backslash * (<code>\</code>) has a special meaning.  It must be followed by * one of the following characters:</p> * * <ul> * <li>Another backslash.  The second backslash has no special * meaning and the two characters represent a single backslash.</li> * * <li>The character 'n'.  The two characters represent a newline * ('\n' in Java).</li> * * <li>A quote.  The two characters represent a quote, and that quote * is not considered to terminate the quoted value. An ending closing * quote must be present for the quoted value to be valid.</li> * * <li>A question mark (?) or asterisk (*).  The two characters represent * a question mark or asterisk respectively.</li> * </ul> * * <p>A quote may not appear inside a quoted value except immediately * after an odd number of consecutive backslashes.</p> * * <p>The quotes surrounding a quoted value, and any backslashes * within that value, are considered to be part of the value.</p> * * <p>If the <em>quoted value</em> contains at least one occurrence of * the characters asterisk or question mark and they are not preceded * by a backslash, then they are considered as wildcard characters and * the object name is a <em>property value pattern</em>. The asterisk * matches any sequence of zero or more characters, while the question * mark matches any single character.</p> * * <p>An ObjectName may be a <em>property list pattern</em>. In this * case it may have zero or more keys and associated values. It matches * a nonpattern ObjectName whose domain matches and that contains the * same keys and associated values, as well as possibly other keys and * values.</p> * * <p>An ObjectName is a <em>property value pattern</em> when at least * one of its <em>quoted</em> or <em>unquoted</em> key property values * contains the wildcard characters asterisk or question mark as described * above. In this case it has one or more keys and associated values, with * at least one of the values containing wildcard characters. It matches a * nonpattern ObjectName whose domain matches and that contains the same * keys whose values match; if the property value pattern is also a * property list pattern then the nonpattern ObjectName can contain * other keys and values.</p> * * <p>An ObjectName is a <em>property pattern</em> if it is either a * <em>property list pattern</em> or a <em>property value pattern</em> * or both.</p> * * <p>An ObjectName is a pattern if its domain contains a wildcard or * if the ObjectName is a property pattern.</p> * * <p>If an ObjectName is not a pattern, it must contain at least one * key with its associated value.</p> * * <p>Examples of ObjectName patterns are:</p> * * <ul> * <li>{@code *:type=Foo,name=Bar} to match names in any domain whose *     exact set of keys is {@code type=Foo,name=Bar}.</li> * <li>{@code d:type=Foo,name=Bar,*} to match names in the domain *     {@code d} that have the keys {@code type=Foo,name=Bar} plus *     zero or more other keys.</li> * <li>{@code *:type=Foo,name=Bar,*} to match names in any domain *     that has the keys {@code type=Foo,name=Bar} plus zero or *     more other keys.</li> * <li>{@code d:type=F?o,name=Bar} will match e.g. *     {@code d:type=Foo,name=Bar} and {@code d:type=Fro,name=Bar}.</li> * <li>{@code d:type=F*o,name=Bar} will match e.g. *     {@code d:type=Fo,name=Bar} and {@code d:type=Frodo,name=Bar}.</li> * <li>{@code d:type=Foo,name="B*"} will match e.g. *     {@code d:type=Foo,name="Bling"}. Wildcards are recognized even *     inside quotes, and like other special characters can be escaped *     with {@code \}.</li> * </ul> * * <p>An ObjectName can be written as a String with the following * elements in order:</p> * * <ul> * <li>The domain. * <li>A colon (<code>:</code>). * <li>A key property list as defined below. * </ul> * * <p>A key property list written as a String is a comma-separated * list of elements.  Each element is either an asterisk or a key * property.  A key property consists of a key, an equals * (<code>=</code>), and the associated value.</p> * * <p>At most one element of a key property list may be an asterisk. * If the key property list contains an asterisk element, the * ObjectName is a property list pattern.</p> * * <p>Spaces have no special significance in a String representing an * ObjectName.  For example, the String: * <pre> * domain: key1 = value1 , key2 = value2 * </pre> * represents an ObjectName with two keys.  The name of each key * contains six characters, of which the first and last are spaces. * The value associated with the key <code>"&nbsp;key1&nbsp;"</code> * also begins and ends with a space.</p> * * <p>In addition to the restrictions on characters spelt out above, * no part of an ObjectName may contain a newline character * (<code>'\n'</code>), whether the domain, a key, or a value, whether * quoted or unquoted.  The newline character can be represented in a * quoted value with the sequence <code>\n</code>. * * <p>The rules on special characters and quoting apply regardless of * which constructor is used to make an ObjectName.</p> * * <p>To avoid collisions between MBeans supplied by different * vendors, a useful convention is to begin the domain name with the * reverse DNS name of the organization that specifies the MBeans, * followed by a period and a string whose interpretation is * determined by that organization.  For example, MBeans specified by * <code>example.com</code>  would have * domains such as <code>com.example.MyDomain</code>.  This is essentially * the same convention as for Java-language package names.</p> * * <p>The <b>serialVersionUID</b> of this class is <code>1081892073854801359L</code>. * * @since 1.5 */@SuppressWarnings("serial") // don't complain serialVersionUID not constantpublic class ObjectName implements Comparable<ObjectName>, QueryExp {     /**     * A structure recording property structure and     * proposing minimal services     */    private static class Property {         int _key_index;        int _key_length;        int _value_length;         /**         * Constructor.         */        Property(int key_index, int key_length, int value_length) {            _key_index = key_index;            _key_length = key_length;            _value_length = value_length;        }         /**         * Assigns the key index of property         */        void setKeyIndex(int key_index) {            _key_index = key_index;        }         /**         * Returns a key string for receiver key         */        String getKeyString(String name) {            return name.substring(_key_index, _key_index + _key_length);        }         /**         * Returns a value string for receiver key         */        String getValueString(String name) {            int in_begin = _key_index + _key_length + 1;            int out_end = in_begin + _value_length;            return name.substring(in_begin, out_end);        }    }     /**     * Marker class for value pattern property.     */    private static class PatternProperty extends Property {        /**         * Constructor.         */        PatternProperty(int key_index, int key_length, int value_length) {            super(key_index, key_length, value_length);        }    }     // Inner classes <========================================       // Private fields ---------------------------------------->      // Serialization compatibility stuff -------------------->     // Two serial forms are supported in this class. The selected form depends    // on system property "jmx.serial.form":    //  - "1.0" for JMX 1.0    //  - any other value for JMX 1.1 and higher    //    // Serial version for old serial form    private static final long oldSerialVersionUID = -5467795090068647408L;    //    // Serial version for new serial form    private static final long newSerialVersionUID = 1081892073854801359L;    //    // Serializable fields in old serial form    private static final ObjectStreamField[] oldSerialPersistentFields =    {        new ObjectStreamField("domain", String.class),        new ObjectStreamField("propertyList", Hashtable.class),        new ObjectStreamField("propertyListString", String.class),        new ObjectStreamField("canonicalName", String.class),        new ObjectStreamField("pattern", Boolean.TYPE),        new ObjectStreamField("propertyPattern", Boolean.TYPE)    };    //    // Serializable fields in new serial form    private static final ObjectStreamField[] newSerialPersistentFields = { };    //    // Actual serial version and serial form    private static final long serialVersionUID;    private static final ObjectStreamField[] serialPersistentFields;    private static boolean compat = false;    static {        try {            GetPropertyAction act = new GetPropertyAction("jmx.serial.form");            String form = AccessController.doPrivileged(act);            compat = (form != null && form.equals("1.0"));        } catch (Exception e) {            // OK: exception means no compat with 1.0, too bad        }        if (compat) {            serialPersistentFields = oldSerialPersistentFields;            serialVersionUID = oldSerialVersionUID;        } else {            serialPersistentFields = newSerialPersistentFields;            serialVersionUID = newSerialVersionUID;        }    }     //    // Serialization compatibility stuff <==============================     // Class private fields ----------------------------------->     /**     * a shared empty array for empty property lists     */    static final private Property[] _Empty_property_array = new Property[0];      // Class private fields <==============================     // Instance private fields ----------------------------------->     /**     * a String containing the canonical name     */    private transient String _canonicalName;      /**     * An array of properties in the same seq order as time creation     */    private transient Property[] _kp_array;     /**     * An array of properties in the same seq order as canonical order     */    private transient Property[] _ca_array;      /**     * The length of the domain part of built objectname     */    private transient int _domain_length = 0;      /**     * The propertyList of built object name. Initialized lazily.     * Table that contains all the pairs (key,value) for this ObjectName.     */    private transient Map<String,String> _propertyList;     /**     * boolean that declares if this ObjectName domain part is a pattern     */    private transient boolean _domain_pattern = false;     /**     * boolean that declares if this ObjectName contains a pattern on the     * key property list     */    private transient boolean _property_list_pattern = false;     /**     * boolean that declares if this ObjectName contains a pattern on the     * value of at least one key property     */    private transient boolean _property_value_pattern = false;     // Instance private fields <=======================================     // Private fields <========================================      //  Private methods ---------------------------------------->     // Category : Instance construction ------------------------->     /**     * Initializes this {@link ObjectName} from the given string     * representation.     *     * @param name A string representation of the {@link ObjectName}     *     * @exception MalformedObjectNameException The string passed as a     * parameter does not have the right format.     * @exception NullPointerException The <code>name</code> parameter     * is null.     */    private void construct(String name)        throws MalformedObjectNameException {         // The name cannot be null        if (name == null)            throw new NullPointerException("name cannot be null");         // Test if the name is empty        if (name.length() == 0) {            // this is equivalent to the whole word query object name.            _canonicalName = "*:*";            _kp_array = _Empty_property_array;            _ca_array = _Empty_property_array;            _domain_length = 1;            _propertyList = null;            _domain_pattern = true;            _property_list_pattern = true;            _property_value_pattern = false;            return;        }         // initialize parsing of the string        final char[] name_chars = name.toCharArray();        final int len = name_chars.length;        final char[] canonical_chars = new char[len]; // canonical form will                                                      // be same length at most        int cname_index = 0;        int index = 0;        char c, c1;         // parses domain part    domain_parsing:        while (index < len) {            switch (name_chars[index]) {                case ':' :                    _domain_length = index++;                    break domain_parsing;                case '=' :                    // ":" omission check.                    //                    // Although "=" is a valid character in the domain part                    // it is true that it is rarely used in the real world.                    // So check straight away if the ":" has been omitted                    // from the ObjectName. This allows us to provide a more                    // accurate exception message.                    int i = ++index;                    while ((i < len) && (name_chars[i++] != ':'))                        if (i == len)                            throw new MalformedObjectNameException(                                "Domain part must be specified");                    break;                case '\n' :                    throw new MalformedObjectNameException(                              "Invalid character '\\n' in domain name");                case '*' :                case '?' :                    _domain_pattern = true;                    index++;                    break;                default :                    index++;                    break;            }        }         // check for non-empty properties        if (index == len)            throw new MalformedObjectNameException(                                         "Key properties cannot be empty");         // we have got the domain part, begins building of _canonicalName        System.arraycopy(name_chars, 0, canonical_chars, 0, _domain_length);        canonical_chars[_domain_length] = ':';        cname_index = _domain_length + 1;         // parses property list        Property prop;        Map<String,Property> keys_map = new HashMap<String,Property>();        String[] keys;        String key_name;        boolean quoted_value;        int property_index = 0;        int in_index;        int key_index, key_length, value_index, value_length; 

Lines 1–500 of 2111.