JDK 11 jdk.jconsole.jmod - JConsole Tool

JDK 11 jdk.jconsole.jmod is the JMOD file for JDK 11 JConsole tool, which can be invoked by the "jconsole" command.

JDK 11 JConsole tool compiled class files are stored in \fyicenter\jdk-11.0.1\jmods\jdk.jconsole.jmod.

JDK 11 JConsole tool compiled class files are also linked and stored in the \fyicenter\jdk-11.0.1\lib\modules JImage file.

JDK 11 JConsole tool source code files are stored in \fyicenter\jdk-11.0.1\lib\src.zip\jdk.jconsole.

You can click and view the content of each source code file in the list below.

✍: FYIcenter

sun/tools/jconsole/inspector/XTree.java

/*
 * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */

package sun.tools.jconsole.inspector;

import java.io.IOException;
import java.util.*;
import javax.management.*;
import javax.swing.*;
import javax.swing.tree.*;
import sun.tools.jconsole.JConsole;
import sun.tools.jconsole.MBeansTab;
import sun.tools.jconsole.Messages;
import sun.tools.jconsole.inspector.XNodeInfo;
import static sun.tools.jconsole.inspector.XNodeInfo.Type;

@SuppressWarnings("serial")
public class XTree extends JTree {

    private static final List<String> orderedKeyPropertyList =
            new ArrayList<String>();

    static {
        String keyPropertyList =
                System.getProperty("com.sun.tools.jconsole.mbeans.keyPropertyList");
        if (keyPropertyList == null) {
            orderedKeyPropertyList.add("type");
            orderedKeyPropertyList.add("j2eeType");
        } else {
            StringTokenizer st = new StringTokenizer(keyPropertyList, ",");
            while (st.hasMoreTokens()) {
                orderedKeyPropertyList.add(st.nextToken());
            }
        }
    }
    private MBeansTab mbeansTab;
    private Map<String, DefaultMutableTreeNode> nodes =
            new HashMap<String, DefaultMutableTreeNode>();

    public XTree(MBeansTab mbeansTab) {
        this(new DefaultMutableTreeNode("MBeanTreeRootNode"), mbeansTab);
    }

    public XTree(TreeNode root, MBeansTab mbeansTab) {
        super(root, true);
        this.mbeansTab = mbeansTab;
        setRootVisible(false);
        setShowsRootHandles(true);
        ToolTipManager.sharedInstance().registerComponent(this);
    }

    /**
     * This method removes the node from its parent
     */
    // Call on EDT
    private synchronized void removeChildNode(DefaultMutableTreeNode child) {
        DefaultTreeModel model = (DefaultTreeModel) getModel();
        model.removeNodeFromParent(child);
    }

    /**
     * This method adds the child to the specified parent node
     * at specific index.
     */
    // Call on EDT
    private synchronized void addChildNode(
            DefaultMutableTreeNode parent,
            DefaultMutableTreeNode child,
            int index) {
        DefaultTreeModel model = (DefaultTreeModel) getModel();
        model.insertNodeInto(child, parent, index);
    }

    /**
     * This method adds the child to the specified parent node.
     * The index where the child is to be added depends on the
     * child node being Comparable or not. If the child node is
     * not Comparable then it is added at the end, i.e. right
     * after the current parent's children.
     */
    // Call on EDT
    private synchronized void addChildNode(
            DefaultMutableTreeNode parent, DefaultMutableTreeNode child) {
        int childCount = parent.getChildCount();
        if (childCount == 0) {
            addChildNode(parent, child, 0);
            return;
        }
        if (child instanceof ComparableDefaultMutableTreeNode) {
            ComparableDefaultMutableTreeNode comparableChild =
                    (ComparableDefaultMutableTreeNode) child;
            for (int i = childCount - 1; i >= 0; i--) {
                DefaultMutableTreeNode brother =
                        (DefaultMutableTreeNode) parent.getChildAt(i);
                // expr1: child node must be inserted after metadata nodes
                // - OR -
                // expr2: "child >= brother"
                if ((i <= 2 && isMetadataNode(brother)) ||
                        comparableChild.compareTo(brother) >= 0) {
                    addChildNode(parent, child, i + 1);
                    return;
                }
            }
            // "child < all brothers", add at the beginning
            addChildNode(parent, child, 0);
            return;
        }
        // "child not comparable", add at the end
        addChildNode(parent, child, childCount);
    }

