1. /*
  2. * @(#)file SnmpVarBindList.java
  3. * @(#)author Sun Microsystems, Inc.
  4. * @(#)version 1.4
  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. // Copyright (c) 1995-96 by Cisco Systems, Inc.
  12. package com.sun.jmx.snmp;
  13. import java.util.Vector;
  14. import java.util.Enumeration;
  15. /**
  16. * Contains a list of <CODE>SnmpVarBind</CODE> objects.
  17. * This class helps to create an <CODE>SnmpVarBindList</CODE> from a list of MIB variable names.
  18. * In addition, it contains different forms of methods which can copy or clone the list.
  19. * This list is required by any SNMP entity which specifies a list of variables to query.
  20. * <p><b>This API is a Sun Microsystems internal API and is subject
  21. * to change without notice.</b></p>
  22. */
  23. public class SnmpVarBindList extends Vector {
  24. /**
  25. * A name given to the <CODE>SnmpVarBindList</CODE>. Useful for debugging.
  26. * The default name is "VarBindList".
  27. */
  28. public String identity = "VarBindList " ; // name identifying this list.
  29. /**
  30. * Timestamp when this <CODE>SnmpVarBindList</CODE> was updated.
  31. * Valid only for <CODE>SnmpGet</CODE> and <CODE>SnmpGetNext</CODE> operations.
  32. * <CODE>SnmpTimestamp</CODE> is null by default.
  33. * Also, when the list is cloned without value the timestamp is not copied.
  34. */
  35. Timestamp timestamp ;
  36. // CONSTRUCTORS
  37. //-------------
  38. /**
  39. * Prepares an empty list.
  40. * The initial capacity and the capacity increment are initialized to 5.
  41. */
  42. public SnmpVarBindList() {
  43. super(5, 5) ;
  44. }
  45. /**
  46. * Prepares an empty list.
  47. * @param initialCapacity The initial capacity of the <CODE>SnmpVarBindList</CODE>.
  48. */
  49. public SnmpVarBindList(int initialCapacity) {
  50. super(initialCapacity) ;
  51. }
  52. /**
  53. * Prepares an empty list with a <CODE>String</CODE> to print while debugging.
  54. * @param name The name of the newly created <CODE>SnmpVarBindList</CODE>.
  55. */
  56. public SnmpVarBindList(String name) {
  57. super(5, 5) ;
  58. identity = name ;
  59. }
  60. /**
  61. * Similar to the copy constructor. Does a shallow copy of the elements.
  62. * Individual elements are not cloned.
  63. * @param list The <CODE>SnmpVarBindList</CODE> to copy.
  64. */
  65. public SnmpVarBindList(SnmpVarBindList list) {
  66. super(list.size(), 5) ;
  67. list.copyInto(elementData) ;
  68. elementCount = list.size() ;
  69. }
  70. /**
  71. * Creates a new <CODE>SnmpVarBindList</CODE> object from a plain vector of <CODE>SnmpVarBind</CODE> objects.
  72. * Objects in the specified vector can be <CODE>SnmpVarBind</CODE> objects or derivatives.
  73. * @param list The vector of <CODE>SnmpVarBind</CODE> objects to copy.
  74. */
  75. public SnmpVarBindList(Vector list) {
  76. super(list.size(), 5);
  77. for (Enumeration e = list.elements(); e.hasMoreElements();) {
  78. final SnmpVarBind varBind = (SnmpVarBind)e.nextElement();
  79. addElement((SnmpVarBind)varBind.clone());
  80. }
  81. }
  82. /**
  83. * Creates a new <CODE>SnmpVarBindList</CODE> object from a plain vector of <CODE>SnmpVarBind</CODE> objects.
  84. * Objects in the specified vector can be <CODE>SnmpVarBind</CODE> objects or derivatives.
  85. * @param name The name of the newly created <CODE>SnmpVarBindList</CODE>.
  86. * @param list The vector of <CODE>SnmpVarBind</CODE> objects to copy.
  87. */
  88. public SnmpVarBindList(String name, Vector list) {
  89. this(list);
  90. identity = name;
  91. }
  92. // GETTER/SETTER
  93. //--------------
  94. /**
  95. * Gets the <CODE>timestamp</CODE> associated with this <CODE>SnmpVarBindList</CODE>.
  96. * @return The <CODE>timestamp</CODE>.
  97. */
  98. public Timestamp getTimestamp() {
  99. return timestamp ;
  100. }
  101. /**
  102. * Records the <CODE>sysUpTime</CODE> and the actual time when this <CODE>SnmpVarBindList</CODE>
  103. * was changed or created.
  104. * This needs to be set explicitly.
  105. * @param tstamp The <CODE>SnmpTimestamp</CODE> of the device for which the values hold <CODE>true</CODE>.
  106. */
  107. public void setTimestamp(Timestamp tstamp) {
  108. timestamp = tstamp ;
  109. }
  110. /**
  111. * Gets an <CODE>SnmpVarBind</CODE> object.
  112. * @param pos The position in the list.
  113. * @return The <CODE>SnmpVarBind</CODE> object at the specified position.
  114. * @exception java.lang.ArrayIndexOutOfBoundsException If the specified <CODE>pos</CODE> is beyond range.
  115. */
  116. public final synchronized SnmpVarBind getVarBindAt(int pos) {
  117. return (SnmpVarBind)(elementAt(pos)) ;
  118. }
  119. /**
  120. * Gets the number of elements in this list.
  121. * @return The number of elements in the list.
  122. */
  123. public synchronized int getVarBindCount() {
  124. return size() ;
  125. }
  126. /**
  127. * This is a convenience function that returns an enumeration. This can be used to traverse the list.
  128. * This is advantageous as it hides the implementation of the class of the list which keeps the variables.
  129. * @return An enumeration object of <CODE>SnmpVarBind</CODE> objects.
  130. */
  131. public synchronized Enumeration getVarBindList() {
  132. return elements() ;
  133. }
  134. /**
  135. * Replaces the current variable binding list of <CODE>SnmpVarBind</CODE> with the new specified variable binding
  136. * list of <CODE>SnmpVarBind</CODE> objects.
  137. * This method only clones the vector. It does not clone the <CODE>SnmpVarBind</CODE> objects
  138. * contained in the list.
  139. * @param list A vector of <CODE>SnmpVarBind</CODE> objects.
  140. */
  141. public final synchronized void setVarBindList(Vector list) {
  142. setVarBindList(list, false) ;
  143. }
  144. /**
  145. * Replaces the current variable binding list of <CODE>SnmpVarBind</CODE> objects with the new variable binding
  146. * list of <CODE>SnmpVarBind</CODE> objects.
  147. * If <CODE>copy</CODE> is <CODE>true</CODE>, it will clone each <CODE>SnmpVarBind</CODE> object
  148. * contained in the list.
  149. * @param list A vector of <CODE>SnmpVarBind</CODE> objects.
  150. * @param copy The flag indicating whether each object in the list should be cloned.
  151. */
  152. public final synchronized void setVarBindList(Vector list, boolean copy) {
  153. synchronized (list) {
  154. final int max = list.size();
  155. setSize(max) ;
  156. list.copyInto(this.elementData) ;
  157. if (copy) { // do deepcopy of all vars.
  158. for (int i = 0; i < max ; i++) {
  159. SnmpVarBind avar = (SnmpVarBind)elementData[i] ;
  160. elementData[i] = avar.clone() ;
  161. }
  162. }
  163. }
  164. }
  165. // PUBLIC METHODS
  166. //---------------
  167. /**
  168. * Appends an <CODE>SnmpVarBindList</CODE> at the end of the current <CODE>SnmpVarBindList</CODE> object.
  169. * @param list The <CODE>SnmpVarBindList</CODE> to append.
  170. */
  171. public synchronized void addVarBindList(SnmpVarBindList list) {
  172. ensureCapacity(list.size() + size()) ;
  173. for (int i = 0; i < list.size(); i++) {
  174. addElement(list.getVarBindAt(i)) ;
  175. }
  176. }
  177. /**
  178. * Removes all the <CODE>SnmpVarBind</CODE> objects of the given <CODE>SnmpVarBindList</CODE> from the existing
  179. * <CODE>SnmpVarBindList</CODE>.
  180. * @param list The <CODE>SnmpVarBindList</CODE> to be removed.
  181. * @return <CODE>true</CODE> if all the <CODE>SnmpVarBind</CODE> objects were components of this
  182. * <CODE>SnmpVarBindList</CODE>, <CODE>false</CODE> otherwise.
  183. */
  184. public synchronized boolean removeVarBindList(SnmpVarBindList list) {
  185. boolean result = true;
  186. for (int i = 0; i < list.size(); i++) {
  187. result = removeElement(list.getVarBindAt(i)) ;
  188. }
  189. return result;
  190. }
  191. /**
  192. * Replaces an element at a specified location with the new element.
  193. * @param var The replacement variable.
  194. * @param pos The location in the <CODE>SnmpVarBindList</CODE>.
  195. * @exception java.lang.ArrayIndexOutOfBoundsException If the specified <CODE>pos</CODE> is beyond range.
  196. */
  197. public final synchronized void replaceVarBind(SnmpVarBind var, int pos) {
  198. setElementAt(var, pos) ;
  199. }
  200. /**
  201. * Prepares a vector of <CODE>SnmpVarBindList</CODE> from an array of SNMP MIB variables and instances.
  202. * @param list An array of <CODE>String</CODE> containing MIB variable names.
  203. * @param inst A common instance for each of the MIB variables in <CODE>vlist</CODE>.
  204. * @exception SnmpStatusException An error occurred while accessing a MIB node.
  205. */
  206. public final synchronized void addVarBind(String list[], String inst) throws SnmpStatusException {
  207. for (int i = 0; i < list.length; i++) {
  208. SnmpVarBind avar = new SnmpVarBind(list[i]) ;
  209. avar.addInstance(inst) ;
  210. addElement(avar) ;
  211. }
  212. }
  213. /**
  214. * Removes the array of SNMP MIB variables and instances from the existing <CODE>SnmpVarBindList</CODE>.
  215. * @param list An array of <CODE>String</CODE> containing MIB variable names.
  216. * @param inst A common instance for each of the MIB variables in <CODE>vlist</CODE>.
  217. * @return <CODE>true</CODE> if all the SNMP MIB variables were components of this <CODE>SnmpVarBindList</CODE>,
  218. * <CODE>false</CODE> otherwise.
  219. * @exception SnmpStatusException An error occurred while accessing a MIB node.
  220. */
  221. public synchronized boolean removeVarBind(String list[], String inst) throws SnmpStatusException {
  222. boolean result = true;
  223. for (int i = 0; i < list.length; i++) {
  224. SnmpVarBind avar = new SnmpVarBind(list[i]) ;
  225. avar.addInstance(inst) ;
  226. int indexOid = indexOfOid(avar) ;
  227. try {
  228. removeElementAt(indexOid) ;
  229. } catch (ArrayIndexOutOfBoundsException e) {
  230. result = false ;
  231. }
  232. }
  233. return result ;
  234. }
  235. /**
  236. * Adds an array of MIB variable names to the list. For example:
  237. * <P>
  238. * <CODE>
  239. * String mylist[] = {"sysUpTime.0", "ifInOctets.0"}
  240. * <BR>
  241. * vb.addVarBind(mylist) ;
  242. * </BR>
  243. * </CODE>
  244. * @param list The array of MIB variable names.
  245. * @exception SnmpStatusException An error occurred while accessing a MIB node.
  246. */
  247. public synchronized void addVarBind(String list[]) throws SnmpStatusException {
  248. addVarBind(list, null) ;
  249. }
  250. /**
  251. * Removes the array of SNMP MIB variables from the existing <CODE>SnmpVarBindList</CODE>.
  252. * @param list Array of strings containing MIB variable names.
  253. * @return <CODE>true</CODE> if all the SNMP MIB variables were components of this <CODE>SnmpVarBindList</CODE>,
  254. * <CODE>false</CODE> otherwise.
  255. * @exception SnmpStatusException An error occurred while accessing a MIB node.
  256. */
  257. public synchronized boolean removeVarBind(String list[]) throws SnmpStatusException {
  258. return removeVarBind(list, null) ;
  259. }
  260. /**
  261. * Creates an <CODE>SnmpVarBind</CODE> object from the given MIB variable and appends it to the existing
  262. * <CODE>SnmpVarBindList</CODE>.
  263. * It creates a new <CODE>SnmpVarBindList</CODE> if one did not exist.
  264. * @param name A MIB variable name.
  265. * @exception SnmpStatusException An error occurred while accessing a MIB node.
  266. */
  267. public synchronized void addVarBind(String name) throws SnmpStatusException {
  268. SnmpVarBind avar ;
  269. avar = new SnmpVarBind(name) ;
  270. addVarBind(avar) ;
  271. }
  272. /**
  273. * Removes the <CODE>SnmpVarBind</CODE> object corresponding to the given MIB variable from the existing
  274. * <CODE>SnmpVarBindList</CODE>.
  275. * @param name A MIB variable name.
  276. * @return <CODE>true</CODE> if the SNMP MIB variable was a component of this <CODE>SnmpVarBindList</CODE>,
  277. * <CODE>false</CODE> otherwise.
  278. * @exception SnmpStatusException An error occurred while accessing a MIB node.
  279. */
  280. public synchronized boolean removeVarBind(String name) throws SnmpStatusException {
  281. SnmpVarBind avar ;
  282. int indexOid ;
  283. avar = new SnmpVarBind(name) ;
  284. indexOid = indexOfOid(avar) ;
  285. try {
  286. removeElementAt(indexOid) ;
  287. return true ;
  288. } catch (ArrayIndexOutOfBoundsException e) {
  289. return false ;
  290. }
  291. }
  292. /**
  293. * Appends the given <CODE>SnmpVarBind</CODE> object to the existing <CODE>SnmpVarBindList</CODE>.
  294. * It creates a new <CODE>SnmpVarBindList</CODE> if one did not exist.
  295. * @param var The <CODE>SnmpVarBind</CODE> object to be appended.
  296. */
  297. public synchronized void addVarBind(SnmpVarBind var) {
  298. addElement(var) ;
  299. }
  300. /**
  301. * Removes the given <CODE>SnmpVarBind</CODE> object from the existing <CODE>SnmpVarBindList</CODE>.
  302. * @param var The <CODE>SnmpVarBind</CODE> object to be removed.
  303. * @return <CODE>true</CODE> if the <CODE>SnmpVarBind</CODE> object was a component of this
  304. * <CODE>SnmpVarBindList</CODE>, <CODE>false</CODE> otherwise.
  305. */
  306. public synchronized boolean removeVarBind(SnmpVarBind var) {
  307. return removeElement(var) ;
  308. }
  309. /**
  310. * Adds the string as an instance part to all OIDs in this list.
  311. * This method should be used with caution because it affects all OIDs in the list.
  312. * @param inst The <CODE>String</CODE> to add as an instance part.
  313. * @exception SnmpStatusException An error occurred while accessing a MIB node.
  314. */
  315. public synchronized void addInstance(String inst) throws SnmpStatusException {
  316. int max= size();
  317. for (int i = 0; i < max; i++) {
  318. ((SnmpVarBind)elementData[i]).addInstance(inst) ;
  319. }
  320. }
  321. /**
  322. * Adds elements in the specified <CODE>SnmpVarBindList</CODE> to this list.
  323. * The elements are not cloned.
  324. * @param list A vector of <CODE>SnmpVarBind</CODE>.
  325. */
  326. final public synchronized void concat(Vector list) {
  327. ensureCapacity(size() + list.size()) ;
  328. for (Enumeration e = list.elements() ; e.hasMoreElements() ; ) {
  329. addElement(e.nextElement()) ;
  330. }
  331. }
  332. /**
  333. * Returns <CODE>false</CODE> if any of the variables does not contain a valid value.
  334. * Typically used for <CODE>SnmpSet</CODE> operations.
  335. * @return <CODE>false</CODE> if any of the variables does not contain a valid value, <CODE>true</CODE> otherwise.
  336. */
  337. public synchronized boolean checkForValidValues() {
  338. int max= this.size();
  339. for (int i = 0; i < max ; i++) {
  340. SnmpVarBind avar = (SnmpVarBind)elementData[i] ;
  341. if (avar.isValidValue() == false)
  342. return false ;
  343. }
  344. return true ;
  345. }
  346. /**
  347. * Returns <CODE>true</CODE> if there is a value that is not specified.
  348. * @return <CODE>true</CODE> if there is a value that is not specified, <CODE>false</CODE> otherwise.
  349. */
  350. public synchronized boolean checkForUnspecifiedValue() {
  351. int max= this.size();
  352. for (int i = 0; i < max ; i++) {
  353. SnmpVarBind avar = (SnmpVarBind)elementData[i] ;
  354. if (avar.isUnspecifiedValue())
  355. return true ;
  356. }
  357. return false ;
  358. }
  359. /**
  360. * Splits the <CODE>SnmpVarBindList</CODE>.
  361. * @param pos The position at which to split the <CODE>SnmpVarBindList</CODE>
  362. * @return The <CODE>SnmpVarBindList</CODE> list from the beginning up to the split position.
  363. */
  364. public synchronized SnmpVarBindList splitAt(int pos) {
  365. SnmpVarBindList splitVb = null ;
  366. if (pos > elementCount)
  367. return splitVb ;
  368. splitVb = new SnmpVarBindList() ; // size() - atPosition) ;
  369. int max= size();
  370. for (int i = pos; i < max ; i++)
  371. splitVb.addElement(elementData[i]) ;
  372. elementCount = pos ;
  373. trimToSize() ;
  374. return splitVb ;
  375. }
  376. /**
  377. * Gives the index of an OID in the <CODE>SnmpVarBindList</CODE>.
  378. * The index returned must be greater than or equal to the <CODE>start</CODE> parameter
  379. * and smaller than the <CODE>end</CODE> parameter. Otherwise the method returns -1.
  380. * @param var The <CODE>SnmpVarBind</CODE> object with the requested OID.
  381. * @param min The min index in <CODE>SnmpVarBindList</CODE>.
  382. * @param max The max index in <CODE>SnmpVarBindList</CODE>.
  383. * @return The index of the OID in <CODE>SnmpVarBindList</CODE>.
  384. */
  385. public synchronized int indexOfOid(SnmpVarBind var, int min, int max) {
  386. SnmpOid oidarg = var.getOid() ;
  387. for (int i = min; i < max ; i++) {
  388. SnmpVarBind avar = (SnmpVarBind)elementData[i] ;
  389. if (oidarg.equals(avar.getOid()))
  390. return i ;
  391. }
  392. return -1 ;
  393. }
  394. /**
  395. * Gives the index of an OID in the <CODE>SnmpVarBindList</CODE>.
  396. * @param var The <CODE>SnmpVarBind</CODE> object with the requested OID.
  397. * @return The index of the OID in <CODE>SnmpVarBindList</CODE>.
  398. */
  399. public synchronized int indexOfOid(SnmpVarBind var) {
  400. return indexOfOid(var, 0, size()) ;
  401. }
  402. /**
  403. * Gives the index of an OID in the <CODE>SnmpVarBindList</CODE>.
  404. * @param oid The <CODE>SnmpOid</CODE> object with the requested OID.
  405. * @return The index of the OID in <CODE>SnmpVarBindList</CODE>.
  406. */
  407. public synchronized int indexOfOid(SnmpOid oid) {
  408. int max = size();
  409. for (int i = 0; i < max ; i++) {
  410. SnmpVarBind avar = (SnmpVarBind)elementData[i] ;
  411. if (oid.equals(avar.getOid()))
  412. return i ;
  413. }
  414. return -1 ;
  415. }
  416. /**
  417. * Clones the <CODE>SnmpVarBindList</CODE>. A new copy of the <CODE>SnmpVarBindList</CODE> is created.
  418. * It is a real deep copy.
  419. * @return The <CODE>SnmpVarBindList</CODE> clone.
  420. */
  421. public synchronized SnmpVarBindList cloneWithValue() {
  422. SnmpVarBindList newvb = new SnmpVarBindList() ;
  423. newvb.setTimestamp(this.getTimestamp()) ;
  424. newvb.ensureCapacity(this.size()) ;
  425. for (int i = 0; i < this.size() ; i++) {
  426. SnmpVarBind avar = (SnmpVarBind)elementData[i] ;
  427. newvb.addElement(avar.clone()) ;
  428. }
  429. return newvb ;
  430. }
  431. /**
  432. * Clones the <CODE>SnmpVarBindList</CODE>. It does not clone the value part of the variable.
  433. * It is a deep copy (except for the value portion).
  434. * @return The <CODE>SnmpVarBindList</CODE> clone.
  435. */
  436. public synchronized SnmpVarBindList cloneWithoutValue() {
  437. SnmpVarBindList newvb = new SnmpVarBindList() ;
  438. int max = this.size();
  439. newvb.ensureCapacity(max) ;
  440. for (int i = 0; i < max ; i++) {
  441. SnmpVarBind avar = (SnmpVarBind)elementData[i] ;
  442. newvb.addElement(avar.cloneWithoutValue()) ;
  443. }
  444. return newvb ;
  445. }
  446. /**
  447. * Clones the <CODE>SnmpVarBindList</CODE>. A new copy of the <CODE>SnmpVarBindList</CODE> is created.
  448. * It is a real deep copy.
  449. * @return The object clone.
  450. */
  451. public synchronized Object clone() {
  452. return cloneWithValue() ;
  453. }
  454. /**
  455. * Copies the <CODE>SnmpVarBindList</CODE> into a plain vector of <CODE>SnmpVarBind</CODE> objects.
  456. * If the <code>copy</code> flag is false, does a shallow copy of the list. Otherwise,
  457. * individual elements will be cloned.
  458. * @param copy The flag indicating whether each object in the list should be cloned.
  459. * @return A new vector of <CODE>SnmpVarBind</CODE> objects.
  460. */
  461. public synchronized Vector toVector(boolean copy) {
  462. final int count = elementCount;
  463. if (copy == false) return (Vector) super.clone();
  464. Vector result = new Vector(count,5);
  465. for (int i = 0; i < count ; i++) {
  466. SnmpVarBind avar = (SnmpVarBind)elementData[i] ;
  467. result.addElement(avar.clone()) ;
  468. }
  469. return result;
  470. }
  471. /**
  472. * Returns a <CODE>String</CODE> containing the ASCII representation of all OIDs in the list.
  473. * @return An ASCII list of all OIDs in this list.
  474. */
  475. public String oidListToString() {
  476. StringBuffer s = new StringBuffer(300) ;
  477. for (int i = 0 ; i < elementCount ; i++) {
  478. SnmpVarBind avar = (SnmpVarBind)elementData[i] ;
  479. s.append(avar.getOid().toString() + "\n") ;
  480. }
  481. return s.toString() ;
  482. }
  483. /**
  484. * Constructs a <CODE>String</CODE> containing details of each <CODE>SnmpVarBindList</CODE> (oid+value).
  485. * This is typically used in debugging.
  486. * @return A detailed <CODE>String</CODE> of all in the <CODE>SnmpVarBindList</CODE>.
  487. */
  488. public synchronized String varBindListToString() {
  489. StringBuffer s = new StringBuffer(300) ;
  490. for (int i = 0; i < elementCount ; i++) {
  491. s.append(elementData[i].toString() + "\n") ;
  492. }
  493. return s.toString() ;
  494. }
  495. /**
  496. * Finalizer of the <CODE>SnmpVarBindList</CODE> objects.
  497. * This method is called by the garbage collector on an object
  498. * when garbage collection determines that there are no more references to the object.
  499. * <P>Removes all the elements from this <CODE>SnmpVarBindList</CODE> object.
  500. */
  501. public void finalize() {
  502. removeAllElements() ;
  503. }
  504. }