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
26package sun.tools.jconsole.inspector;
27
28import java.io.IOException;
29import java.util.*;
30import javax.management.*;
31import javax.swing.*;
32import javax.swing.tree.*;
33import sun.tools.jconsole.JConsole;
34import sun.tools.jconsole.MBeansTab;
35import sun.tools.jconsole.Resources;
36import sun.tools.jconsole.inspector.XNodeInfo;
37import static sun.tools.jconsole.inspector.XNodeInfo.Type;
38
39@SuppressWarnings("serial")
40public 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