1 /* 2 * Copyright (c) 1998, 2012, 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 27 package com.sun.jmx.snmp.daemon; 28 29 30 31 // java imports 32 // 33 import java.util.Vector; 34 import java.util.Enumeration; 35 36 // jmx imports 37 // 38 import com.sun.jmx.snmp.SnmpOid; 39 40 // SNMP Runtime imports 41 // 42 import com.sun.jmx.snmp.agent.SnmpMibAgent; 43 44 /** 45 * The class is used for building a tree representation of the different 46 * root oids of the supported MIBs. Each node is associated to a specific MIB. 47 */ 48 final class SnmpMibTree { 49 50 public SnmpMibTree() { 51 defaultAgent= null; 52 root= new TreeNode(-1, null, null); 53 } 54 55 public void setDefaultAgent(SnmpMibAgent def) { 56 defaultAgent= def; 57 root.agent= def; 58 } 59 60 public SnmpMibAgent getDefaultAgent() { 61 return defaultAgent; 62 } 63 64 public void register(SnmpMibAgent agent) { 65 root.registerNode(agent); 66 } 67 68 public void register(SnmpMibAgent agent, long[] oid) { 69 root.registerNode(oid, 0, agent); 70 } 71 72 public SnmpMibAgent getAgentMib(SnmpOid oid) { 73 TreeNode node= root.retrieveMatchingBranch(oid.longValue(), 0); 74 if (node == null) 75 return defaultAgent; 76 else 77 if(node.getAgentMib() == null) 78 return defaultAgent; 79 else 80 return node.getAgentMib(); 81 } 82 83 public void unregister(SnmpMibAgent agent, SnmpOid[] oids) { 84 for(int i = 0; i < oids.length; i++) { 85 long[] oid = oids[i].longValue(); 86 TreeNode node = root.retrieveMatchingBranch(oid, 0); 87 if (node == null) 88 continue; 89 node.removeAgent(agent); 90 } 91 } 92 93 94 public void unregister(SnmpMibAgent agent) { 95 96 root.removeAgentFully(agent); 97 } 98 99 /* 100 public void unregister(SnmpMibAgent agent) { 101 long[] oid= agent.getRootOid(); 102 TreeNode node= root.retrieveMatchingBranch(oid, 0); 103 if (node == null) 104 return; 105 node.removeAgent(agent); 106 } 107 */ 108 public void printTree() { 109 root.printTree(">"); 110 } 111 112 private SnmpMibAgent defaultAgent; 113 private TreeNode root; 114 115 // A SnmpMibTree object is a tree of TreeNode 116 // 117 final class TreeNode { 118 119 void registerNode(SnmpMibAgent agent) { 120 long[] oid= agent.getRootOid(); 121 registerNode(oid, 0, agent); 122 } 123 124 TreeNode retrieveMatchingBranch(long[] oid, int cursor) { 125 TreeNode node= retrieveChild(oid, cursor); 126 if (node == null) 127 return this; 128 if (children.isEmpty()) { 129 // In this case, the node does not have any children. So no point to 130 // continue the search ... 131 return node; 132 } 133 if( cursor + 1 == oid.length) { 134 // In this case, the oid does not have any more element. So the search 135 // is over. 136 return node; 137 } 138 139 TreeNode n = node.retrieveMatchingBranch(oid, cursor + 1); 140 //If the returned node got a null agent, we have to replace it by 141 //the current one (in case it is not null) 142 // 143 return n.agent == null ? this : n; 144 } 145 146 SnmpMibAgent getAgentMib() { 147 return agent; 148 } 149 150 public void printTree(String ident) { 151 152 StringBuilder buff= new StringBuilder(); 153 if (agents == null) { 154 return; 155 } 156 157 for(Enumeration<SnmpMibAgent> e= agents.elements(); e.hasMoreElements(); ) { 158 SnmpMibAgent mib= e.nextElement(); 159 if (mib == null) 160 buff.append("empty "); 161 else 162 buff.append(mib.getMibName()).append(" "); 163 } 164 ident+= " "; 165 if (children == null) { 166 return; 167 } 168 for(Enumeration<TreeNode> e= children.elements(); e.hasMoreElements(); ) { 169 TreeNode node= e.nextElement(); 170 node.printTree(ident); 171 } 172 } 173 174 // PRIVATE STUFF 175 //-------------- 176 177 /** 178 * Only the treeNode class can create an instance of treeNode. 179 * The creation occurs when registering a new oid. 180 */ 181 private TreeNode(long nodeValue, SnmpMibAgent agent, TreeNode sup) { 182 this.nodeValue= nodeValue; 183 this.parent= sup; 184 agents.addElement(agent); 185 } 186 187 private void removeAgentFully(SnmpMibAgent agent) { 188 Vector<TreeNode> v = new Vector<>(); 189 for(Enumeration<TreeNode> e= children.elements(); 190 e.hasMoreElements(); ) { 191 192 TreeNode node= e.nextElement(); 193 node.removeAgentFully(agent); 194 if(node.agents.isEmpty()) 195 v.add(node); 196 197 } 198 for(Enumeration<TreeNode> e= v.elements(); e.hasMoreElements(); ) { 199 children.removeElement(e.nextElement()); 200 } 201 removeAgent(agent); 202 203 } 204 205 private void removeAgent(SnmpMibAgent mib) { 206 if (!agents.contains(mib)) 207 return; 208 agents.removeElement(mib); 209 210 if (!agents.isEmpty()) 211 agent= agents.firstElement(); 212 213 } 214 215 private void setAgent(SnmpMibAgent agent) { 216 this.agent = agent; 217 } 218 219 private void registerNode(long[] oid, int cursor, SnmpMibAgent agent) { 220 221 if (cursor >= oid.length) 222 //That's it ! 223 // 224 return; 225 TreeNode child = retrieveChild(oid, cursor); 226 if (child == null) { 227 // Create a child and register it ! 228 // 229 long theValue= oid[cursor]; 230 child= new TreeNode(theValue, agent, this); 231 children.addElement(child); 232 } 233 else 234 if (agents.contains(agent) == false) { 235 agents.addElement(agent); 236 } 237 238 // We have to set the agent attribute 239 // 240 if(cursor == (oid.length - 1)) { 241 child.setAgent(agent); 242 } 243 else 244 child.registerNode(oid, cursor+1, agent); 245 } 246 247 private TreeNode retrieveChild(long[] oid, int current) { 248 long theValue= oid[current]; 249 250 for(Enumeration<TreeNode> e= children.elements(); e.hasMoreElements(); ) { 251 TreeNode node= e.nextElement(); 252 if (node.match(theValue)) 253 return node; 254 } 255 return null; 256 } 257 258 private boolean match(long value) { 259 return (nodeValue == value) ? true : false; 260 } 261 262 private Vector<TreeNode> children= new Vector<>(); 263 private Vector<SnmpMibAgent> agents= new Vector<>(); 264 private long nodeValue; 265 private SnmpMibAgent agent; 266 private TreeNode parent; 267 268 }; // end of class TreeNode 269 }