KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > jmx > snmp > agent > SnmpMibOid


1 /*
2  * @(#)file SnmpMibOid.java
3  * @(#)author Sun Microsystems, Inc.
4  * @(#)version 4.21
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
12
13 package com.sun.jmx.snmp.agent;
14
15
16
17 // java imports
18
//
19
import java.io.Serializable JavaDoc;
20 import java.util.Vector JavaDoc;
21 import java.util.Enumeration JavaDoc;
22
23 // jmx imports
24
//
25
import com.sun.jmx.snmp.SnmpOid;
26 import com.sun.jmx.snmp.SnmpValue;
27 import com.sun.jmx.snmp.SnmpVarBind;
28 import com.sun.jmx.snmp.SnmpStatusException;
29
30 /**
31  * Represents a node in an SNMP MIB which is neither a group nor a variable.
32  * This class defines a list of sub-nodes and the methods that allow to
33  * manipulate the sub-nodes.
34  * <P>
35  * This class is used internally and by the class generated by
36  * <CODE>mibgen</CODE>.
37  * You should not need to use this class directly.
38  *
39  * <p><b>This API is a Sun Microsystems internal API and is subject
40  * to change without notice.</b></p>
41  * @version 4.21 02/25/04
42  * @author Sun Microsystems, Inc
43  */