    /**
     * This method removes all the displayed nodes from the tree,
     * but does not affect actual MBeanServer contents.
     */
    // Call on EDT
    @Override
    public synchronized void removeAll() {
        DefaultTreeModel model = (DefaultTreeModel) getModel();
        DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot();
        root.removeAllChildren();
        model.nodeStructureChanged(root);
        nodes.clear();
    }

    // Call on EDT
    public synchronized void removeMBeanFromView(ObjectName mbean) {
        // We assume here that MBeans are removed one by one (on MBean
        // unregistered notification). Deletes the tree node associated
        // with the given MBean and recursively all the node parents
        // which are leaves and non XMBean.
        //
        DefaultMutableTreeNode node = null;
        Dn dn = new Dn(mbean);
        if (dn.getTokenCount() > 0) {
            DefaultTreeModel model = (DefaultTreeModel) getModel();
            Token token = dn.getToken(0);
            String hashKey = dn.getHashKey(token);
            node = nodes.get(hashKey);
            if ((node != null) && (!node.isRoot())) {
                if (hasNonMetadataNodes(node)) {
                    removeMetadataNodes(node);
                    String label = token.getValue();
                    XNodeInfo userObject = new XNodeInfo(
                            Type.NONMBEAN, label,
                            label, token.getTokenValue());
                    changeNodeValue(node, userObject);
                } else {
                    DefaultMutableTreeNode parent =
                            (DefaultMutableTreeNode) node.getParent();
                    model.removeNodeFromParent(node);
                    nodes.remove(hashKey);
                    removeParentFromView(dn, 1, parent);
                }
            }
        }
    }

    /**
     * Returns true if any of the children nodes is a non MBean metadata node.
     */
    private boolean hasNonMetadataNodes(DefaultMutableTreeNode node) {
        for (Enumeration<?> e = node.children(); e.hasMoreElements();) {
            DefaultMutableTreeNode n = (DefaultMutableTreeNode) e.nextElement();
            Object uo = n.getUserObject();
            if (uo instanceof XNodeInfo) {
                switch (((XNodeInfo) uo).getType()) {
                    case ATTRIBUTES:
                    case NOTIFICATIONS:
                    case OPERATIONS:
                        break;
                    default:
                        return true;
                }
            } else {
                return true;
            }
        }
        return false;
    }

    /**
     * Returns true if any of the children nodes is an MBean metadata node.
     */
    public boolean hasMetadataNodes(DefaultMutableTreeNode node) {
        for (Enumeration<?> e = node.children(); e.hasMoreElements();) {
            DefaultMutableTreeNode n = (DefaultMutableTreeNode) e.nextElement();
            Object uo = n.getUserObject();
            if (uo instanceof XNodeInfo) {
                switch (((XNodeInfo) uo).getType()) {
                    case ATTRIBUTES:
                    case NOTIFICATIONS:
                    case OPERATIONS:
                        return true;
                    default:
                        break;
                }
            } else {
                return false;
            }
        }
        return false;
    }

    /**
     * Returns true if the given node is an MBean metadata node.
     */
    public boolean isMetadataNode(DefaultMutableTreeNode node) {
        Object uo = node.getUserObject();
        if (uo instanceof XNodeInfo) {
            switch (((XNodeInfo) uo).getType()) {
                case ATTRIBUTES:
                case NOTIFICATIONS:
                case OPERATIONS:
                    return true;
                default:
                    return false;
            }
        } else {
            return false;
        }
    }

