KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > jmx > snmp > SnmpOid


1 /*
2  * @(#)file SnmpOid.java
3  * @(#)author Sun Microsystems, Inc.
4  * @(#)version 4.22
5  * @(#)date 08/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 // Copyright (c) 1995-96 by Cisco Systems, Inc.
12

13 package com.sun.jmx.snmp;
14
15
16 // java imports
17
//
18
import java.util.StringTokenizer JavaDoc;
19 import java.util.NoSuchElementException JavaDoc;
20
21 /**
22  * Represents an SNMP Object Identifier (OID).
23  *
24  * <p><b>This API is a Sun Microsystems internal API and is subject
25  * to change without notice.</b></p>
26  * @version 4.22 12/19/03
27  * @author Sun Microsystems, Inc
28  * @author Cisco Systems, Inc.
29  */

30
31 public class SnmpOid extends SnmpValue {
32
33     // CONSTRUCTORS
34
//-------------
35
/**
36      * Constructs a new <CODE>SnmpOid</CODE> with no components.
37      */

38     public SnmpOid() {
39     components = new long[15] ;
40     componentCount = 0 ;
41     }
42   
43     /**
44      * Constructs a new <CODE>SnmpOid</CODE> from the specified component array.
45      * @param oidComponents The initialization component array.
46      */

47     public SnmpOid(long[] oidComponents) {
48     components = (long[])oidComponents.clone() ;
49     componentCount = components.length ;
50     }
51
52     /**
53      * Constructs a new <CODE>SnmpOid</CODE> containing one component with the
54      * specified value.
55      * @param id The initialization component value.
56      */

57     public SnmpOid(long id) {
58     components = new long[1] ;
59     components[0] = id ;
60     componentCount = components.length ;
61     }
62   
63     /**
64      * Constructs a new <CODE>SnmpOid</CODE> containing four components
65      * with the specified values.
66      * @param id1 The first component value.
67      * @param id2 The second component values.
68      * @param id3 The third component values.
69      * @param id4 The fourth component values.
70      */

71     public SnmpOid(long id1, long id2, long id3, long id4) {
72     components = new long[4] ;
73     components[0] = id1 ;
74     components[1] = id2 ;
75     components[2] = id3 ;
76     components[3] = id4 ;
77     componentCount = components.length ;
78     }
79
80     /**
81      * Constructs a new <CODE>SnmpOid</CODE> from a dot-formatted <CODE>String</CODE> or a MIB variable
82      * name. It generates an exception if the variable name cannot be resolved, or
83      * if the dot-formatted <CODE>String</CODE> has an invalid subidentifier.
84      * This constructor helps build an OID object with a <CODE>String</CODE> like .1.2.3.4 or 1.2.3.4
85      * or <CODE>ifInOctets</CODE> or <CODE>ifInOctets</CODE>.0.
86      * @param s <CODE>String</CODE> or MIB variable of the form .1.2.3 or 1.2.3 or <CODE>ifInOctets</CODE>.
87      * @exception IllegalArgumentException The subidentifier is neither a numeric <CODE>String</CODE>
88      * nor a <CODE>String</CODE> of the MIB database.
89      */

90     public SnmpOid(String JavaDoc s) throws IllegalArgumentException JavaDoc {
91     String JavaDoc dotString = s ;
92
93     if (s.startsWith(".") == false) {
94         try {
95         dotString = resolveVarName(s);
96         } catch(SnmpStatusException e) {
97         throw new IllegalArgumentException JavaDoc(e.getMessage());
98         }
99     }
100
101     StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(dotString, ".", false) ;
102     componentCount= st.countTokens();
103     
104     // Now extract the ids
105
//
106
if (componentCount == 0) {
107         components = new long[15] ;
108     } else {
109         components = new long[componentCount] ;
110         try {
111         for (int i = 0 ; i < componentCount ; i++) {
112             try {
113             components[i] = Long.parseLong(st.nextToken()) ;
114             }
115             catch(NoSuchElementException JavaDoc e) {}
116         }
117         }
118         catch(NumberFormatException JavaDoc e) {
119         throw new IllegalArgumentException JavaDoc(s) ;
120         }
121     }
122     }
123
124     // PUBLIC METHODS
125
//---------------
126
/**
127      * Gets the number of components in this OID.
128      * @return The number of components.
129      */

130     public int getLength() {
131     return componentCount ;
132     }
133
134     /**
135      * Returns a copy of the components array of this <CODE>SnmpOid</CODE>.
136      * @return The copy of the components array.
137      */

138     public long[] longValue() {
139     long[] result = new long[componentCount] ;
140     System.arraycopy(components,0,result,0,componentCount);
141     return result ;
142     }
143
144     /**
145      * Returns the components array of this <CODE>SnmpOid</CODE>.
146      * If <code>duplicate</code> is true, a copy is returned.
147      * Otherwise, a reference to the internal array is returned,
148      * in which case the caller <b>shall not</b> modify this array.
149      * This method is provided to optimize processing in those cases
150      * where the caller needs only to read the components array.
151      *
152      * @param duplicate Indicates whether a copy or a reference must
153      * be returned:
154      * <li><code>true</code> if a copy must be returned,</li>
155      * <li><code>false</code> if a reference on the internal data
156      * can be returned.</li>
157      * @return A copy of (or a reference on) the components array.
158      */

159     public final long[] longValue(boolean duplicate) {
160     if (duplicate) return longValue();
161     if (componentCount == components.length) return components ;
162     components = longValue();
163     componentCount = components.length;
164     return components ;
165     }
166
167     /**
168      * Returns the value of the OID arc found at the requested position
169      * in the <CODE>components</CODE> array. The first element is at
170      * position <code>0</code>.
171      *
172      * @param pos The position at which the OID arc should be peeked.
173      *
174      * @return The OID arc found at the requested position.
175      *
176      * @exception SnmpStatusException No OID arc was found at the requested
177      * position.
178      */

179     public final long getOidArc(int pos) throws SnmpStatusException {
180     try {
181         return components[pos];
182     } catch(Exception JavaDoc e) {
183         throw new SnmpStatusException(SnmpStatusException.noAccess);
184     }
185     }
186
187     /**
188      * Converts the OID value to its <CODE>Long</CODE> form.
189      * @return The <CODE>Long</CODE> representation of the value.
190      */

191     public Long JavaDoc toLong() {
192     if (componentCount != 1) {
193         throw new IllegalArgumentException JavaDoc() ;
194     }
195     return new Long JavaDoc(components[0]) ;
196     }
197
198     /**
199      * Converts the OID value to its <CODE>Integer</CODE> form.
200      * @return The <CODE>Integer</CODE> representation of the value.
201      */

202     public Integer JavaDoc toInteger() {
203     if ((componentCount != 1) || (components[0] > Integer.MAX_VALUE)) {
204         throw new IllegalArgumentException JavaDoc() ;
205     }
206     return new Integer JavaDoc((int)components[0]) ;
207     }
208
209     /**
210      * Converts the OID value to its <CODE>String</CODE> form.
211      * @return The <CODE>String</CODE> representation of the value.
212      */

213     public String JavaDoc toString() {
214     String JavaDoc result = "" ;
215     if (componentCount >= 1) {
216         for (int i = 0 ; i < componentCount - 1 ; i++) {
217         result = result + components[i] + "." ;
218         }
219         result = result + components[componentCount - 1] ;
220     }
221     return result ;
222     }
223     
224     /**
225      * Converts the OID value to its <CODE>Boolean</CODE> form.
226      * @return The <CODE>Boolean</CODE> representation of the value.
227      */

228     public Boolean JavaDoc toBoolean() {
229     if ((componentCount != 1) && (components[0] != 1) && (components[0] != 2)) {
230         throw new IllegalArgumentException JavaDoc() ;
231     }
232     return new Boolean JavaDoc(components[0] == 1) ;
233     }
234   
235     /**
236      * Converts the OID value to its array of <CODE>Bytes</CODE> form.
237      * @return The array of <CODE>Bytes</CODE> representation of the value.
238      */

239     public Byte JavaDoc[] toByte() {
240     Byte JavaDoc[] result = new Byte JavaDoc[componentCount] ;
241     for (int i =0 ; i < componentCount ; i++) {
242         if (components[0] > 255) {
243         throw new IllegalArgumentException JavaDoc() ;
244         }
245         result[i] = new Byte JavaDoc((byte)components[i]) ;
246     }
247     return result ;
248     }
249
250     /**
251      * Converts the OID value to its <CODE>SnmpOid</CODE> form.
252      * @return The OID representation of the value.
253      */

254     public SnmpOid toOid() {
255     long[] ids = new long[componentCount] ;
256     for (int i = 0 ; i < componentCount ; i++) {
257         ids[i] = components[i] ;
258     }
259     return new SnmpOid(ids) ;
260     }
261   
262     /**
263      * Extracts the OID from an index OID and returns its
264      * value converted as an <CODE>SnmpOid</CODE>.
265      * @param index The index array.
266      * @param start The position in the index array.
267      * @return The OID representing the OID value.
268      * @exception SnmpStatusException There is no OID value
269      * available at the start position.
270      */

271     public static SnmpOid toOid(long[] index, int start) throws SnmpStatusException {
272     try {
273         if (index[start] > Integer.MAX_VALUE) {
274         throw new SnmpStatusException(SnmpStatusException.noSuchName) ;
275         }
276         int idCount = (int)index[start++] ;
277         long[] ids = new long[idCount] ;
278         for (int i = 0 ; i < idCount ; i++) {
279         ids[i] = index[start + i] ;
280         }
281         return new SnmpOid(ids) ;
282     }
283     catch(IndexOutOfBoundsException JavaDoc e) {
284         throw new SnmpStatusException(SnmpStatusException.noSuchName) ;
285     }
286     }
287
288     /**
289      * Scans an index OID, skips the OID value and returns the position
290      * of the next value.
291      * @param index The index array.
292      * @param start The position in the index array.
293      * @return The position of the next value.
294      * @exception SnmpStatusException There is no OID value
295      * available at the start position.
296      */

297     public static int nextOid(long[] index, int start) throws SnmpStatusException {
298     try {
299         if (index[start] > Integer.MAX_VALUE) {
300         throw new SnmpStatusException(SnmpStatusException.noSuchName) ;
301         }
302         int idCount = (int)index[start++] ;
303         start += idCount ;
304         if (start <= index.length) {
305         return start ;
306         }
307         else {
308         throw new SnmpStatusException(SnmpStatusException.noSuchName) ;
309         }
310     }
311     catch(IndexOutOfBoundsException JavaDoc e) {
312         throw new SnmpStatusException(SnmpStatusException.noSuchName) ;
313     }
314     }
315
316     /**
317      * Appends an <CODE>SnmpOid</CODE> representing an <CODE>SnmpOid</CODE> to another OID.
318      * @param source An OID representing an <CODE>SnmpOid</CODE> value.
319      * @param dest Where source should be appended.
320      */

321     public static void appendToOid(SnmpOid source, SnmpOid dest) {
322     dest.append(source.getLength()) ;
323     dest.append(source) ;
324     }
325   
326     /**
327      * Performs a clone action. This provides a workaround for the
328      * <CODE>SnmpValue</CODE> interface.
329      * @return The SnmpValue clone.
330      */

331     final synchronized public SnmpValue duplicate() {
332     return (SnmpValue)clone() ;
333     }
334
335     /**
336      * Clones the <CODE>SnmpOid</CODE> object, making a copy of its data.
337      * @return The object clone.
338      */

339     public Object JavaDoc clone() {
340     try {
341         SnmpOid obj = (SnmpOid)super.clone() ;
342         obj.components = new long[this.componentCount] ;
343
344         System.arraycopy(this.components, 0, obj.components, 0,
345                  this.componentCount) ;
346         return obj ;
347     } catch (CloneNotSupportedException JavaDoc e) {
348         throw new InternalError JavaDoc() ; // should never happen. VM bug.
349
}
350     }
351
352     /**
353      * Inserts a subid at the beginning of this <CODE>SnmpOid</CODE>.
354      * @param id The long subid to insert.
355      */

356     public void insert(long id) {
357     enlargeIfNeeded(1) ;
358     for (int i = componentCount - 1 ; i >= 0 ; i--) {
359         components[i + 1] = components[i] ;
360     }
361     components[0] = id ;
362     componentCount++ ;
363     }
364  
365     /**
366      * Inserts a subid at the beginning of this <CODE>SnmpOid</CODE>.
367      * @param id The integer subid to insert.
368      */

369     public void insert(int id) {
370     insert((long)id) ;
371     }
372   
373     /**
374      * Appends the specified <CODE>SnmpOid</CODE> to the end of this <CODE>SnmpOid</CODE>.
375      * @param oid The OID to append.
376      */

377     public void append(SnmpOid oid) {
378     enlargeIfNeeded(oid.componentCount) ;
379     for (int i = 0 ; i < oid.componentCount ; i++) {
380         components[componentCount + i] = oid.components[i] ;
381     }
382     componentCount += oid.componentCount ;
383     }
384   
385     /**
386      * Appends the specified long to the end of this <CODE>SnmpOid</CODE>.
387      * @param id The long to append.
388      */

389     public void append(long id) {
390     enlargeIfNeeded(1) ;
391     components[componentCount] = id ;
392     componentCount++ ;
393     }
394   
395     /**
396      * Adds the specified dot-formatted OID <CODE>String</CODE> to the end of this <CODE>SnmpOid</CODE>.
397      * The subidentifiers can be expressed as a dot-formatted <CODE>String</CODE> or a
398      * MIB variable name.
399      * @param s Variable name of the form .1.2.3 or 1.2.3 or
400      * <CODE>ifInOctets</CODE>.
401      * @exception SnmpStatusException An error occurred while accessing a MIB node.
402      */

403     public void addToOid(String JavaDoc s) throws SnmpStatusException {
404     SnmpOid suffix= new SnmpOid(s);
405     this.append(suffix);
406     }
407
408     /**
409      * Adds the specified array of longs to the end of this <CODE>SnmpOid</CODE>.
410      * @param oid An array of longs.
411      * @exception SnmpStatusException An error occurred while accessing a MIB node.
412      */

413     public void addToOid(long []oid) throws SnmpStatusException {
414     SnmpOid suffix= new SnmpOid(oid);
415     this.append(suffix);
416     }
417
418     /**
419      * Checks the validity of the OID.
420      * @return <CODE>true</CODE> if the OID is valid, <CODE>false</CODE> otherwise.
421      */

422     public boolean isValid() {
423     return ((componentCount >= 2) &&
424         ((0 <= components[0]) && (components[0] < 3)) &&
425         ((0 <= components[1]) && (components[1] < 40))) ;
426     }
427
428     /**
429      * Checks whether the specified <CODE>Object</CODE> is equal to this <CODE>SnmpOid</CODE>.
430      * @param o The <CODE>Object</CODE> to be compared.
431      * @return <CODE>true</CODE> if <CODE>o</CODE> is an <CODE>SnmpOid</CODE> instance and equal to this, <CODE>false</CODE> otherwise.
432      */

433     public boolean equals(Object JavaDoc o) {
434     boolean result = false ;
435     
436     if (o instanceof SnmpOid) {
437         SnmpOid oid = (SnmpOid)o ;
438         if (oid.componentCount == componentCount) {
439         int i = 0 ;
440         long[] objoid = oid.components;
441         while ((i < componentCount) && (components[i] == objoid[i]))
442             i++ ;
443         result = (i == componentCount) ;
444         }
445     }
446     return result ;
447     }
448  
449      /**
450      * The hashCode is computed from the OID components.
451      * @return a hashCode for this SnmpOid.
452      **/

453     public int hashCode() {
454     long acc=0;
455     for (int i=0;i<componentCount;i++) {
456         acc = acc*31+components[i];
457     }
458     return (int)acc;
459     }
460
461    /**
462      * Compares two OIDs lexicographically.
463      * @param other The OID to be compared.
464      * @return
465      * The value 0 if the parameter <CODE>other</CODE> is equal to this <CODE>SnmpOid</CODE>.
466      * A value smaller than 0 if this <CODE>SnmpOid</CODE> is lexicographically smaller than <CODE>other</CODE>.
467      * A value larger than 0 if this <CODE>SnmpOid</CODE> is lexicographically larger than <CODE>other</CODE>.
468      */

469     public int compareTo(SnmpOid other) {
470     int result = 0 ;
471     int i = 0 ;
472     int cmplen = Math.min(componentCount, other.componentCount) ;
473     long[] otheroid = other.components;
474
475     for (i = 0; i < cmplen; i++) {
476         if (components[i] != otheroid[i]) {
477         break ;
478         }
479     }
480     if ((i == componentCount) && (i == other.componentCount)) {
481         result = 0 ;
482     }
483     else if (i == componentCount) {
484         result = -1 ;
485     }
486     else if (i == other.componentCount) {
487         result = 1 ;
488     }
489     else {
490         result = (components[i] < otheroid[i]) ? -1 : 1 ;
491     }
492     return result ;
493     }
494       
495     /**
496      * Resolves a MIB variable <CODE>String</CODE> with the MIB database.
497      * @param s The variable name to resolve.
498      * @exception SnmpStatusException If the variable is not found in the MIB database.
499      */

500     public String JavaDoc resolveVarName(String JavaDoc s) throws SnmpStatusException {
501     int index = s.indexOf('.') ;
502     
503     // First handle the case where oid is expressed as 1.2.3.4
504
//
505
try {
506         return handleLong(s, index);
507     } catch(NumberFormatException JavaDoc e) {}
508     
509     // if we are here, it means we have something to resolve..
510
//
511
if (meta == null)
512       throw new SnmpStatusException(SnmpStatusException.noSuchName);
513     
514     // Ok assume there is a variable name to resolve ...
515
//
516
if (index <= 0) {
517         SnmpOidRecord rec = meta.resolveVarName(s);
518         return rec.getOid();
519     
520     } else {
521         SnmpOidRecord rec = meta.resolveVarName(s.substring(0, index));
522         return (rec.getOid()+ s.substring(index));
523
524     }
525     }
526
527     /**
528      * Returns a textual description of the type object.
529      * @return ASN.1 textual description.
530      */

531     public String JavaDoc getTypeName() {
532     return name ;
533     }
534
535     /**
536      * Returns the MIB table used for resolving MIB variable names.
537      * @return The MIB table.
538      */

539     public static SnmpOidTable getSnmpOidTable() {
540     return meta;
541     }
542     
543     /**
544      * Sets the MIB table to use for resolving MIB variable names.
545      * If no mib table is available, the class will not be able to resolve
546      * names contained in the Object Identifier.
547      * @param db The MIB table to use.
548      */

549     public static void setSnmpOidTable(SnmpOidTable db) {
550     meta = db;
551     }
552
553     /**
554      * Converts an OID index converted string back to a DisplayString
555      *
556      **/

557     public String JavaDoc toOctetString() {
558     return new String JavaDoc(tobyte()) ;
559     }
560  
561
562     // PRIVATE METHODS
563
//------------------
564

565     /**
566      * convert the components array into a byte array
567      **/

568     private byte[] tobyte() {
569     byte[] result = new byte[componentCount] ;
570     for (int i =0 ; i < componentCount ; i++) {
571         if (components[0] > 255) {
572         throw new IllegalArgumentException JavaDoc() ;
573         }
574         result[i] = (byte)components[i] ;
575     }
576     return result ;
577     }
578
579
580     /**
581      * Checks if there is enough space in the components
582      * array to insert n new subids. If not, it increases the size of
583      * the array.
584      * In fact it reallocates a new array and copy the old one into the new one.
585      * @param n The number of subids to insert.
586      */

587     private void enlargeIfNeeded(int n) {
588     int neededSize = components.length ;
589     while (componentCount + n > neededSize) {
590         neededSize = neededSize * 2 ;
591     }
592     if (neededSize > components.length) {
593         long[] newComponents = new long[neededSize] ;
594         for (int i = 0 ; i < components.length ; i++) {
595         newComponents[i] = components[i] ;
596         }
597         components = newComponents ;
598     }
599     }
600   
601     // PRIVATE METHODS
602
//----------------
603
private String JavaDoc handleLong(String JavaDoc oid, int index) throws NumberFormatException JavaDoc, SnmpStatusException {
604     String JavaDoc str;
605     if (index >0) {
606         str= oid.substring(0, index);
607     } else {
608         str= oid ;
609     }
610     
611     // just parse the element.
612
//
613
Long.parseLong(str);
614     return oid;
615     }
616   
617     // VARIABLES
618
//----------
619
/**
620      * The components' array.
621      * @serial
622      */

623     protected long components[] = null ;
624
625     /**
626      * The length of the components' array.
627      * @serial
628      */

629     protected int componentCount = 0 ;
630   
631     /**
632      * The name of the type.
633      */

634     final static String JavaDoc name = "Object Identifier";
635   
636     /**
637      * Reference to a mib table. If no mib table is available,
638      * the class will not be able to resolve names contained in the Object Identifier.
639      */

640      private static SnmpOidTable meta= null;
641
642     /**
643      * Ensure serialization compatibility with version 4.1 FCS
644      *
645      */

646     static final long serialVersionUID = 8956237235607885096L;
647 }
648
Popular Tags