History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/tools/jconsole/inspector/XTree.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/tools/jconsole/inspector/XTree.java+834−0
@@ -0,0 +1,834 @@
1+/*
2+ * Copyright (c) 2004, 2008, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package sun.tools.jconsole.inspector;
27+
28+import java.io.IOException;
29+import java.util.*;
30+import javax.management.*;
31+import javax.swing.*;
32+import javax.swing.tree.*;
33+import sun.tools.jconsole.JConsole;
34+import sun.tools.jconsole.MBeansTab;
35+import sun.tools.jconsole.Resources;
36+import sun.tools.jconsole.inspector.XNodeInfo;
37+import static sun.tools.jconsole.inspector.XNodeInfo.Type;
38+
39+@SuppressWarnings("serial")
40+public class XTree extends JTree {
41+
42+ private static final List<String> orderedKeyPropertyList =
43+ new ArrayList<String>();
44+
45+ static {
46+ String keyPropertyList =
47+ System.getProperty("com.sun.tools.jconsole.mbeans.keyPropertyList");
48+ if (keyPropertyList == null) {
49+ orderedKeyPropertyList.add("type");
50+ orderedKeyPropertyList.add("j2eeType");
51+ } else {
52+ StringTokenizer st = new StringTokenizer(keyPropertyList, ",");
53+ while (st.hasMoreTokens()) {
54+ orderedKeyPropertyList.add(st.nextToken());
55+ }
56+ }
57+ }
58+ private MBeansTab mbeansTab;
59+ private Map<String, DefaultMutableTreeNode> nodes =
60+ new HashMap<String, DefaultMutableTreeNode>();
61+
62+ public XTree(MBeansTab mbeansTab) {
63+ this(new DefaultMutableTreeNode("MBeanTreeRootNode"), mbeansTab);
64+ }
65+
66+ public XTree(TreeNode root, MBeansTab mbeansTab) {
67+ super(root, true);
68+ this.mbeansTab = mbeansTab;
69+ setRootVisible(false);
70+ setShowsRootHandles(true);
71+ ToolTipManager.sharedInstance().registerComponent(this);
72+ }
73+
74+ /**
75+ * This method removes the node from its parent
76+ */
77+ // Call on EDT
78+ private synchronized void removeChildNode(DefaultMutableTreeNode child) {
79+ DefaultTreeModel model = (DefaultTreeModel) getModel();
80+ model.removeNodeFromParent(child);
81+ }
82+
83+ /**
84+ * This method adds the child to the specified parent node
85+ * at specific index.
86+ */
87+ // Call on EDT
88+ private synchronized void addChildNode(
89+ DefaultMutableTreeNode parent,
90+ DefaultMutableTreeNode child,
91+ int index) {
92+ DefaultTreeModel model = (DefaultTreeModel) getModel();
93+ model.insertNodeInto(child, parent, index);
94+ }
95+
96+ /**
97+ * This method adds the child to the specified parent node.
98+ * The index where the child is to be added depends on the
99+ * child node being Comparable or not. If the child node is
100+ * not Comparable then it is added at the end, i.e. right
101+ * after the current parent's children.
102+ */
103+ // Call on EDT
104+ private synchronized void addChildNode(
105+ DefaultMutableTreeNode parent, DefaultMutableTreeNode child) {
106+ int childCount = parent.getChildCount();
107+ if (childCount == 0) {
108+ addChildNode(parent, child, 0);
109+ return;
110+ }
111+ if (child instanceof ComparableDefaultMutableTreeNode) {
112+ ComparableDefaultMutableTreeNode comparableChild =
113+ (ComparableDefaultMutableTreeNode) child;
114+ for (int i = childCount - 1; i >= 0; i--) {
115+ DefaultMutableTreeNode brother =
116+ (DefaultMutableTreeNode) parent.getChildAt(i);
117+ // expr1: child node must be inserted after metadata nodes
118+ // - OR -
119+ // expr2: "child >= brother"
120+ if ((i <= 2 && isMetadataNode(brother)) ||
121+ comparableChild.compareTo(brother) >= 0) {
122+ addChildNode(parent, child, i + 1);
123+ return;
124+ }
125+ }
126+ // "child < all brothers", add at the beginning
127+ addChildNode(parent, child, 0);
128+ return;
129+ }
130+ // "child not comparable", add at the end
131+ addChildNode(parent, child, childCount);
132+ }
133+
134+ /**
135+ * This method removes all the displayed nodes from the tree,
136+ * but does not affect actual MBeanServer contents.
137+ */
138+ // Call on EDT
139+ @Override
140+ public synchronized void removeAll() {
141+ DefaultTreeModel model = (DefaultTreeModel) getModel();
142+ DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot();
143+ root.removeAllChildren();
144+ model.nodeStructureChanged(root);
145+ nodes.clear();
146+ }
147+
148+ // Call on EDT
149+ public synchronized void removeMBeanFromView(ObjectName mbean) {
150+ // We assume here that MBeans are removed one by one (on MBean
151+ // unregistered notification). Deletes the tree node associated
152+ // with the given MBean and recursively all the node parents
153+ // which are leaves and non XMBean.
154+ //
155+ DefaultMutableTreeNode node = null;
156+ Dn dn = new Dn(mbean);
157+ if (dn.getTokenCount() > 0) {
158+ DefaultTreeModel model = (DefaultTreeModel) getModel();
159+ Token token = dn.getToken(0);
160+ String hashKey = dn.getHashKey(token);
161+ node = nodes.get(hashKey);
162+ if ((node != null) && (!node.isRoot())) {
163+ if (hasNonMetadataNodes(node)) {
164+ removeMetadataNodes(node);
165+ String label = token.getValue();
166+ XNodeInfo userObject = new XNodeInfo(
167+ Type.NONMBEAN, label,
168+ label, token.getTokenValue());
169+ changeNodeValue(node, userObject);
170+ } else {
171+ DefaultMutableTreeNode parent =
172+ (DefaultMutableTreeNode) node.getParent();
173+ model.removeNodeFromParent(node);
174+ nodes.remove(hashKey);
175+ removeParentFromView(dn, 1, parent);
176+ }
177+ }
178+ }
179+ }
180+
181+ /**
182+ * Returns true if any of the children nodes is a non MBean metadata node.
183+ */
184+ private boolean hasNonMetadataNodes(DefaultMutableTreeNode node) {
185+ for (Enumeration e = node.children(); e.hasMoreElements();) {
186+ DefaultMutableTreeNode n = (DefaultMutableTreeNode) e.nextElement();
187+ Object uo = n.getUserObject();
188+ if (uo instanceof XNodeInfo) {
189+ switch (((XNodeInfo) uo).getType()) {
190+ case ATTRIBUTES:
191+ case NOTIFICATIONS:
192+ case OPERATIONS:
193+ break;
194+ default:
195+ return true;
196+ }
197+ } else {
198+ return true;
199+ }
200+ }
201+ return false;
202+ }
203+
204+ /**
205+ * Returns true if any of the children nodes is an MBean metadata node.
206+ */
207+ public boolean hasMetadataNodes(DefaultMutableTreeNode node) {
208+ for (Enumeration e = node.children(); e.hasMoreElements();) {
209+ DefaultMutableTreeNode n = (DefaultMutableTreeNode) e.nextElement();
210+ Object uo = n.getUserObject();
211+ if (uo instanceof XNodeInfo) {
212+ switch (((XNodeInfo) uo).getType()) {
213+ case ATTRIBUTES:
214+ case NOTIFICATIONS:
215+ case OPERATIONS:
216+ return true;
217+ default:
218+ break;
219+ }
220+ } else {
221+ return false;
222+ }
223+ }
224+ return false;
225+ }
226+
227+ /**
228+ * Returns true if the given node is an MBean metadata node.
229+ */
230+ public boolean isMetadataNode(DefaultMutableTreeNode node) {
231+ Object uo = node.getUserObject();
232+ if (uo instanceof XNodeInfo) {
233+ switch (((XNodeInfo) uo).getType()) {
234+ case ATTRIBUTES:
235+ case NOTIFICATIONS:
236+ case OPERATIONS:
237+ return true;
238+ default:
239+ return false;
240+ }
241+ } else {
242+ return false;
243+ }
244+ }
245+
246+ /**
247+ * Remove the metadata nodes associated with a given MBean node.
248+ */
249+ // Call on EDT
250+ private void removeMetadataNodes(DefaultMutableTreeNode node) {
251+ Set<DefaultMutableTreeNode> metadataNodes =
252+ new HashSet<DefaultMutableTreeNode>();
253+ DefaultTreeModel model = (DefaultTreeModel) getModel();
254+ for (Enumeration e = node.children(); e.hasMoreElements();) {
255+ DefaultMutableTreeNode n = (DefaultMutableTreeNode) e.nextElement();
256+ Object uo = n.getUserObject();
257+ if (uo instanceof XNodeInfo) {
258+ switch (((XNodeInfo) uo).getType()) {
259+ case ATTRIBUTES:
260+ case NOTIFICATIONS:
261+ case OPERATIONS:
262+ metadataNodes.add(n);
263+ break;
264+ default:
265+ break;
266+ }
267+ }
268+ }
269+ for (DefaultMutableTreeNode n : metadataNodes) {
270+ model.removeNodeFromParent(n);
271+ }
272+ }
273+
274+ /**
275+ * Removes only the parent nodes which are non MBean and leaf.
276+ * This method assumes the child nodes have been removed before.
277+ */
278+ // Call on EDT
279+ private DefaultMutableTreeNode removeParentFromView(
280+ Dn dn, int index, DefaultMutableTreeNode node) {
281+ if ((!node.isRoot()) && node.isLeaf() &&
282+ (!(((XNodeInfo) node.getUserObject()).getType().equals(Type.MBEAN)))) {
283+ DefaultMutableTreeNode parent =
284+ (DefaultMutableTreeNode) node.getParent();
285+ removeChildNode(node);
286+ String hashKey = dn.getHashKey(dn.getToken(index));
287+ nodes.remove(hashKey);
288+ removeParentFromView(dn, index + 1, parent);
289+ }
290+ return node;
291+ }
292+
293+ // Call on EDT
294+ public synchronized void addMBeansToView(Set<ObjectName> mbeans) {
295+ Set<Dn> dns = new TreeSet<Dn>();
296+ for (ObjectName mbean : mbeans) {
297+ Dn dn = new Dn(mbean);
298+ dns.add(dn);
299+ }
300+ for (Dn dn : dns) {
301+ ObjectName mbean = dn.getObjectName();
302+ XMBean xmbean = new XMBean(mbean, mbeansTab);
303+ addMBeanToView(mbean, xmbean, dn);
304+ }
305+ }
306+
307+ // Call on EDT
308+ public synchronized void addMBeanToView(ObjectName mbean) {
309+ // Build XMBean for the given MBean
310+ //
311+ XMBean xmbean = new XMBean(mbean, mbeansTab);
312+ // Build Dn for the given MBean
313+ //
314+ Dn dn = new Dn(mbean);
315+ // Add the new nodes to the MBean tree from leaf to root
316+ //
317+ addMBeanToView(mbean, xmbean, dn);
318+ }
319+
320+ // Call on EDT
321+ private synchronized void addMBeanToView(
322+ ObjectName mbean, XMBean xmbean, Dn dn) {
323+
324+ DefaultMutableTreeNode childNode = null;
325+ DefaultMutableTreeNode parentNode = null;
326+
327+ // Add the node or replace its user object if already added
328+ //
329+ Token token = dn.getToken(0);
330+ String hashKey = dn.getHashKey(token);
331+ if (nodes.containsKey(hashKey)) {
332+ // Found existing node previously created when adding another node
333+ //
334+ childNode = nodes.get(hashKey);
335+ // Replace user object to reflect that this node is an MBean
336+ //
337+ Object data = createNodeValue(xmbean, token);
338+ String label = data.toString();
339+ XNodeInfo userObject =
340+ new XNodeInfo(Type.MBEAN, data, label, mbean.toString());
341+ changeNodeValue(childNode, userObject);
342+ return;
343+ }
344+
345+ // Create new leaf node
346+ //
347+ childNode = createDnNode(dn, token, xmbean);
348+ nodes.put(hashKey, childNode);
349+
350+ // Add intermediate non MBean nodes
351+ //
352+ for (int i = 1; i < dn.getTokenCount(); i++) {
353+ token = dn.getToken(i);
354+ hashKey = dn.getHashKey(token);
355+ if (nodes.containsKey(hashKey)) {
356+ // Intermediate node already present, add new node as child
357+ //
358+ parentNode = nodes.get(hashKey);
359+ addChildNode(parentNode, childNode);
360+ return;
361+ } else {
362+ // Create new intermediate node
363+ //
364+ if ("domain".equals(token.getTokenType())) {
365+ parentNode = createDomainNode(dn, token);
366+ DefaultMutableTreeNode root =
367+ (DefaultMutableTreeNode) getModel().getRoot();
368+ addChildNode(root, parentNode);
369+ } else {
370+ parentNode = createSubDnNode(dn, token);
371+ }
372+ nodes.put(hashKey, parentNode);
373+ addChildNode(parentNode, childNode);
374+ }
375+ childNode = parentNode;
376+ }
377+ }
378+
379+ // Call on EDT
380+ private synchronized void changeNodeValue(
381+ DefaultMutableTreeNode node, XNodeInfo nodeValue) {
382+ if (node instanceof ComparableDefaultMutableTreeNode) {
383+ // should it stay at the same place?
384+ DefaultMutableTreeNode clone =
385+ (DefaultMutableTreeNode) node.clone();
386+ clone.setUserObject(nodeValue);
387+ if (((ComparableDefaultMutableTreeNode) node).compareTo(clone) == 0) {
388+ // the order in the tree didn't change
389+ node.setUserObject(nodeValue);
390+ DefaultTreeModel model = (DefaultTreeModel) getModel();
391+ model.nodeChanged(node);
392+ } else {
393+ // delete the node and re-order it in case the
394+ // node value modifies the order in the tree
395+ DefaultMutableTreeNode parent =
396+ (DefaultMutableTreeNode) node.getParent();
397+ removeChildNode(node);
398+ node.setUserObject(nodeValue);
399+ addChildNode(parent, node);
400+ }
401+ } else {
402+ // not comparable stays at the same place
403+ node.setUserObject(nodeValue);
404+ DefaultTreeModel model = (DefaultTreeModel) getModel();
405+ model.nodeChanged(node);
406+ }
407+ // Load the MBean metadata if type is MBEAN
408+ if (nodeValue.getType().equals(Type.MBEAN)) {
409+ removeMetadataNodes(node);
410+ TreeNode[] treeNodes = node.getPath();
411+ TreePath path = new TreePath(treeNodes);
412+ if (isExpanded(path)) {
413+ addMetadataNodes(node);
414+ }
415+ }
416+ // Clear the current selection and set it
417+ // again so valueChanged() gets called
418+ if (node == getLastSelectedPathComponent()) {
419+ TreePath selectionPath = getSelectionPath();
420+ clearSelection();
421+ setSelectionPath(selectionPath);
422+ }
423+ }
424+
425+ /**
426+ * Creates the domain node.
427+ */
428+ private DefaultMutableTreeNode createDomainNode(Dn dn, Token token) {
429+ DefaultMutableTreeNode node = new ComparableDefaultMutableTreeNode();
430+ String label = dn.getDomain();
431+ XNodeInfo userObject =
432+ new XNodeInfo(Type.NONMBEAN, label, label, label);
433+ node.setUserObject(userObject);
434+ return node;
435+ }
436+
437+ /**
438+ * Creates the node corresponding to the whole Dn, i.e. an MBean.
439+ */
440+ private DefaultMutableTreeNode createDnNode(
441+ Dn dn, Token token, XMBean xmbean) {
442+ DefaultMutableTreeNode node = new ComparableDefaultMutableTreeNode();
443+ Object data = createNodeValue(xmbean, token);
444+ String label = data.toString();
445+ XNodeInfo userObject = new XNodeInfo(Type.MBEAN, data, label,
446+ xmbean.getObjectName().toString());
447+ node.setUserObject(userObject);
448+ return node;
449+ }
450+
451+ /**
452+ * Creates the node corresponding to a subDn, i.e. a non-MBean
453+ * intermediate node.
454+ */
455+ private DefaultMutableTreeNode createSubDnNode(Dn dn, Token token) {
456+ DefaultMutableTreeNode node = new ComparableDefaultMutableTreeNode();
457+ String label = isKeyValueView() ? token.getTokenValue() : token.getValue();
458+ XNodeInfo userObject =
459+ new XNodeInfo(Type.NONMBEAN, label, label, token.getTokenValue());
460+ node.setUserObject(userObject);
461+ return node;
462+ }
463+
464+ private Object createNodeValue(XMBean xmbean, Token token) {
465+ String label = isKeyValueView() ? token.getTokenValue() : token.getValue();
466+ xmbean.setText(label);
467+ return xmbean;
468+ }
469+
470+ /**
471+ * Parses the MBean ObjectName comma-separated properties string and puts
472+ * the individual key/value pairs into the map. Key order in the properties
473+ * string is preserved by the map.
474+ */
475+ private static Map<String, String> extractKeyValuePairs(
476+ String props, ObjectName mbean) {
477+ Map<String, String> map = new LinkedHashMap<String, String>();
478+ int eq = props.indexOf("=");
479+ while (eq != -1) {
480+ String key = props.substring(0, eq);
481+ String value = mbean.getKeyProperty(key);
482+ map.put(key, value);
483+ props = props.substring(key.length() + 1 + value.length());
484+ if (props.startsWith(",")) {
485+ props = props.substring(1);
486+ }
487+ eq = props.indexOf("=");
488+ }
489+ return map;
490+ }
491+
492+ /**
493+ * Returns the ordered key property list that will be used to build the
494+ * MBean tree. If the "com.sun.tools.jconsole.mbeans.keyPropertyList" system
495+ * property is not specified, then the ordered key property list used
496+ * to build the MBean tree will be the one returned by the method
497+ * ObjectName.getKeyPropertyListString() with "type" as first key,
498+ * and "j2eeType" as second key, if present. If any of the keys specified
499+ * in the comma-separated key property list does not apply to the given
500+ * MBean then it will be discarded.
501+ */
502+ private static String getKeyPropertyListString(ObjectName mbean) {
503+ String props = mbean.getKeyPropertyListString();
504+ Map<String, String> map = extractKeyValuePairs(props, mbean);
505+ StringBuilder sb = new StringBuilder();
506+ // Add the key/value pairs to the buffer following the
507+ // key order defined by the "orderedKeyPropertyList"
508+ for (String key : orderedKeyPropertyList) {
509+ if (map.containsKey(key)) {
510+ sb.append(key + "=" + map.get(key) + ",");
511+ map.remove(key);
512+ }
513+ }
514+ // Add the remaining key/value pairs to the buffer
515+ for (Map.Entry<String, String> entry : map.entrySet()) {
516+ sb.append(entry.getKey() + "=" + entry.getValue() + ",");
517+ }
518+ String orderedKeyPropertyListString = sb.toString();
519+ orderedKeyPropertyListString = orderedKeyPropertyListString.substring(
520+ 0, orderedKeyPropertyListString.length() - 1);
521+ return orderedKeyPropertyListString;
522+ }
523+
524+ // Call on EDT
525+ public void addMetadataNodes(DefaultMutableTreeNode node) {
526+ XMBean mbean = (XMBean) ((XNodeInfo) node.getUserObject()).getData();
527+ DefaultTreeModel model = (DefaultTreeModel) getModel();
528+ MBeanInfoNodesSwingWorker sw =
529+ new MBeanInfoNodesSwingWorker(model, node, mbean);
530+ if (sw != null) {
531+ sw.execute();
532+ }
533+ }
534+
535+ private static class MBeanInfoNodesSwingWorker
536+ extends SwingWorker<Object[], Void> {
537+
538+ private final DefaultTreeModel model;
539+ private final DefaultMutableTreeNode node;
540+ private final XMBean mbean;
541+
542+ public MBeanInfoNodesSwingWorker(
543+ DefaultTreeModel model,
544+ DefaultMutableTreeNode node,
545+ XMBean mbean) {
546+ this.model = model;
547+ this.node = node;
548+ this.mbean = mbean;
549+ }
550+
551+ @Override
552+ public Object[] doInBackground() throws InstanceNotFoundException,
553+ IntrospectionException, ReflectionException, IOException {
554+ Object result[] = new Object[2];
555+ // Retrieve MBeanInfo for this MBean
556+ result[0] = mbean.getMBeanInfo();
557+ // Check if this MBean is a notification emitter
558+ result[1] = mbean.isBroadcaster();
559+ return result;
560+ }
561+
562+ @Override
563+ protected void done() {
564+ try {
565+ Object result[] = get();
566+ MBeanInfo mbeanInfo = (MBeanInfo) result[0];
567+ Boolean isBroadcaster = (Boolean) result[1];
568+ if (mbeanInfo != null) {
569+ addMBeanInfoNodes(model, node, mbean, mbeanInfo, isBroadcaster);
570+ }
571+ } catch (Exception e) {
572+ Throwable t = Utils.getActualException(e);
573+ if (JConsole.isDebug()) {
574+ t.printStackTrace();
575+ }
576+ }
577+ }
578+
579+ // Call on EDT
580+ private void addMBeanInfoNodes(
581+ DefaultTreeModel tree, DefaultMutableTreeNode node,
582+ XMBean mbean, MBeanInfo mbeanInfo, Boolean isBroadcaster) {
583+ MBeanAttributeInfo[] ai = mbeanInfo.getAttributes();
584+ MBeanOperationInfo[] oi = mbeanInfo.getOperations();
585+ MBeanNotificationInfo[] ni = mbeanInfo.getNotifications();
586+
587+ // Insert the Attributes/Operations/Notifications metadata nodes as
588+ // the three first children of this MBean node. This is only useful
589+ // when this MBean node denotes an MBean but it's not a leaf in the
590+ // MBean tree
591+ //
592+ int childIndex = 0;
593+
594+ // MBeanAttributeInfo node
595+ //
596+ if (ai != null && ai.length > 0) {
597+ DefaultMutableTreeNode attributes = new DefaultMutableTreeNode();
598+ XNodeInfo attributesUO = new XNodeInfo(Type.ATTRIBUTES, mbean,
599+ Resources.getText("Attributes"), null);
600+ attributes.setUserObject(attributesUO);
601+ node.insert(attributes, childIndex++);
602+ for (MBeanAttributeInfo mbai : ai) {
603+ DefaultMutableTreeNode attribute = new DefaultMutableTreeNode();
604+ XNodeInfo attributeUO = new XNodeInfo(Type.ATTRIBUTE,
605+ new Object[]{mbean, mbai}, mbai.getName(), null);
606+ attribute.setUserObject(attributeUO);
607+ attribute.setAllowsChildren(false);
608+ attributes.add(attribute);
609+ }
610+ }
611+ // MBeanOperationInfo node
612+ //
613+ if (oi != null && oi.length > 0) {
614+ DefaultMutableTreeNode operations = new DefaultMutableTreeNode();
615+ XNodeInfo operationsUO = new XNodeInfo(Type.OPERATIONS, mbean,
616+ Resources.getText("Operations"), null);
617+ operations.setUserObject(operationsUO);
618+ node.insert(operations, childIndex++);
619+ for (MBeanOperationInfo mboi : oi) {
620+ // Compute the operation's tool tip text:
621+ // "operationname(param1type,param2type,...)"
622+ //
623+ StringBuilder sb = new StringBuilder();
624+ for (MBeanParameterInfo mbpi : mboi.getSignature()) {
625+ sb.append(mbpi.getType() + ",");
626+ }
627+ String signature = sb.toString();
628+ if (signature.length() > 0) {
629+ // Remove the trailing ','
630+ //
631+ signature = signature.substring(0, signature.length() - 1);
632+ }
633+ String toolTipText = mboi.getName() + "(" + signature + ")";
634+ // Create operation node
635+ //
636+ DefaultMutableTreeNode operation = new DefaultMutableTreeNode();
637+ XNodeInfo operationUO = new XNodeInfo(Type.OPERATION,
638+ new Object[]{mbean, mboi}, mboi.getName(), toolTipText);
639+ operation.setUserObject(operationUO);
640+ operation.setAllowsChildren(false);
641+ operations.add(operation);
642+ }
643+ }
644+ // MBeanNotificationInfo node
645+ //
646+ if (isBroadcaster != null && isBroadcaster.booleanValue()) {
647+ DefaultMutableTreeNode notifications = new DefaultMutableTreeNode();
648+ XNodeInfo notificationsUO = new XNodeInfo(Type.NOTIFICATIONS, mbean,
649+ Resources.getText("Notifications"), null);
650+ notifications.setUserObject(notificationsUO);
651+ node.insert(notifications, childIndex++);
652+ if (ni != null && ni.length > 0) {
653+ for (MBeanNotificationInfo mbni : ni) {
654+ DefaultMutableTreeNode notification =
655+ new DefaultMutableTreeNode();
656+ XNodeInfo notificationUO = new XNodeInfo(Type.NOTIFICATION,
657+ mbni, mbni.getName(), null);
658+ notification.setUserObject(notificationUO);
659+ notification.setAllowsChildren(false);
660+ notifications.add(notification);
661+ }
662+ }
663+ }
664+ // Update tree model
665+ //
666+ model.reload(node);
667+ }
668+ }
669+ //
670+ // Tree preferences
671+ //
672+ private static boolean treeView;
673+ private static boolean treeViewInit = false;
674+
675+ private static boolean isTreeView() {
676+ if (!treeViewInit) {
677+ treeView = getTreeViewValue();
678+ treeViewInit = true;
679+ }
680+ return treeView;
681+ }
682+
683+ private static boolean getTreeViewValue() {
684+ String tv = System.getProperty("treeView");
685+ return ((tv == null) ? true : !(tv.equals("false")));
686+ }
687+ //
688+ // MBean key-value preferences
689+ //
690+ private boolean keyValueView = Boolean.getBoolean("keyValueView");
691+
692+ private boolean isKeyValueView() {
693+ return keyValueView;
694+ }
695+
696+ //
697+ // Utility classes
698+ //
699+ private static class ComparableDefaultMutableTreeNode
700+ extends DefaultMutableTreeNode
701+ implements Comparable<DefaultMutableTreeNode> {
702+
703+ public int compareTo(DefaultMutableTreeNode node) {
704+ return (this.toString().compareTo(node.toString()));
705+ }
706+ }
707+
708+ private static class Dn implements Comparable<Dn> {
709+
710+ private ObjectName mbean;
711+ private String domain;
712+ private String keyPropertyList;
713+ private String hashDn;
714+ private List<Token> tokens = new ArrayList<Token>();
715+
716+ public Dn(ObjectName mbean) {
717+ this.mbean = mbean;
718+ this.domain = mbean.getDomain();
719+ this.keyPropertyList = getKeyPropertyListString(mbean);
720+
721+ if (isTreeView()) {
722+ // Tree view
723+ Map<String, String> map =
724+ extractKeyValuePairs(keyPropertyList, mbean);
725+ for (Map.Entry<String, String> entry : map.entrySet()) {
726+ tokens.add(new Token("key", entry.getKey() + "=" + entry.getValue()));
727+ }
728+ } else {
729+ // Flat view
730+ tokens.add(new Token("key", "properties=" + keyPropertyList));
731+ }
732+
733+ // Add the domain as the first token in the Dn
734+ tokens.add(0, new Token("domain", "domain=" + domain));
735+
736+ // Reverse the Dn (from leaf to root)
737+ Collections.reverse(tokens);
738+
739+ // Compute hash for Dn
740+ computeHashDn();
741+ }
742+
743+ public ObjectName getObjectName() {
744+ return mbean;
745+ }
746+
747+ public String getDomain() {
748+ return domain;
749+ }
750+
751+ public String getKeyPropertyList() {
752+ return keyPropertyList;
753+ }
754+
755+ public Token getToken(int index) {
756+ return tokens.get(index);
757+ }
758+
759+ public int getTokenCount() {
760+ return tokens.size();
761+ }
762+
763+ public String getHashDn() {
764+ return hashDn;
765+ }
766+
767+ public String getHashKey(Token token) {
768+ final int begin = hashDn.indexOf(token.getTokenValue());
769+ return hashDn.substring(begin, hashDn.length());
770+ }
771+
772+ private void computeHashDn() {
773+ if (tokens.isEmpty()) {
774+ return;
775+ }
776+ final StringBuilder hdn = new StringBuilder();
777+ for (int i = 0; i < tokens.size(); i++) {
778+ hdn.append(tokens.get(i).getTokenValue());
779+ hdn.append(",");
780+ }
781+ hashDn = hdn.substring(0, hdn.length() - 1);
782+ }
783+
784+ @Override
785+ public String toString() {
786+ return domain + ":" + keyPropertyList;
787+ }
788+
789+ public int compareTo(Dn dn) {
790+ return this.toString().compareTo(dn.toString());
791+ }
792+ }
793+
794+ private static class Token {
795+
796+ private String tokenType;
797+ private String tokenValue;
798+ private String key;
799+ private String value;
800+
801+ public Token(String tokenType, String tokenValue) {
802+ this.tokenType = tokenType;
803+ this.tokenValue = tokenValue;
804+ buildKeyValue();
805+ }
806+
807+ public String getTokenType() {
808+ return tokenType;
809+ }
810+
811+ public String getTokenValue() {
812+ return tokenValue;
813+ }
814+
815+ public String getKey() {
816+ return key;
817+ }
818+
819+ public String getValue() {
820+ return value;
821+ }
822+
823+ private void buildKeyValue() {
824+ int index = tokenValue.indexOf("=");
825+ if (index < 0) {
826+ key = tokenValue;
827+ value = tokenValue;
828+ } else {
829+ key = tokenValue.substring(0, index);
830+ value = tokenValue.substring(index + 1, tokenValue.length());
831+ }
832+ }
833+ }
834+}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t