1. /*
  2. * @(#)file SnmpMibNode.java
  3. * @(#)author Sun Microsystems, Inc.
  4. * @(#)version 4.20
  5. * @(#)date 04/09/15
  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.agent;
  12. // java imports
  13. //
  14. import java.io.Serializable;
  15. import java.util.Vector;
  16. import java.util.Hashtable;
  17. import java.util.Enumeration;
  18. // jmx imports
  19. //
  20. import com.sun.jmx.snmp.SnmpOid;
  21. import com.sun.jmx.snmp.SnmpValue;
  22. import com.sun.jmx.snmp.SnmpVarBind;
  23. import com.sun.jmx.snmp.SnmpDefinitions;
  24. import com.sun.jmx.snmp.SnmpStatusException;
  25. /**
  26. * The <CODE>SnmpMibNode</CODE> class represents a node in an SNMP MIB.
  27. * <P>
  28. * This class is used internally and by the class generated by
  29. * <CODE>mibgen</CODE>.
  30. * You should not need to use this class directly.
  31. *
  32. * <p><b>This API is a Sun Microsystems internal API and is subject
  33. * to change without notice.</b></p>
  34. * @version 4.20 12/19/03
  35. * @author Sun Microsystems, Inc
  36. */
  37. public abstract class SnmpMibNode implements Serializable {
  38. // ---------------------------------------------------------------------
  39. // PUBLIC METHODS
  40. //----------------------------------------------------------------------
  41. /**
  42. * Get the next OID arc corresponding to a readable scalar variable,
  43. * a branch leading to a subgroub, or a table.
  44. *
  45. * @param id Id we start from looking for the next.
  46. * @param userData A contextual object containing user-data.
  47. * This object is allocated through the <code>
  48. * {@link com.sun.jmx.snmp.agent.SnmpUserDataFactory}</code>
  49. * for each incoming SNMP request.
  50. *
  51. * @return The next id in this group.
  52. *
  53. * @exception SnmpStatusException If no id is found after the given id.
  54. */
  55. public long getNextVarId(long id, Object userData)
  56. throws SnmpStatusException {
  57. return getNextIdentifier(varList,id);
  58. }
  59. /**
  60. * Get the next OID arc corresponding to a readable scalar variable,
  61. * a branch leading to a subgroub, or a table, possibly skipping over
  62. * those arcs that must not or cannot be returned.
  63. *
  64. * Calls {@link #getNextVarId(long,java.lang.Object)} until
  65. * {@link #skipVariable(long,java.lang.Object,int)} returns false.
  66. *
  67. * @param id Id we start from looking for the next.
  68. * @param userData A contextual object containing user-data.
  69. * This object is allocated through the <code>
  70. * {@link com.sun.jmx.snmp.agent.SnmpUserDataFactory}</code>
  71. * for each incoming SNMP request.
  72. * @param pduVersion Protocol version of the original request PDU.
  73. *
  74. * @return The next id in this group which can be returned using
  75. * the given PDU's protocol version.
  76. *
  77. * @exception SnmpStatusException If no id is found after the given id.
  78. */
  79. public long getNextVarId(long id, Object userData, int pduVersion)
  80. throws SnmpStatusException {
  81. long varid=id;
  82. do {
  83. varid = getNextVarId(varid,userData);
  84. } while (skipVariable(varid,userData,pduVersion));
  85. return varid;
  86. }
  87. /**
  88. * Hook for subclasses.
  89. * The default implementation of this method is to always return
  90. * false. Subclasses should redefine this method so that it returns
  91. * true when:
  92. * <ul><li>the variable is a leaf that is not instantiated,</li>
  93. * <li>or the variable is a leaf whose type cannot be returned by that
  94. * version of the protocol (e.g. an Counter64 with SNMPv1).</li>
  95. * </ul>
  96. *
  97. * @param id Id we start from looking for the next.
  98. * @param userData A contextual object containing user-data.
  99. * This object is allocated through the <code>
  100. * {@link com.sun.jmx.snmp.agent.SnmpUserDataFactory}</code>
  101. * for each incoming SNMP request.
  102. * @param pduVersion Protocol version of the original request PDU.
  103. *
  104. * @return true if the variable must be skipped by the get-next
  105. * algorithm.
  106. */
  107. protected boolean skipVariable(long id, Object userData, int pduVersion) {
  108. return false;
  109. }
  110. /**
  111. * Find the node which handles a varbind, and register it in the
  112. * SnmpRequestTree. This method is a pure internal method. You should
  113. * never try to call it directly.
  114. *
  115. * @param varbind The varbind to be handled
  116. *
  117. * @param oid The OID array extracted from the varbind
  118. *
  119. * @param depth The depth reached in the OID at this step of the
  120. * processing.
  121. *
  122. * @param handlers The Hashtable in which the varbind will be registered
  123. * with its handling node. This hashtable contains
  124. * <CODE>SnmpRequestTree.Handler</CODE> items.
  125. *
  126. * @exception SnmpStatusException No handling node was found.
  127. **/
  128. void findHandlingNode(SnmpVarBind varbind,
  129. long[] oid, int depth,
  130. SnmpRequestTree handlers)
  131. throws SnmpStatusException {
  132. throw noSuchObjectException;
  133. }
  134. /**
  135. * Find the node which handles the leaf that immediately follows the
  136. * given varbind OID, and register the it in the SnmpRequestTree.
  137. * This method is a pure internal method. You should never try to call
  138. * it directly.
  139. *
  140. * @param varbind The varbind to be handled
  141. *
  142. * @param oid The OID array extracted from the varbind
  143. *
  144. * @param depth The depth reached in the OID at this step of the
  145. * processing.
  146. *
  147. * @param handlers The Hashtable in which the varbind will be registered
  148. * with its handling node. This hashtable contains
  149. * SnmpRequestTree.Handler items.
  150. *
  151. * @return The SnmpOid of the next leaf.
  152. *
  153. * @exception SnmpStatusException No handling node was found.
  154. **/
  155. long[] findNextHandlingNode(SnmpVarBind varbind,
  156. long[] oid, int pos, int depth,
  157. SnmpRequestTree handlers, AcmChecker checker)
  158. throws SnmpStatusException {
  159. throw noSuchObjectException;
  160. }
  161. /**
  162. * Generic handling of the <CODE>get</CODE> operation.
  163. *
  164. * <p> You can override this method if you need to implement some
  165. * specific policies for minimizing the accesses made to some remote
  166. * underlying resources.
  167. * <p>
  168. *
  169. * @param req The sub-request that must be handled by this node.
  170. *
  171. * @param depth The depth reached in the OID tree.
  172. *
  173. * @exception SnmpStatusException An error occurred while accessing
  174. * the MIB node.
  175. */
  176. public abstract void get(SnmpMibSubRequest req, int depth)
  177. throws SnmpStatusException;
  178. /**
  179. * Generic handling of the <CODE>set</CODE> operation.
  180. * <p> You can override this method if you need to implement some
  181. * specific policies for minimizing the accesses made to some remote
  182. * underlying resources.
  183. * <p>
  184. *
  185. * @param req The sub-request that must be handled by this node.
  186. *
  187. * @param depth The depth reached in the OID tree.
  188. *
  189. * @exception SnmpStatusException An error occurred while accessing
  190. * the MIB node.
  191. */
  192. public abstract void set(SnmpMibSubRequest req, int depth)
  193. throws SnmpStatusException;
  194. /**
  195. * Generic handling of the <CODE>check</CODE> operation.
  196. * <p> You can override this method if you need to implement some
  197. * specific policies for minimizing the accesses made to some remote
  198. * underlying resources, or if you need to implement some consistency
  199. * checks between the different values provided in the varbind list.
  200. * <p>
  201. *
  202. * @param req The sub-request that must be handled by this node.
  203. *
  204. * @param depth The depth reached in the OID tree.
  205. *
  206. * @exception SnmpStatusException An error occurred while accessing
  207. * the MIB node.
  208. */
  209. public abstract void check(SnmpMibSubRequest req, int depth)
  210. throws SnmpStatusException;
  211. /**
  212. * Sorts the specified integer array.
  213. *
  214. * @param array An integer array.
  215. */
  216. static public void sort(int array[]) {
  217. QuickSort(array, 0, array.length - 1);
  218. }
  219. /**
  220. * Computes the root OID of the MIB.
  221. */
  222. public void getRootOid(Vector result) {
  223. return;
  224. }
  225. //----------------------------------------------------------------------
  226. // PACKAGE METHODS
  227. //----------------------------------------------------------------------
  228. /**
  229. * This is a generic version of C.A.R Hoare's Quick Sort
  230. * algorithm. This will handle arrays that are already
  231. * sorted, and arrays with duplicate keys.
  232. *
  233. * If you think of a one dimensional array as going from
  234. * the lowest index on the left to the highest index on the right
  235. * then the parameters to this function are lowest index or
  236. * left and highest index or right. The first time you call
  237. * this function it will be with the parameters 0, a.length - 1.
  238. *
  239. * @param a An integer array.
  240. * @param lo0 Left boundary of array partition.
  241. * @param hi0 Right boundary of array partition.
  242. */
  243. static void QuickSort(int a[], int lo0, int hi0) {
  244. int lo = lo0;
  245. int hi = hi0;
  246. int mid;
  247. if ( hi0 > lo0) {
  248. /* Arbitrarily establishing partition element as the midpoint of
  249. * the array.
  250. */
  251. mid = a[ ( lo0 + hi0 ) / 2 ];
  252. // loop through the array until indices cross
  253. while( lo <= hi ) {
  254. /* find the first element that is greater than or equal to
  255. * the partition element starting from the left Index.
  256. */
  257. while( ( lo < hi0 ) && ( a[lo] < mid ))
  258. ++lo;
  259. /* find an element that is smaller than or equal to
  260. * the partition element starting from the right Index.
  261. */
  262. while( ( hi > lo0 ) && ( a[hi] > mid ))
  263. --hi;
  264. // if the indexes have not crossed, swap
  265. if( lo <= hi ) {
  266. swap(a, lo, hi);
  267. ++lo;
  268. --hi;
  269. }
  270. }
  271. /* If the right index has not reached the left side of array
  272. * must now sort the left partition.
  273. */
  274. if( lo0 < hi )
  275. QuickSort( a, lo0, hi );
  276. /* If the left index has not reached the right side of array
  277. * must now sort the right partition.
  278. */
  279. if( lo < hi0 )
  280. QuickSort( a, lo, hi0 );
  281. }
  282. }
  283. //----------------------------------------------------------------------
  284. // PROTECTED METHODS
  285. //----------------------------------------------------------------------
  286. /**
  287. * This will give the first element greater than <CODE>value</CODE>
  288. * in a sorted array.
  289. * If there is no element of the array greater than <CODE>value</CODE>,
  290. * the method will throw a <CODE>SnmpStatusException</CODE>.
  291. *
  292. * @param table A sorted integer array.
  293. *
  294. * @param value The greatest value.
  295. *
  296. * @exception SnmpStatusException If there is no element greater than
  297. * <CODE>value</CODE>.
  298. */
  299. final static protected int getNextIdentifier(int table[], long value)
  300. throws SnmpStatusException {
  301. final int[] a = table;
  302. final int val= (int) value;
  303. if (a == null)
  304. throw noSuchObjectException;
  305. int low= 0;
  306. int max= a.length;
  307. int curr= low + (max-low)/2;
  308. int elmt= 0;
  309. // Basic check
  310. //
  311. if (max < 1)
  312. throw noSuchObjectException;
  313. if (a[max-1] <= val)
  314. throw noSuchObjectException;
  315. while (low <= max) {
  316. elmt= a[curr];
  317. if (val == elmt) {
  318. // We ned to get the next index ...
  319. //
  320. curr++;
  321. return a[curr];
  322. }
  323. if (elmt < val) {
  324. low= curr +1;
  325. } else {
  326. max= curr -1;
  327. }
  328. curr= low + (max-low)/2;
  329. }
  330. return a[curr];
  331. }
  332. //----------------------------------------------------------------------
  333. // PRIVATE METHODS
  334. //----------------------------------------------------------------------
  335. final static private void swap(int a[], int i, int j) {
  336. int T;
  337. T = a[i];
  338. a[i] = a[j];
  339. a[j] = T;
  340. }
  341. //----------------------------------------------------------------------
  342. // PROTECTED VARIABLES
  343. //----------------------------------------------------------------------
  344. /**
  345. * Contains the list of variable identifiers.
  346. */
  347. protected int[] varList;
  348. /**
  349. * Contains a predefined exception that is often fired when an
  350. * object is not found in the MIB.
  351. */
  352. static final protected SnmpStatusException noSuchInstanceException =
  353. new SnmpStatusException(SnmpStatusException.noSuchInstance);
  354. static final protected SnmpStatusException noSuchObjectException =
  355. new SnmpStatusException(SnmpStatusException.noSuchObject);
  356. static final protected SnmpStatusException noSuchNameException =
  357. new SnmpStatusException(SnmpDefinitions.snmpRspNoSuchName);
  358. }