    /**
     * Remove the metadata nodes associated with a given MBean node.
     */
    // Call on EDT
    private void removeMetadataNodes(DefaultMutableTreeNode node) {
        Set<DefaultMutableTreeNode> metadataNodes =
                new HashSet<DefaultMutableTreeNode>();
        DefaultTreeModel model = (DefaultTreeModel) getModel();
        for (Enumeration<?> e = node.children(); e.hasMoreElements();) {
            DefaultMutableTreeNode n = (DefaultMutableTreeNode) e.nextElement();
            Object uo = n.getUserObject();
            if (uo instanceof XNodeInfo) {
                switch (((XNodeInfo) uo).getType()) {
                    case ATTRIBUTES:
                    case NOTIFICATIONS:
                    case OPERATIONS:
                        metadataNodes.add(n);
                        break;
                    default:
                        break;
                }
            }
        }
        for (DefaultMutableTreeNode n : metadataNodes) {
            model.removeNodeFromParent(n);
        }
    }

    /**
     * Removes only the parent nodes which are non MBean and leaf.
     * This method assumes the child nodes have been removed before.
     */
    // Call on EDT
    private DefaultMutableTreeNode removeParentFromView(
            Dn dn, int index, DefaultMutableTreeNode node) {
        if ((!node.isRoot()) && node.isLeaf() &&
                (!(((XNodeInfo) node.getUserObject()).getType().equals(Type.MBEAN)))) {
            DefaultMutableTreeNode parent =
                    (DefaultMutableTreeNode) node.getParent();
            removeChildNode(node);
            String hashKey = dn.getHashKey(dn.getToken(index));
            nodes.remove(hashKey);
            removeParentFromView(dn, index + 1, parent);
        }
        return node;
    }

    // Call on EDT
    public synchronized void addMBeansToView(Set<ObjectName> mbeans) {
        Set<Dn> dns = new TreeSet<Dn>();
        for (ObjectName mbean : mbeans) {
            Dn dn = new Dn(mbean);
            dns.add(dn);
        }
        for (Dn dn : dns) {
            ObjectName mbean = dn.getObjectName();
            XMBean xmbean = new XMBean(mbean, mbeansTab);
            addMBeanToView(mbean, xmbean, dn);
        }
    }

    // Call on EDT
    public synchronized void addMBeanToView(ObjectName mbean) {
        // Build XMBean for the given MBean
        //
        XMBean xmbean = new XMBean(mbean, mbeansTab);
        // Build Dn for the given MBean
        //
        Dn dn = new Dn(mbean);
        // Add the new nodes to the MBean tree from leaf to root
        //
        addMBeanToView(mbean, xmbean, dn);
    }

    // Call on EDT
    private synchronized void addMBeanToView(
            ObjectName mbean, XMBean xmbean, Dn dn) {

        DefaultMutableTreeNode childNode = null;
        DefaultMutableTreeNode parentNode = null;

        // Add the node or replace its user object if already added
        //
        Token token = dn.getToken(0);
        String hashKey = dn.getHashKey(token);
        if (nodes.containsKey(hashKey)) {
            // Found existing node previously created when adding another node
            //
            childNode = nodes.get(hashKey);
            // Replace user object to reflect that this node is an MBean
            //
            Object data = createNodeValue(xmbean, token);
            String label = data.toString();
            XNodeInfo userObject =
                    new XNodeInfo(Type.MBEAN, data, label, mbean.toString());
            changeNodeValue(childNode, userObject);
            return;
        }

        // Create new leaf node
        //
        childNode = createDnNode(dn, token, xmbean);
        nodes.put(hashKey, childNode);

        // Add intermediate non MBean nodes
        //
        for (int i = 1; i < dn.getTokenCount(); i++) {
            token = dn.getToken(i);
            hashKey = dn.getHashKey(token);
            if (nodes.containsKey(hashKey)) {
                // Intermediate node already present, add new node as child
                //
                parentNode = nodes.get(hashKey);
                addChildNode(parentNode, childNode);
                return;
            } else {
                // Create new intermediate node
                //
                if ("domain".equals(token.getTokenType())) {
                    parentNode = createDomainNode(dn, token);
                    DefaultMutableTreeNode root =
                            (DefaultMutableTreeNode) getModel().getRoot();
                    addChildNode(root, parentNode);
                } else {
                    parentNode = createSubDnNode(dn, token);
                }
                nodes.put(hashKey, parentNode);
                addChildNode(parentNode, childNode);
            }
            childNode = parentNode;
        }
    }

