1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.monitoring.reporting.web.plugin.jmx;
18
19 import org.apache.commons.codec.binary.Base64;
20 import org.apache.commons.lang3.StringEscapeUtils;
21
22 import java.util.Collection;
23 import java.util.Collections;
24 import java.util.Comparator;
25 import java.util.Map;
26 import java.util.TreeMap;
27
28 public class JMXNode {
29 private final String name;
30 private final Map<Key, JMXNode> children = new TreeMap<Key, JMXNode>();
31 private String base64 = null;
32
33 public JMXNode(final String name) {
34 this.name = name;
35 }
36
37 public static void addNode(final JMXNode rootNode, final String domain, final String props) {
38 final Map<String, String> properties = new TreeMap<String, String>(new JMXPropertiesComparator(props));
39 for (final String k : props.split(",")) {
40 final String[] kv = k.split("=");
41 if (kv.length < 2) {
42 properties.put(StringEscapeUtils.escapeHtml4(kv[0]), "");
43 } else {
44 properties.put(StringEscapeUtils.escapeHtml4(kv[0]), StringEscapeUtils.escapeHtml4(kv[1]));
45 }
46 }
47
48 final Key rootKey = new Key("domain", domain);
49 JMXNode node = rootNode.children.get(rootKey);
50 if (node == null) {
51 node = new JMXNode(domain);
52 rootNode.children.put(rootKey, node);
53 }
54
55 for (final Map.Entry<String, String> entry : properties.entrySet()) {
56 final Key key = new Key(entry.getKey(), entry.getValue());
57 final String value = entry.getValue();
58
59 JMXNode child = node.children.get(key);
60 if (child == null) {
61 child = new JMXNode(value);
62 node.children.put(key, child);
63 }
64
65 node = child;
66 }
67
68 node.base64 = Base64.encodeBase64String((domain + ":" + props).getBytes());
69 }
70
71 public String getName() {
72 return name;
73 }
74
75 public boolean isLeaf() {
76 return base64 != null;
77 }
78
79 public String getBase64() {
80 return base64;
81 }
82
83 public Collection<JMXNode> getChildren() {
84 return Collections.unmodifiableCollection(children.values());
85 }
86
87 protected static class Key implements Comparable<Key> {
88 private final String key;
89 private final String value;
90
91 public Key(final String key, final String value) {
92 this.key = key;
93 this.value = value;
94 }
95
96 @Override
97 public boolean equals(final Object o) {
98 if (this == o) {
99 return true;
100 }
101 if (o == null || Key.class != o.getClass()) {
102 return false;
103 }
104
105 final Key key1 = Key.class.cast(o);
106 return key.equals(key1.key) && value.equals(key1.value);
107 }
108
109 @Override
110 public int hashCode() {
111 int result = key.hashCode();
112 result = 31 * result + value.hashCode();
113 return result;
114 }
115
116 @Override
117 public int compareTo(final Key o) {
118 if (equals(o)) {
119 return 0;
120 }
121
122 final int keys = key.compareTo(o.key);
123 if (keys != 0) {
124 return keys;
125 }
126 return value.compareTo(o.value);
127 }
128
129 @Override
130 public String toString() {
131 return "{" + key + " = " + value + '}';
132 }
133 }
134
135 protected static class JMXPropertiesComparator implements Comparator<String> {
136 private final String properties;
137
138 protected JMXPropertiesComparator(final String props) {
139 properties = props;
140 }
141
142 @Override
143 public int compare(final String o1, final String o2) {
144 if (o1.equals(o2)) {
145 return 0;
146 }
147
148 if ("type".equals(o1)) {
149 return -1;
150 }
151 if ("type".equals(o2)) {
152 return 1;
153 }
154 if ("j2eeType".equals(o1)) {
155 return -1;
156 }
157 if ("j2eeType".equals(o2)) {
158 return 1;
159 }
160
161 return properties.indexOf(o1 + "=") - properties.indexOf(o2 + "=");
162 }
163 }
164 }