44
45 public class SnmpMibOid extends SnmpMibNode implements Serializable JavaDoc {
46
47     /**
48      * Default constructor.
49      */

50     public SnmpMibOid() {
51     }
52     
53     // PUBLIC METHODS
54
//---------------
55

56     /**
57      * Generic handling of the <CODE>get</CODE> operation.
58      *
59      * <p> This method should be overridden in subclasses.
60      * <p>
61      *
62      * @param req The sub-request that must be handled by this node.
63      *
64      * @param depth The depth reached in the OID tree.
65      *
66      * @exception SnmpStatusException The default implementation (if not
67      * overridden) is to generate a SnmpStatusException.
68      */

69     public void get(SnmpMibSubRequest req, int depth)
70     throws SnmpStatusException {
71         for (Enumeration JavaDoc e= req.getElements(); e.hasMoreElements();) {
72             SnmpVarBind var= (SnmpVarBind) e.nextElement();
73         SnmpStatusException x =
74         new SnmpStatusException(SnmpStatusException.noSuchObject);
75         req.registerGetException(var,x);
76     }
77     }
78
79     /**
80      * Generic handling of the <CODE>set</CODE> operation.
81      *
82      * <p> This method should be overridden in subclasses.
83      * <p>
84      *
85      * @param req The sub-request that must be handled by this node.
86      *
87      * @param depth The depth reached in the OID tree.
88      *
89      * @exception SnmpStatusException The default implementation (if not
90      * overridden) is to generate a SnmpStatusException.
91      */

92     public void set(SnmpMibSubRequest req, int depth)
93     throws SnmpStatusException {
94         for (Enumeration JavaDoc e= req.getElements(); e.hasMoreElements();) {
95             SnmpVarBind var= (SnmpVarBind) e.nextElement();
96         SnmpStatusException x =
97         new SnmpStatusException(SnmpStatusException.noAccess);
98         req.registerSetException(var,x);
99     }
100     }
101
102     /**
103      * Generic handling of the <CODE>check</CODE> operation.
104      *
105      * <p> This method should be overridden in subclasses.
106      * <p>
107      *
108      * @param req The sub-request that must be handled by this node.
109      *
110      * @param depth The depth reached in the OID tree.
111      *
112      * @exception SnmpStatusException The default implementation (if not
113      * overriden) is to generate a SnmpStatusException.
114      */

115     public void check(SnmpMibSubRequest req, int depth)
116     throws SnmpStatusException {
117         for (Enumeration JavaDoc e= req.getElements(); e.hasMoreElements();) {
118             SnmpVarBind var= (SnmpVarBind) e.nextElement();
119         SnmpStatusException x =
120         new SnmpStatusException(SnmpStatusException.noAccess);
121         req.registerCheckException(var,x);
122     }
123     }
124
125
126
127     // ---------------------------------------------------------------------
128
//
129
// Implements the method defined in SnmpMibNode.
130
//
131
// ---------------------------------------------------------------------
132
//
133
void findHandlingNode(SnmpVarBind varbind,
134               long[] oid, int depth,
135               SnmpRequestTree handlers)
136     throws SnmpStatusException {
137
138
139     final int length = oid.length;
140     SnmpMibNode node = null;
141     
142     if (handlers == null)
143             throw new SnmpStatusException(SnmpStatusException.snmpRspGenErr);
144
145     if (depth > length) {
146         // Nothing is left... the oid is not valid
147
throw noSuchObjectException;
148
149     } else if (depth == length) {
150         // The oid is not complete...
151
throw noSuchInstanceException;
152
153     } else {
154         // Some children variable or subobject is being querried
155
// getChild() will raise an exception if no child is found.
156
//
157
final SnmpMibNode child= getChild(oid[depth]);
158
159         // XXXX zzzz : what about null children?
160
// (variables for nested groups)
161
// if child==null, then we're dealing with a variable or
162
// a table: we register this node.
163
// This behaviour should be overriden in subclasses,
164
// in particular in group meta classes: the group
165
// meta classes that hold tables should take care
166
// of forwarding this call to all the tables involved.
167
//
168
if (child == null)
169         handlers.add(this,depth,varbind);
170         else
171         child.findHandlingNode(varbind,oid,depth+1,handlers);
172     }
173     }
174
175     // ---------------------------------------------------------------------
176
//
177
// Implements the method defined in SnmpMibNode.
178
//
179
// ---------------------------------------------------------------------
180
//
181
long[] findNextHandlingNode(SnmpVarBind varbind,
182                 long[] oid, int pos, int depth,
183                 SnmpRequestTree handlers,
184                 AcmChecker checker)
185     throws SnmpStatusException {
186
187
188     final int length = oid.length;
189     SnmpMibNode node = null;
190     long[] result = null;
191     if (handlers == null)
192         // This should be considered as a genErr, but we do not want to
193
// abort the whole request, so we're going to throw
194
// a noSuchObject...
195
//
196
throw noSuchObjectException;
197
198     final Object JavaDoc data = handlers.getUserData();
199     final int pduVersion = handlers.getRequestPduVersion();
200
201         if (pos >= length) {
202             long[] newOid= new long[1];
203         newOid[0]= getNextVarId(-1,data,pduVersion);
204             result = findNextHandlingNode(varbind,newOid,0,depth,handlers,
205                       checker);
206         return result;
207         }
208
209         // search the element specified in the oid
210
//
211
long[] newOid= new long[1];
212         long index= oid[pos];
213    
214         while (true) {
215      
216             try {
217                 final SnmpMibNode child = getChild(index);
218         // SnmpOid result = null;
219
if (child == null) {
220             // shouldn't happen
221
throw noSuchObjectException;
222             // validateVarId(index);
223
// handlers.add(this,varbind,depth);
224
// result = new SnmpOid(0);
225
} else {
226             checker.add(depth, index);
227             try {
228             result = child.findNextHandlingNode(varbind,oid,pos+1,
229                                 depth+1,handlers,
230                                 checker);
231             } finally {
232             checker.remove(depth);
233             }
234         }
235         
236         // Build up the leaf OID
237
result[depth] = index;
238                 return result;
239         
240             } catch(SnmpStatusException e) {
241                 // If there is no such element go one level up ...
242
//
243
index= getNextVarId(index,data,pduVersion);
244
245                 // There is no need to carry the original oid ...
246
newOid[0]=index;
247                 pos= 1;
248                 oid=newOid;
249             }
250         }
251     }
252
253
254     /**
255      * Computes the root OID of the MIB.
256      */

257     public void getRootOid(Vector JavaDoc result) {
258
259         // If a node has several children, let assume that we are one step to
260
// far in order to get the MIB root.
261
//
262
if (nbChildren != 1)
263             return;
264         
265         result.addElement(new Integer JavaDoc(varList[0]));
266
267         // Now query our child.
268
//
269
((SnmpMibNode)children.firstElement()).getRootOid(result);
270     
271     }
272
273     /**
274      * Registers a specific node in the tree.
275      */

276     public void registerNode(String JavaDoc oidString ,SnmpMibNode node)
277     throws IllegalAccessException JavaDoc {
278         SnmpOid oid= new SnmpOid(oidString);
279         registerNode(oid.longValue(), 0, node);
280     }
281     
282     // PROTECTED METHODS
283
//------------------
284

285     /**
286      * Registers a specific node in the tree.
287      */

288     void registerNode(long[] oid, int cursor ,SnmpMibNode node)
289     throws IllegalAccessException JavaDoc {
290         
291         if (cursor >= oid.length)
292             throw new IllegalAccessException JavaDoc();
293     
294         // Check if the node is already defined
295
//
296
long var= oid[cursor];
297
298         //System.out.println("entering registration for val="
299
// + String.valueOf(var) + " position= " + cursor);
300

301         int pos = retrieveIndex(var);
302         if (pos == nbChildren) {
303             nbChildren++;
304             varList= new int[nbChildren];
305             varList[0]= (int) var;
306             pos =0;
307             if ( (cursor + 1) == oid.length) {
308                 // That 's the end of the trip.
309
// Do not forward the registration
310

311                 //System.out.println("End of trip for val="
312
// + String.valueOf(var) + " position= " + cursor);
313
children.insertElementAt(node,pos);
314                 return;
315             }
316
317             //System.out.println("Create node for val="
318
// + String.valueOf(var) + " position= " + cursor);
319
SnmpMibOid child= new SnmpMibOid();
320             children.insertElementAt(child, pos);
321             child.registerNode(oid, cursor + 1, node);
322             return;
323         }
324         if (pos == -1) {
325             // The node is not yet registered
326
//
327
int[] tmp= new int[nbChildren + 1];
328             tmp[nbChildren]= (int) var;
329             System.arraycopy(varList, 0, tmp, 0, nbChildren);
330             varList= tmp;
331             nbChildren++;
332             SnmpMibNode.sort(varList);
333             int newPos = retrieveIndex(var);
334             varList[newPos]= (int) var;
335             if ( (cursor + 1) == oid.length) {
336                 // That 's the end of the trip.
337
// Do not forward the registration
338

339                 //System.out.println("End of trip for val="
340
// + String.valueOf(var) + " position= " + cursor);
341
children.insertElementAt(node, newPos);
342                 return;
343             }
344             SnmpMibOid child= new SnmpMibOid();
345             // System.out.println("Create node for val=" +
346
// String.valueOf(var) + " position= " + cursor);
347
children.insertElementAt(child, newPos);
348             child.registerNode(oid, cursor + 1, node);
349             return;
350         }
351         else {
352             // The node is already registered
353
//
354
SnmpMibNode child= (SnmpMibNode) children.elementAt(pos);
355             if ( (cursor + 1) == oid.length ) {
356                 //System.out.println("Node already registered val=" +
357
// String.valueOf(var) + " position= " + cursor);
358
if (child == node) return;
359         if (child != null && node != null) {
360             // Now we're going to patch the tree the following way:
361
// if a subgroup has been registered before its father,
362
// we're going to replace the father OID node with
363
// the actual group-node and export the children from
364
// the temporary OID node to the actual group node.
365
//
366

367             if (node instanceof SnmpMibGroup) {
368             // `node' is a group => replace `child' with `node'
369
// export the child's subtree to `node'.
370
//
371
((SnmpMibOid)child).exportChildren((SnmpMibOid)node);
372             children.setElementAt(node,pos);
373             return;
374
375             } else if ((node instanceof SnmpMibOid) &&
376                  (child instanceof SnmpMibGroup)) {
377             // `node' is a temporary node, and `child' is a
378
// group => keep child and export the node's
379
// subtree to `child'.
380
//
381
((SnmpMibOid)node).exportChildren((SnmpMibOid)child);
382             return;
383             } else if (node instanceof SnmpMibOid) {
384             // `node' and `child' are both temporary OID nodes
385
// => replace `child' with `node' and export child's
386
// subtree to `node'.
387
//
388
((SnmpMibOid)child).exportChildren((SnmpMibOid)node);
389             children.setElementAt(node,pos);
390             return;
391             }
392         }
393         children.setElementAt(node,pos);
394                 return;
395             } else {
396         if (child == null)
397             throw new IllegalAccessException JavaDoc();
398                 ((SnmpMibOid)child).registerNode(oid, cursor + 1, node);
399             }
400         }
401     }
402     
403     /**
404      * Export this node's children to a brother node that will replace
405      * this node in the OID tree.
406      * This method is a patch that fixes the problem of registering
407      * a subnode before its father node.
408      *
409      **/

410     void exportChildren(SnmpMibOid brother)
411     throws IllegalAccessException JavaDoc {
412     
413     if (brother == null) return;
414     final long[] oid = new long[1];
415     for (int i=0; i<nbChildren; i++) {
416         final SnmpMibNode child = (SnmpMibNode)children.elementAt(i);
417         if (child == null) continue;
418         oid[0] = varList[i];
419         brother.registerNode(oid,0,child);
420     }
421     }
422
423     // PRIVATE METHODS
424
//----------------
425

426     SnmpMibNode getChild(long id) throws SnmpStatusException {
427         
428         // first we need to retrieve the identifier in the list of children
429
//
430
final int pos= getInsertAt(id);
431         if (pos >= nbChildren)
432             throw noSuchObjectException;
433     
434         if (varList[pos] != (int) id)
435             throw noSuchObjectException;
436
437         // Access the node
438
//
439
SnmpMibNode child = null;
440         try {
441             child = (SnmpMibNode) children.elementAtNonSync(pos);
442         } catch(ArrayIndexOutOfBoundsException JavaDoc e) {
443             throw noSuchObjectException;
444         }
445     if (child == null)
446             throw noSuchInstanceException;
447     return child;
448     }
449   
450     private int retrieveIndex(long val) {
451
452         int low= 0;
453         int cursor= (int) val;
454     if (varList == null || varList.length < 1)
455         return nbChildren;
456
457         int max= varList.length -1 ;
458         int curr= low + (max-low)/2;
459         int elmt= 0;
460         while (low <= max) {
461             elmt= varList[curr];
462             if (cursor == elmt) {
463                 // We need to get the next index ...
464
//
465
return curr;
466             }
467             if (elmt < cursor) {
468                 low= curr +1;
469             } else {
470                 max= curr -1;
471             }
472             curr= low + (max-low)/2;
473         }
474         return -1;
475     }
476   
477     private int getInsertAt(long val) {
478         
479         int low= 0;
480         final int index= (int) val;
481     if (varList == null)
482             return -1;
483         int max= varList.length -1 ;
484         int elmt=0;
485     //final int[] v = varList;
486

487         //if (index > a[max])
488
//return max +1;
489

490   
491         int curr= low + (max-low)/2;
492         while (low <= max) {
493
494             elmt= varList[curr];
495
496             // never know ...we might find something ...
497
//
498
if (index == elmt)
499                 return curr;
500
501             if (elmt < index) {
502                 low= curr +1;
503             } else {
504                 max= curr -1;
505             }
506             curr= low + (max-low)/2;
507         }
508
509         return curr;
510     }
511     
512     // PRIVATE VARIABLES
513
//------------------
514

515     /**
516      * Contains the list of sub nodes.
517      */

518     private NonSyncVector children= new NonSyncVector(1);
519     
520     /**
521      * The number of sub nodes.
522      */

523     private int nbChildren= 0;
524     
525     
526     // All the methods of the Vector class are synchronized.
527
// Synchronization is a very expensive operation. In our case it is
528
// not always required...
529
//
530
class NonSyncVector extends Vector JavaDoc {
531     
532         public NonSyncVector(int size) {
533             super(size);
534         }
535     
536         final void addNonSyncElement(Object JavaDoc obj) {
537             ensureCapacity(elementCount + 1);
538             elementData[elementCount++] = obj;
539         }
540     
541         final Object JavaDoc elementAtNonSync(int index) {
542             return elementData[index];
543         }
544     
545     }
546 }
547
Popular Tags