    // Call on EDT
    private synchronized void changeNodeValue(
            DefaultMutableTreeNode node, XNodeInfo nodeValue) {
        if (node instanceof ComparableDefaultMutableTreeNode) {
            // should it stay at the same place?
            DefaultMutableTreeNode clone =
                    (DefaultMutableTreeNode) node.clone();
            clone.setUserObject(nodeValue);
            if (((ComparableDefaultMutableTreeNode) node).compareTo(clone) == 0) {
                // the order in the tree didn't change
                node.setUserObject(nodeValue);
                DefaultTreeModel model = (DefaultTreeModel) getModel();
                model.nodeChanged(node);
            } else {
                // delete the node and re-order it in case the
                // node value modifies the order in the tree
                DefaultMutableTreeNode parent =
                        (DefaultMutableTreeNode) node.getParent();
                removeChildNode(node);
                node.setUserObject(nodeValue);
                addChildNode(parent, node);
            }
        } else {
            // not comparable stays at the same place
            node.setUserObject(nodeValue);
            DefaultTreeModel model = (DefaultTreeModel) getModel();
            model.nodeChanged(node);
        }
        // Load the MBean metadata if type is MBEAN
        if (nodeValue.getType().equals(Type.MBEAN)) {
            removeMetadataNodes(node);
            TreeNode[] treeNodes = node.getPath();
            TreePath path = new TreePath(treeNodes);
            if (isExpanded(path)) {
                addMetadataNodes(node);
            }
        }
        // Clear the current selection and set it
        // again so valueChanged() gets called
        if (node == getLastSelectedPathComponent()) {
            TreePath selectionPath = getSelectionPath();
            clearSelection();
            setSelectionPath(selectionPath);
        }
    }

    /**
     * Creates the domain node.
     */
    private DefaultMutableTreeNode createDomainNode(Dn dn, Token token) {
        DefaultMutableTreeNode node = new ComparableDefaultMutableTreeNode();
        String label = dn.getDomain();
        XNodeInfo userObject =
                new XNodeInfo(Type.NONMBEAN, label, label, label);
        node.setUserObject(userObject);
        return node;
    }

    /**
     * Creates the node corresponding to the whole Dn, i.e. an MBean.
     */
    private DefaultMutableTreeNode createDnNode(
            Dn dn, Token token, XMBean xmbean) {
        DefaultMutableTreeNode node = new ComparableDefaultMutableTreeNode();
        Object data = createNodeValue(xmbean, token);
        String label = data.toString();
        XNodeInfo userObject = new XNodeInfo(Type.MBEAN, data, label,
                xmbean.getObjectName().toString());
        node.setUserObject(userObject);
        return node;
    }

    /**
     * Creates the node corresponding to a subDn, i.e. a non-MBean
     * intermediate node.
     */
    private DefaultMutableTreeNode createSubDnNode(Dn dn, Token token) {
        DefaultMutableTreeNode node = new ComparableDefaultMutableTreeNode();
        String label = isKeyValueView() ? token.getTokenValue() : token.getValue();
        XNodeInfo userObject =
                new XNodeInfo(Type.NONMBEAN, label, label, token.getTokenValue());
        node.setUserObject(userObject);
        return node;
    }

    private Object createNodeValue(XMBean xmbean, Token token) {
        String label = isKeyValueView() ? token.getTokenValue() : token.getValue();
        xmbean.setText(label);
        return xmbean;
    }

