001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.commons.monitoring.reporting.web.plugin.jmx; 018 019 import org.apache.commons.codec.binary.Base64; 020 import org.apache.commons.lang3.StringEscapeUtils; 021 022 import java.util.Collection; 023 import java.util.Collections; 024 import java.util.Comparator; 025 import java.util.Map; 026 import java.util.TreeMap; 027 028 public class JMXNode { 029 private final String name; 030 private final Map<Key, JMXNode> children = new TreeMap<Key, JMXNode>(); 031 private String base64 = null; 032 033 public JMXNode(final String name) { 034 this.name = name; 035 } 036 037 public static void addNode(final JMXNode rootNode, final String domain, final String props) { 038 final Map<String, String> properties = new TreeMap<String, String>(new JMXPropertiesComparator(props)); 039 for (final String k : props.split(",")) { 040 final String[] kv = k.split("="); 041 if (kv.length < 2) { 042 properties.put(StringEscapeUtils.escapeHtml4(kv[0]), ""); 043 } else { 044 properties.put(StringEscapeUtils.escapeHtml4(kv[0]), StringEscapeUtils.escapeHtml4(kv[1])); 045 } 046 } 047 048 final Key rootKey = new Key("domain", domain); 049 JMXNode node = rootNode.children.get(rootKey); 050 if (node == null) { 051 node = new JMXNode(domain); 052 rootNode.children.put(rootKey, node); 053 } 054 055 for (final Map.Entry<String, String> entry : properties.entrySet()) { 056 final Key key = new Key(entry.getKey(), entry.getValue()); 057 final String value = entry.getValue(); 058 059 JMXNode child = node.children.get(key); 060 if (child == null) { 061 child = new JMXNode(value); 062 node.children.put(key, child); 063 } 064 065 node = child; 066 } 067 068 node.base64 = Base64.encodeBase64String((domain + ":" + props).getBytes()); 069 } 070 071 public String getName() { 072 return name; 073 } 074 075 public boolean isLeaf() { 076 return base64 != null; 077 } 078 079 public String getBase64() { 080 return base64; 081 } 082 083 public Collection<JMXNode> getChildren() { 084 return Collections.unmodifiableCollection(children.values()); 085 } 086 087 protected static class Key implements Comparable<Key> { 088 private final String key; 089 private final String value; 090 091 public Key(final String key, final String value) { 092 this.key = key; 093 this.value = value; 094 } 095 096 @Override 097 public boolean equals(final Object o) { 098 if (this == o) { 099 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 }