1. /*
  2. * @(#)file SnmpMibTree.java
  3. * @(#)author Sun Microsystems, Inc.
  4. * @(#)version 4.7
  5. * @(#)date 01/02/09
  6. *
  7. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  8. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  9. *
  10. */
  11. package com.sun.jmx.snmp.daemon;
  12. // java imports
  13. //
  14. import java.util.Vector;
  15. import java.util.Enumeration;
  16. // jmx imports
  17. //
  18. import com.sun.jmx.snmp.SnmpOid;
  19. // SNMP Runtime imports
  20. //
  21. import com.sun.jmx.snmp.agent.SnmpMibAgent;
  22. /**
  23. * The class is used for building a tree representation of the different
  24. * root oids of the supported MIBs. Each node is associated to a specific MIB.
  25. */
  26. final class SnmpMibTree {
  27. public SnmpMibTree() {
  28. defaultAgent= null;
  29. root= new TreeNode(-1, null, null);
  30. }
  31. public void setDefaultAgent(SnmpMibAgent def) {
  32. defaultAgent= def;
  33. root.agent= def;
  34. }
  35. public SnmpMibAgent getDefaultAgent() {
  36. return defaultAgent;
  37. }
  38. public void register(SnmpMibAgent agent) {
  39. root.registerNode(agent);
  40. }
  41. public void register(SnmpMibAgent agent, long[] oid) {
  42. root.registerNode(oid, 0, agent);
  43. }
  44. public SnmpMibAgent getAgentMib(SnmpOid oid) {
  45. TreeNode node= root.retrieveMatchingBranch(oid.longValue(), 0);
  46. if (node == null)
  47. return defaultAgent;
  48. else
  49. if(node.getAgentMib() == null)
  50. return defaultAgent;
  51. else
  52. return node.getAgentMib();
  53. }
  54. public void unregister(SnmpMibAgent agent, SnmpOid[] oids) {
  55. for(int i = 0; i < oids.length; i++) {
  56. long[] oid = oids[i].longValue();
  57. TreeNode node = root.retrieveMatchingBranch(oid, 0);
  58. if (node == null)
  59. continue;
  60. node.removeAgent(agent);
  61. }
  62. }
  63. public void unregister(SnmpMibAgent agent) {
  64. root.removeAgentFully(agent);
  65. }
  66. /*
  67. public void unregister(SnmpMibAgent agent) {
  68. long[] oid= agent.getRootOid();
  69. TreeNode node= root.retrieveMatchingBranch(oid, 0);
  70. if (node == null)
  71. return;
  72. node.removeAgent(agent);
  73. }
  74. */
  75. public void printTree() {
  76. root.printTree(">");
  77. }
  78. private SnmpMibAgent defaultAgent;
  79. private TreeNode root;
  80. // A SnmpMibTree object is a tree of TreeNode
  81. //
  82. final class TreeNode {
  83. void registerNode(SnmpMibAgent agent) {
  84. long[] oid= agent.getRootOid();
  85. registerNode(oid, 0, agent);
  86. }
  87. TreeNode retrieveMatchingBranch(long[] oid, int cursor) {
  88. TreeNode node= retrieveChild(oid, cursor);
  89. if (node == null)
  90. return this;
  91. if (children.size() == 0) {
  92. // In this case, the node does not have any children. So no point to
  93. // continue the search ...
  94. return node;
  95. }
  96. if( cursor + 1 == oid.length) {
  97. // In this case, the oid does not have any more element. So the search
  98. // is over.
  99. return node;
  100. }
  101. TreeNode n = node.retrieveMatchingBranch(oid, cursor + 1);
  102. //If the returned node got a null agent, we have to replace it by
  103. //the current one (in case it is not null)
  104. //
  105. return n.agent == null ? this : n;
  106. }
  107. SnmpMibAgent getAgentMib() {
  108. return agent;
  109. }
  110. public void printTree(String ident) {
  111. StringBuffer buff= new StringBuffer();
  112. if (agents == null) {
  113. return;
  114. }
  115. for(Enumeration e= agents.elements(); e.hasMoreElements(); ) {
  116. SnmpMibAgent mib= (SnmpMibAgent) e.nextElement();
  117. if (mib == null)
  118. buff.append("empty ");
  119. else
  120. buff.append(mib.getMibName() + " ");
  121. }
  122. ident+= " ";
  123. if (children == null) {
  124. return;
  125. }
  126. for(Enumeration e= children.elements(); e.hasMoreElements(); ) {
  127. TreeNode node= (TreeNode) e.nextElement();
  128. node.printTree(ident);
  129. }
  130. }
  131. // PRIVATE STUFF
  132. //--------------
  133. /**
  134. * Only the treeNode class can create an instance of treeNode.
  135. * The creation occurs when registering a new oid.
  136. */
  137. private TreeNode(long nodeValue, SnmpMibAgent agent, TreeNode sup) {
  138. this.nodeValue= nodeValue;
  139. this.parent= sup;
  140. agents.addElement(agent);
  141. }
  142. private void removeAgentFully(SnmpMibAgent agent) {
  143. Vector v = new Vector();
  144. for(Enumeration e= children.elements(); e.hasMoreElements(); ) {
  145. TreeNode node= (TreeNode) e.nextElement();
  146. node.removeAgentFully(agent);
  147. if(node.agents.isEmpty())
  148. v.add(node);
  149. }
  150. for(Enumeration e= v.elements(); e.hasMoreElements(); ) {
  151. children.removeElement(e.nextElement());
  152. }
  153. removeAgent(agent);
  154. }
  155. private void removeAgent(SnmpMibAgent mib) {
  156. if (!agents.contains(mib))
  157. return;
  158. agents.removeElement(mib);
  159. if (!agents.isEmpty())
  160. agent= (SnmpMibAgent)agents.firstElement();
  161. }
  162. private void setAgent(SnmpMibAgent agent) {
  163. this.agent = agent;
  164. }
  165. private void registerNode(long[] oid, int cursor, SnmpMibAgent agent) {
  166. if (cursor >= oid.length)
  167. //That's it !
  168. //
  169. return;
  170. TreeNode child = retrieveChild(oid, cursor);
  171. if (child == null) {
  172. // Create a child and register it !
  173. //
  174. long theValue= oid[cursor];
  175. child= new TreeNode(theValue, agent, this);
  176. children.addElement(child);
  177. }
  178. else
  179. if (agents.contains(agent) == false) {
  180. agents.addElement(agent);
  181. }
  182. // We have to set the agent attribute
  183. //
  184. if(cursor == (oid.length - 1)) {
  185. child.setAgent(agent);
  186. }
  187. else
  188. child.registerNode(oid, cursor+1, agent);
  189. }
  190. private TreeNode retrieveChild(long[] oid, int current) {
  191. long theValue= oid[current];
  192. for(Enumeration e= children.elements(); e.hasMoreElements(); ) {
  193. TreeNode node= (TreeNode) e.nextElement();
  194. if (node.match(theValue))
  195. return node;
  196. }
  197. return null;
  198. }
  199. final private boolean match(long value) {
  200. return (nodeValue == value) ? true : false;
  201. }
  202. private Vector children= new Vector();
  203. private Vector agents= new Vector();
  204. private long nodeValue;
  205. protected SnmpMibAgent agent;
  206. private TreeNode parent;
  207. }; // end of class TreeNode
  208. }