    /**
     * Parses the MBean ObjectName comma-separated properties string and puts
     * the individual key/value pairs into the map. Key order in the properties
     * string is preserved by the map.
     */
    private static Map<String, String> extractKeyValuePairs(
            String props, ObjectName mbean) {
        Map<String, String> map = new LinkedHashMap<String, String>();
        int eq = props.indexOf('=');
        while (eq != -1) {
            String key = props.substring(0, eq);
            String value = mbean.getKeyProperty(key);
            map.put(key, value);
            props = props.substring(key.length() + 1 + value.length());
            if (props.startsWith(",")) {
                props = props.substring(1);
            }
            eq = props.indexOf('=');
        }
        return map;
    }

    /**
     * Returns the ordered key property list that will be used to build the
     * MBean tree. If the "com.sun.tools.jconsole.mbeans.keyPropertyList" system
     * property is not specified, then the ordered key property list used
     * to build the MBean tree will be the one returned by the method
     * ObjectName.getKeyPropertyListString() with "type" as first key,
     * and "j2eeType" as second key, if present. If any of the keys specified
     * in the comma-separated key property list does not apply to the given
     * MBean then it will be discarded.
     */
    private static String getKeyPropertyListString(ObjectName mbean) {
        String props = mbean.getKeyPropertyListString();
        Map<String, String> map = extractKeyValuePairs(props, mbean);
        StringBuilder sb = new StringBuilder();
        // Add the key/value pairs to the buffer following the
        // key order defined by the "orderedKeyPropertyList"
        for (String key : orderedKeyPropertyList) {
            if (map.containsKey(key)) {
                sb.append(key).append('=').append(map.get(key)).append(',');
                map.remove(key);
            }
        }
        // Add the remaining key/value pairs to the buffer
        for (Map.Entry<String, String> entry : map.entrySet()) {
            sb.append(entry.getKey()).append('=').append(entry.getValue()).append(',');
        }
        String orderedKeyPropertyListString = sb.toString();
        orderedKeyPropertyListString = orderedKeyPropertyListString.substring(
                0, orderedKeyPropertyListString.length() - 1);
        return orderedKeyPropertyListString;
    }

    // Call on EDT
    public void addMetadataNodes(DefaultMutableTreeNode node) {
        XMBean mbean = (XMBean) ((XNodeInfo) node.getUserObject()).getData();
        DefaultTreeModel model = (DefaultTreeModel) getModel();
        MBeanInfoNodesSwingWorker sw =
                new MBeanInfoNodesSwingWorker(model, node, mbean);
        if (sw != null) {
            sw.execute();
        }
    }

    private static class MBeanInfoNodesSwingWorker
            extends SwingWorker<Object[], Void> {

        private final DefaultTreeModel model;
        private final DefaultMutableTreeNode node;
        private final XMBean mbean;

        public MBeanInfoNodesSwingWorker(
                DefaultTreeModel model,
                DefaultMutableTreeNode node,
                XMBean mbean) {
            this.model = model;
            this.node = node;
            this.mbean = mbean;
        }

        @Override
        public Object[] doInBackground() throws InstanceNotFoundException,
                IntrospectionException, ReflectionException, IOException {
            Object result[] = new Object[2];
            // Retrieve MBeanInfo for this MBean
            result[0] = mbean.getMBeanInfo();
            // Check if this MBean is a notification emitter
            result[1] = mbean.isBroadcaster();
            return result;
        }

        @Override
        protected void done() {
            try {
                Object result[] = get();
                MBeanInfo mbeanInfo = (MBeanInfo) result[0];
                Boolean isBroadcaster = (Boolean) result[1];
                if (mbeanInfo != null) {
                    addMBeanInfoNodes(model, node, mbean, mbeanInfo, isBroadcaster);
                }
            } catch (Exception e) {
                Throwable t = Utils.getActualException(e);
                if (JConsole.isDebug()) {
                    t.printStackTrace();
                }
            }
        }

        // Call on EDT
        private void addMBeanInfoNodes(
                DefaultTreeModel tree, DefaultMutableTreeNode node,
                XMBean mbean, MBeanInfo mbeanInfo, Boolean isBroadcaster) {
            MBeanAttributeInfo[] ai = mbeanInfo.getAttributes();
            MBeanOperationInfo[] oi = mbeanInfo.getOperations();
            MBeanNotificationInfo[] ni = mbeanInfo.getNotifications();

            // Insert the Attributes/Operations/Notifications metadata nodes as
            // the three first children of this MBean node. This is only useful
            // when this MBean node denotes an MBean but it's not a leaf in the
            // MBean tree
            //
            int childIndex = 0;

            // MBeanAttributeInfo node
            //
            if (ai != null && ai.length > 0) {
                DefaultMutableTreeNode attributes = new DefaultMutableTreeNode();
                XNodeInfo attributesUO = new XNodeInfo(Type.ATTRIBUTES, mbean,
                        Messages.ATTRIBUTES, null);
                attributes.setUserObject(attributesUO);
                node.insert(attributes, childIndex++);
                for (MBeanAttributeInfo mbai : ai) {
                    DefaultMutableTreeNode attribute = new DefaultMutableTreeNode();
                    XNodeInfo attributeUO = new XNodeInfo(Type.ATTRIBUTE,
                            new Object[]{mbean, mbai}, mbai.getName(), null);
                    attribute.setUserObject(attributeUO);
                    attribute.setAllowsChildren(false);
                    attributes.add(attribute);
                }
            }
            // MBeanOperationInfo node
            //
            if (oi != null && oi.length > 0) {
                DefaultMutableTreeNode operations = new DefaultMutableTreeNode();
                XNodeInfo operationsUO = new XNodeInfo(Type.OPERATIONS, mbean,
                        Messages.OPERATIONS, null);
                operations.setUserObject(operationsUO);
                node.insert(operations, childIndex++);
                for (MBeanOperationInfo mboi : oi) {
                    // Compute the operation's tool tip text:
                    // "operationname(param1type,param2type,...)"
                    //
                    StringBuilder sb = new StringBuilder();
                    for (MBeanParameterInfo mbpi : mboi.getSignature()) {
                        sb.append(mbpi.getType()).append(',');
                    }
                    String signature = sb.toString();
                    if (signature.length() > 0) {
                        // Remove the trailing ','
                        //
                        signature = signature.substring(0, signature.length() - 1);
                    }
                    String toolTipText = mboi.getName() + "(" + signature + ")";
                    // Create operation node
                    //
                    DefaultMutableTreeNode operation = new DefaultMutableTreeNode();
                    XNodeInfo operationUO = new XNodeInfo(Type.OPERATION,
                            new Object[]{mbean, mboi}, mboi.getName(), toolTipText);
                    operation.setUserObject(operationUO);
                    operation.setAllowsChildren(false);
                    operations.add(operation);
                }
            }
            // MBeanNotificationInfo node
            //
            if (isBroadcaster != null && isBroadcaster.booleanValue()) {
                DefaultMutableTreeNode notifications = new DefaultMutableTreeNode();
                XNodeInfo notificationsUO = new XNodeInfo(Type.NOTIFICATIONS, mbean,
                        Messages.NOTIFICATIONS, null);
                notifications.setUserObject(notificationsUO);
                node.insert(notifications, childIndex++);
                if (ni != null && ni.length > 0) {
                    for (MBeanNotificationInfo mbni : ni) {
                        DefaultMutableTreeNode notification =
                                new DefaultMutableTreeNode();
                        XNodeInfo notificationUO = new XNodeInfo(Type.NOTIFICATION,
                                mbni, mbni.getName(), null);
                        notification.setUserObject(notificationUO);
                        notification.setAllowsChildren(false);
                        notifications.add(notification);
                    }
                }
            }
            // Update tree model
            //
            model.reload(node);
        }
    }
    //
    // Tree preferences
    //
    private static boolean treeView;
    private static boolean treeViewInit = false;

    private static boolean isTreeView() {
        if (!treeViewInit) {
            treeView = getTreeViewValue();
            treeViewInit = true;
        }
        return treeView;
    }

    private static boolean getTreeViewValue() {
        String tv = System.getProperty("treeView");
        return ((tv == null) ? true : !(tv.equals("false")));
    }
    //
    // MBean key-value preferences
    //
    private boolean keyValueView = Boolean.getBoolean("keyValueView");

    private boolean isKeyValueView() {
        return keyValueView;
    }

    //
    // Utility classes
    //
    private static class ComparableDefaultMutableTreeNode
            extends DefaultMutableTreeNode
            implements Comparable<DefaultMutableTreeNode> {

        public int compareTo(DefaultMutableTreeNode node) {
            return (this.toString().compareTo(node.toString()));
        }
    }

    private static class Dn implements Comparable<Dn> {

        private ObjectName mbean;
        private String domain;
        private String keyPropertyList;
        private String hashDn;
        private List<Token> tokens = new ArrayList<Token>();

        public Dn(ObjectName mbean) {
            this.mbean = mbean;
            this.domain = mbean.getDomain();
            this.keyPropertyList = getKeyPropertyListString(mbean);

            if (isTreeView()) {
                // Tree view
                Map<String, String> map =
                        extractKeyValuePairs(keyPropertyList, mbean);
                for (Map.Entry<String, String> entry : map.entrySet()) {
                    tokens.add(new Token("key", entry.getKey() + "=" + entry.getValue()));
                }
            } else {
                // Flat view
                tokens.add(new Token("key", "properties=" + keyPropertyList));
            }

            // Add the domain as the first token in the Dn
            tokens.add(0, new Token("domain", "domain=" + domain));

            // Reverse the Dn (from leaf to root)
            Collections.reverse(tokens);

            // Compute hash for Dn
            computeHashDn();
        }

        public ObjectName getObjectName() {
            return mbean;
        }

        public String getDomain() {
            return domain;
        }

        public String getKeyPropertyList() {
            return keyPropertyList;
        }

        public Token getToken(int index) {
            return tokens.get(index);
        }

        public int getTokenCount() {
            return tokens.size();
        }

        public String getHashDn() {
            return hashDn;
        }

        public String getHashKey(Token token) {
            final int begin = hashDn.indexOf(token.getTokenValue());
            return hashDn.substring(begin, hashDn.length());
        }

        private void computeHashDn() {
            if (tokens.isEmpty()) {
                return;
            }
            final StringBuilder hdn = new StringBuilder();
            for (int i = 0; i < tokens.size(); i++) {
                hdn.append(tokens.get(i).getTokenValue());
                hdn.append(",");
            }
            hashDn = hdn.substring(0, hdn.length() - 1);
        }

        @Override
        public String toString() {
            return domain + ":" + keyPropertyList;
        }

        public int compareTo(Dn dn) {
            return this.toString().compareTo(dn.toString());
        }
    }

    private static class Token {

        private String tokenType;
        private String tokenValue;
        private String key;
        private String value;

        public Token(String tokenType, String tokenValue) {
            this.tokenType = tokenType;
            this.tokenValue = tokenValue;
            buildKeyValue();
        }

        public String getTokenType() {
            return tokenType;
        }

        public String getTokenValue() {
            return tokenValue;
        }

        public String getKey() {
            return key;
        }

        public String getValue() {
            return value;
        }

        private void buildKeyValue() {
            int index = tokenValue.indexOf('=');
            if (index < 0) {
                key = tokenValue;
                value = tokenValue;
            } else {
                key = tokenValue.substring(0, index);
                value = tokenValue.substring(index + 1, tokenValue.length());
            }
        }
    }
}

sun/tools/jconsole/inspector/XTree.java

 

Or download all of them as a single archive file:

File name: jdk.jconsole-11.0.1-src.zip
File size: 164713 bytes
Release date: 2018-11-04
Download 

 

JDK 11 jdk.jdeps.jmod - JDeps Tool

JDK 11 jdk.jcmd.jmod - JCmd Tool

Download and Use JDK 11

⇑⇑ FAQ for JDK (Java Development Kit)

2020-07-07, 20015👍, 0💬