KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * @(#)file SnmpRequestTree.java
3  * @(#)author Sun Microsystems, Inc.
4  * @(#)version 1.26
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 package com.sun.jmx.snmp.agent;
11
12 import java.util.Vector JavaDoc;
13 import java.util.ArrayList JavaDoc;
14 import java.util.Hashtable JavaDoc;
15 import java.util.Enumeration JavaDoc;
16 import java.util.Iterator JavaDoc;
17 import java.util.List JavaDoc;
18 import java.util.NoSuchElementException JavaDoc;
19 import java.util.Arrays JavaDoc;
20 import com.sun.jmx.snmp.SnmpVarBind;
21 import com.sun.jmx.snmp.SnmpStatusException;
22 import com.sun.jmx.snmp.SnmpDefinitions;
23 import com.sun.jmx.snmp.SnmpOid;
24 import com.sun.jmx.snmp.SnmpPdu;
25 import com.sun.jmx.snmp.SnmpEngine;
26 import com.sun.jmx.trace.Trace;
27
28 // XXX: things to do: use SnmpOid rather than `instance' for future
29
// evolutions.
30
// XXX: Maybe use hashlists rather than vectors for entries?
31
// => in that case, the key should be SnmpOid.toString()
32
//
33
/**
34  * This class is used to register varbinds from a SNMP varbind list with
35  * the SnmpMibNode responsible for handling the requests concerning that
36  * varbind.
37  * This class holds a hashtable of Handler nodes, whith the involved
38  * SnmpMibNode as a key.
39  * When the involved SnmpMibNode is a group, the sublist of varbind is
40  * directly stored in the Handler node.
41  * When the involved SnmpMibNode is a table, the sublist is stored in a
42  * sorted array indexed by the OID of the entry involved.
43  */

44 final class SnmpRequestTree {
45
46     // Constructor:
47
// @param req The SnmpMibRequest that will be segmented in this
48
// tree. It holds the original varbind vector passed
49
// by the SnmpSubRequestHandler to this MIB. This
50
// varbind vector is used to retrieve the "real"
51
// position of a varbind in the vector. There is no other easy
52
// way to do this - since as a result of the segmentation the
53
// original positions will be lost.
54
// @param creationflag indicates whether the operation involved
55
// allows for entry creation (ie: it is a SET request).
56
// @param pdutype indicates the type of the request PDU as defined
57
// in SnmpDefinitions
58
//
59
SnmpRequestTree(SnmpMibRequest req, boolean creationflag, int pdutype) {
60     this.request = req;
61     this.version = req.getVersion();
62     this.creationflag = creationflag;
63     this.hashtable = new Hashtable JavaDoc();
64     setPduType(pdutype);
65     }
66
67     public static int mapSetException(int errorStatus, int version)
68     throws SnmpStatusException {
69
70     final int errorCode = errorStatus;
71
72     if (version == SnmpDefinitions.snmpVersionOne)
73         return errorCode;
74     
75     int mappedErrorCode = errorCode;
76     
77     // Now take care of V2 errorCodes that can be stored
78
// in the varbind itself:
79
if (errorCode == SnmpStatusException.noSuchObject)
80         // noSuchObject => notWritable
81
mappedErrorCode = SnmpStatusException.snmpRspNotWritable;
82     
83     else if (errorCode == SnmpStatusException.noSuchInstance)
84         // noSuchInstance => notWritable
85
mappedErrorCode = SnmpStatusException.snmpRspNotWritable;
86
87     return mappedErrorCode;
88     }
89
90     public static int mapGetException(int errorStatus, int version)
91     throws SnmpStatusException {
92
93     final int errorCode = errorStatus;
94     if (version == SnmpDefinitions.snmpVersionOne)
95         return errorCode;
96     
97     int mappedErrorCode = errorCode;
98     
99     // Now take care of V2 errorCodes that can be stored
100
// in the varbind itself:
101
if (errorCode ==
102         SnmpStatusException.noSuchObject)
103         // noSuchObject => noSuchObject
104
mappedErrorCode = errorCode;
105     
106     else if (errorCode ==
107          SnmpStatusException.noSuchInstance)
108         // noSuchInstance => noSuchInstance
109
mappedErrorCode = errorCode;
110     
111     // Now we're going to try to transform every other
112
// global code in either noSuchInstance or noSuchObject,
113
// so that the get can return a partial result.
114
//
115
// Only noSuchInstance or noSuchObject can be stored
116
// in the varbind itself.
117
//
118

119     // According to RFC 1905: noAccess is emitted when the
120
// the access is denied because it is not in the MIB view...
121
//
122
else if (errorCode ==
123          SnmpStatusException.noAccess)
124         // noAccess => noSuchInstance
125
mappedErrorCode = SnmpStatusException.noSuchInstance;
126     
127     // According to RFC 1905: (my interpretation because it is not
128
// really clear) The specified variable name exists - but the
129
// variable does not exists and cannot be created under the
130
// present circumstances (probably because the request specifies
131
// another variable/value which is incompatible, or because the
132
// value of some other variable in the MIB prevents the creation)
133
//
134
// Note that this error should never be raised in a GET context
135
// but who knows?
136
//
137
else if (errorCode == SnmpStatusException.snmpRspInconsistentName)
138         // inconsistentName => noSuchInstance
139
mappedErrorCode = SnmpStatusException.noSuchInstance;
140     
141     // All the errors comprised between snmpRspWrongType and
142
// snmpRspInconsistentValue concern values: so we're going
143
// to assume the OID was correct, and reply with noSuchInstance.
144
//
145
// Note that this error should never be raised in a GET context
146
// but who knows?
147
//
148
else if ((errorCode >= SnmpStatusException.snmpRspWrongType) &&
149          (errorCode <= SnmpStatusException.snmpRspInconsistentValue))
150         mappedErrorCode = SnmpStatusException.noSuchInstance;
151     
152     // We're going to assume the OID was correct, and reply
153
// with noSuchInstance.
154
//
155
else if (errorCode == SnmpStatusException.readOnly)
156         mappedErrorCode = SnmpStatusException.noSuchInstance;
157     
158     // For all other errors but genErr, we're going to reply with
159
// noSuchObject
160
//
161
else if (errorCode != SnmpStatusException.snmpRspAuthorizationError &&
162          errorCode != SnmpStatusException.snmpRspGenErr)
163         mappedErrorCode = SnmpStatusException.noSuchObject;
164     
165     // Only genErr will abort the GET and be returned as global
166
// error.
167
//
168
return mappedErrorCode;
169     
170     }
171
172     //-------------------------------------------------------------------
173
// This class is a package implementation of the enumeration of
174
// SnmSubRequest associated with an Handler node.
175
//-------------------------------------------------------------------
176

177     static final class Enum implements Enumeration JavaDoc {
178     Enum(SnmpRequestTree hlist,Handler h) {
179         handler = h;
180         this.hlist = hlist;
181         size = h.getSubReqCount();
182     }
183     private final Handler handler;
184     private final SnmpRequestTree hlist;
185     private int entry = 0;
186     private int iter = 0;
187     private int size = 0;
188     
189     public boolean hasMoreElements() {
190         return iter < size;
191     }
192
193     public Object JavaDoc nextElement() throws NoSuchElementException JavaDoc {
194         if (iter == 0) {
195         if (handler.sublist != null) {
196             iter++;
197             return hlist.getSubRequest(handler);
198         }
199         }
200         iter ++;
201         if (iter > size) throw new NoSuchElementException JavaDoc();
202         Object JavaDoc result = hlist.getSubRequest(handler,entry);
203         entry++;
204         return result;
205     }
206     }
207
208     //-------------------------------------------------------------------
209
// This class is a package implementation of the SnmpMibSubRequest
210
// interface. It can only be instantiated by SnmpRequestTree.
211
//-------------------------------------------------------------------
212

213     static final class SnmpMibSubRequestImpl implements SnmpMibSubRequest {
214     SnmpMibSubRequestImpl(SnmpMibRequest global, Vector JavaDoc sublist,
215                SnmpOid entryoid, boolean isnew,
216                boolean getnextflag, SnmpVarBind rs) {
217         this.global = global;
218         varbinds = sublist;
219         this.version = global.getVersion();
220         this.entryoid = entryoid;
221         this.isnew = isnew;
222         this.getnextflag = getnextflag;
223         this.statusvb = rs;
224     }
225
226     final private Vector JavaDoc varbinds;
227     final private SnmpMibRequest global;
228     final private int version;
229     final private boolean isnew;
230     final private SnmpOid entryoid;
231     final private boolean getnextflag;
232     final private SnmpVarBind statusvb;
233
234     // -------------------------------------------------------------
235
// Implements the method defined in SnmpMibRequest interface.
236
// See SnmpMibRequest for the java doc.
237
// -------------------------------------------------------------
238
public Enumeration JavaDoc getElements() {
239         return varbinds.elements();
240     }
241     
242     // -------------------------------------------------------------
243
// Implements the method defined in SnmpMibRequest interface.
244
// See SnmpMibRequest for the java doc.
245
// -------------------------------------------------------------
246
public Vector JavaDoc getSubList() {
247         return varbinds;
248     }
249     
250     // -------------------------------------------------------------
251
// Implements the method defined in SnmpMibRequest interface.
252
// See SnmpMibRequest for the java doc.
253
// -------------------------------------------------------------
254
public final int getSize() {
255         if (varbinds == null) return 0;
256         return varbinds.size();
257     }
258
259     // -------------------------------------------------------------
260
// Implements the method defined in SnmpMibRequest interface.
261
// See SnmpMibRequest for the java doc.
262
// -------------------------------------------------------------
263
public void addVarBind(SnmpVarBind varbind) {
264         // XXX not sure we must also add the varbind in the global
265
// request? or whether we should raise an exception:
266
// in principle, this method should not be called!
267
varbinds.addElement(varbind);
268         global.addVarBind(varbind);
269     }
270
271     // -------------------------------------------------------------
272
// Implements the method defined in SnmpMibSubRequest interface.
273
// See SnmpMibSubRequest for the java doc.
274
// -------------------------------------------------------------
275
public boolean isNewEntry() {
276         return isnew;
277     }
278     
279     // -------------------------------------------------------------
280
// Implements the method defined in SnmpMibSubRequest interface.
281
// See SnmpMibSubRequest for the java doc.
282
// -------------------------------------------------------------
283
public SnmpOid getEntryOid() {
284         return entryoid;
285     }
286     
287     // -------------------------------------------------------------
288
// Implements the method defined in SnmpMibRequest interface.
289
// See SnmpMibRequest for the java doc.
290
// -------------------------------------------------------------
291
public int getVarIndex(SnmpVarBind varbind) {
292         if (varbind == null) return 0;
293         return global.getVarIndex(varbind);
294     }
295
296     // -------------------------------------------------------------
297
// Implements the method defined in SnmpMibRequest interface.
298
// See SnmpMibRequest for the java doc.
299
// -------------------------------------------------------------
300
public Object JavaDoc getUserData() { return global.getUserData(); }
301
302
303     // -------------------------------------------------------------
304
// Implements the method defined in SnmpMibSubRequest interface.
305
// See SnmpMibSubRequest for the java doc.
306
// -------------------------------------------------------------
307

308     public void registerGetException(SnmpVarBind var,
309                      SnmpStatusException exception)
310         throws SnmpStatusException {
311         // The index in the exception must correspond to
312
// the SNMP index ...
313
//
314
if (version == SnmpDefinitions.snmpVersionOne)
315         throw new SnmpStatusException(exception, getVarIndex(var)+1);
316
317         if (var == null)
318         throw exception;
319
320         // If we're doing a getnext ==> endOfMibView
321
if (getnextflag) {
322         var.value = SnmpVarBind.endOfMibView;
323         return;
324         }
325
326         final int errorCode = mapGetException(exception.getStatus(),
327                           version);
328
329         // Now take care of V2 errorCodes that can be stored
330
// in the varbind itself:
331
if (errorCode ==
332         SnmpStatusException.noSuchObject)
333         // noSuchObject => noSuchObject
334
var.value= SnmpVarBind.noSuchObject;
335
336         else if (errorCode ==
337              SnmpStatusException.noSuchInstance)
338         // noSuchInstance => noSuchInstance
339
var.value= SnmpVarBind.noSuchInstance;
340
341         else
342         throw new SnmpStatusException(errorCode, getVarIndex(var)+1);
343
344     }
345     
346     // -------------------------------------------------------------
347
// Implements the method defined in SnmpMibSubRequest interface.
348
// See SnmpMibSubRequest for the java doc.
349
// -------------------------------------------------------------
350
public void registerSetException(SnmpVarBind var,
351                      SnmpStatusException exception)
352         throws SnmpStatusException {
353         // The index in the exception must correspond to
354
// the SNMP index ...
355
//
356
if (version == SnmpDefinitions.snmpVersionOne)
357         throw new SnmpStatusException(exception, getVarIndex(var)+1);
358
359         // Although the first pass of check() did not fail,
360
// the set() phase could not be carried out correctly.
361
// Since we don't know how to make an "undo", and some
362
// assignation may already have been performed, we're going
363
// to throw an snmpRspUndoFailed.
364
//
365
throw new SnmpStatusException(SnmpDefinitions.snmpRspUndoFailed,
366                       getVarIndex(var)+1);
367     }
368     
369     // -------------------------------------------------------------
370
// Implements the method defined in SnmpMibSubRequest interface.
371
// See SnmpMibSubRequest for the java doc.
372
// -------------------------------------------------------------
373
public void registerCheckException(SnmpVarBind var,
374                        SnmpStatusException exception)
375         throws SnmpStatusException {
376         // The index in the exception must correspond to
377
// the SNMP index ...
378
//
379
// We throw the exception in order to abort the SET operation
380
// in an atomic way.
381
final int errorCode = exception.getStatus();
382         final int mappedErrorCode = mapSetException(errorCode,
383                             version);
384         
385         if (errorCode != mappedErrorCode)
386         throw new
387             SnmpStatusException(mappedErrorCode, getVarIndex(var)+1);
388         else
389         throw new SnmpStatusException(exception, getVarIndex(var)+1);
390     }
391
392     // -------------------------------------------------------------
393
// Implements the method defined in SnmpMibRequest interface.
394
// See SnmpMibRequest for the java doc.
395
// -------------------------------------------------------------
396
public int getVersion() {
397         return version;
398     }
399     
400     public SnmpVarBind getRowStatusVarBind() {
401         return statusvb;
402     }
403     
404     public SnmpPdu getPdu() {
405         return global.getPdu();
406     }
407
408     public int getRequestPduVersion() {
409         return global.getRequestPduVersion();
410     }
411
412     public SnmpEngine getEngine() {
413         return global.getEngine();
414     }
415
416     public String JavaDoc getPrincipal() {
417         return global.getPrincipal();
418     }
419     
420     public int getSecurityLevel() {
421         return global.getSecurityLevel();
422     }
423     
424     public int getSecurityModel() {
425         return global.getSecurityModel();
426     }
427     
428     public byte[] getContextName() {
429         return global.getContextName();
430     }
431     
432     public byte[] getAccessContextName() {
433         return global.getAccessContextName();
434     }
435     }
436     
437     //-------------------------------------------------------------------
438
// This class implements a node in the SnmpRequestTree.
439
// It stores:
440
// o The SnmpMibNode involved (key)
441
// o The sublist of varbind directly handled by this node
442
// o A vector of sublists concerning the entries (existing or not)
443
// of the SnmpMIbNode (when it is a table).
444
//-------------------------------------------------------------------
445

446     static final class Handler {
447     SnmpMibNode meta; // The meta which handles the sublist.
448
int depth; // The depth of the meta node.
449
Vector JavaDoc sublist; // The sublist of varbinds to be handled.
450
// List entryoids; // Sorted array of entry oids
451
// List entrylists; // Sorted array of entry lists
452
// List isentrynew; // Sorted array of booleans
453
SnmpOid[] entryoids = null; // Sorted array of entry oids
454
Vector JavaDoc[] entrylists = null; // Sorted array of entry lists
455
boolean[] isentrynew = null; // Sorted array of booleans
456
SnmpVarBind[] rowstatus = null; // RowStatus varbind, if any
457
int entrycount = 0;
458     int entrysize = 0;
459
460     final int type; // request PDU type as defined in SnmpDefinitions
461
final private static int Delta = 10;
462
463     public Handler(int pduType) {
464         this.type = pduType;
465     }
466
467     /**
468      * Adds a varbind in this node sublist.
469      */

470     public void addVarbind(SnmpVarBind varbind) {
471         if (sublist == null) sublist = new Vector JavaDoc();
472         sublist.addElement(varbind);
473     }
474
475     /**
476      * register an entry for the given oid at the given position with
477      * the given sublist.
478      */

479     void add(int pos,SnmpOid oid, Vector JavaDoc v, boolean isnew,
480          SnmpVarBind statusvb) {
481
482         if (entryoids == null) {
483         // Vectors are null: Allocate new vectors
484

485         entryoids = new SnmpOid[Delta];
486         entrylists = new Vector JavaDoc[Delta];
487         isentrynew = new boolean[Delta];
488         rowstatus = new SnmpVarBind[Delta];
489         entrysize = Delta;
490         pos = 0;
491
492         } else if (pos >= entrysize || entrycount == entrysize) {
493         // Vectors must be enlarged
494

495         // Save old vectors
496
SnmpOid[] olde = entryoids;
497         Vector JavaDoc[] oldl = entrylists;
498         boolean[] oldn = isentrynew;
499         SnmpVarBind[] oldr = rowstatus;
500
501         // Allocate larger vectors
502
entrysize += Delta;
503         entryoids = new SnmpOid[entrysize];
504         entrylists = new Vector JavaDoc[entrysize];
505         isentrynew = new boolean[entrysize];
506         rowstatus = new SnmpVarBind[entrysize];
507
508         // Check pos validity
509
if (pos > entrycount) pos = entrycount;
510         if (pos < 0) pos = 0;
511
512         final int l1 = pos;
513         final int l2 = entrycount - pos;
514
515         // Copy original vectors up to `pos'
516
if (l1 > 0) {
517             java.lang.System.arraycopy(olde,0,entryoids,
518                            0,l1);
519             java.lang.System.arraycopy(oldl,0,entrylists,
520                            0,l1);
521             java.lang.System.arraycopy(oldn,0,isentrynew,
522                            0,l1);
523             java.lang.System.arraycopy(oldr,0,rowstatus,
524                            0,l1);
525         }
526
527         // Copy original vectors from `pos' to end, leaving
528
// an empty room at `pos' in the new vectors.
529
if (l2 > 0) {
530             final int l3 = l1+1;
531             java.lang.System.arraycopy(olde,l1,entryoids,
532                            l3,l2);
533             java.lang.System.arraycopy(oldl,l1,entrylists,
534                            l3,l2);
535             java.lang.System.arraycopy(oldn,l1,isentrynew,
536                            l3,l2);
537             java.lang.System.arraycopy(oldr,l1,rowstatus,
538                            l3,l2);
539         }
540         
541
542         } else if (pos < entrycount) {
543         // Vectors are large enough to accomodate one additional
544
// entry.
545
//
546
// Shift vectors, making an empty room at `pos'
547
final int l1 = pos+1;
548         final int l2 = entrycount - pos;
549
550         java.lang.System.arraycopy(entryoids,pos,entryoids,
551                        l1,l2);
552         java.lang.System.arraycopy(entrylists,pos,entrylists,
553                        l1,l2);
554         java.lang.System.arraycopy(isentrynew,pos,isentrynew,
555                        l1,l2);
556         java.lang.System.arraycopy(rowstatus,pos,rowstatus,
557                        l1,l2);
558         }
559
560         // Fill the gap at `pos'
561
entryoids[pos] = oid;
562         entrylists[pos] = v;
563         isentrynew[pos] = isnew;
564         rowstatus[pos] = statusvb;
565         entrycount++;
566     }
567
568     public void addVarbind(SnmpVarBind varbind, SnmpOid entryoid,
569                    boolean isnew, SnmpVarBind statusvb)
570         throws SnmpStatusException {
571         Vector JavaDoc v = null;
572         SnmpVarBind rs = statusvb;
573
574         if (entryoids == null) {
575 // entryoids = new ArrayList();
576
// entrylists = new ArrayList();
577
// isentrynew = new ArrayList();
578
v = new Vector JavaDoc();
579 // entryoids.add(entryoid);
580
// entrylists.add(v);
581
// isentrynew.add(new Boolean(isnew));
582
add(0,entryoid,v,isnew,rs);
583         } else {
584         // int pos = findOid(entryoids,entryoid);
585
// int pos = findOid(entryoids,entrycount,entryoid);
586
final int pos =
587             getInsertionPoint(entryoids,entrycount,entryoid);
588         if (pos > -1 && pos < entrycount &&
589             entryoid.compareTo(entryoids[pos]) == 0) {
590             v = entrylists[pos];
591             rs = rowstatus[pos];
592         } else {
593             // if (pos == -1 || pos >= entryoids.size() ) {
594
// if (pos == -1 || pos >= entrycount ) {
595
// pos = getInsertionPoint(entryoids,entryoid);
596
// pos = getInsertionPoint(entryoids,entrycount,entryoid);
597
v = new Vector JavaDoc();
598 // entryoids.add(pos,entryoid);
599
// entrylists.add(pos,v);
600
// isentrynew.add(pos,new Boolean(isnew));
601
add(pos,entryoid,v,isnew,rs);
602         }
603 // } else v = (Vector) entrylists.get(pos);
604
// } else v = entrylists[pos];
605
if (statusvb != null) {
606             if ((rs != null) && (rs != statusvb) &&
607             ((type == SnmpDefinitions.pduWalkRequest) ||
608              (type == SnmpDefinitions.pduSetRequestPdu))) {
609             throw new SnmpStatusException(
610                   SnmpStatusException.snmpRspInconsistentValue);
611             }
612             rowstatus[pos] = statusvb;
613         }
614         }
615         
616         // We do not include the status variable in the varbind,
617
// because we're going to set it separately...
618
//
619
if (statusvb != varbind)
620         v.addElement(varbind);
621     }
622
623     public int getSubReqCount() {
624         int count = 0;
625         if (sublist != null) count++;
626 // if (entryoids != null) count += entryoids.size();
627
if (entryoids != null) count += entrycount;
628         return count;
629     }
630
631     public Vector JavaDoc getSubList() {
632         return sublist;
633     }
634     
635     public int getEntryPos(SnmpOid entryoid) {
636         // return findOid(entryoids,entryoid);
637
return findOid(entryoids,entrycount,entryoid);
638     }
639
640     public SnmpOid getEntryOid(int pos) {
641         if (entryoids == null) return null;
642         // if (pos == -1 || pos >= entryoids.size() ) return null;
643
if (pos == -1 || pos >= entrycount ) return null;
644         // return (SnmpOid) entryoids.get(pos);
645
return (SnmpOid) entryoids[pos];
646     }
647
648     public boolean isNewEntry(int pos) {
649         if (entryoids == null) return false;
650         // if (pos == -1 || pos >= entryoids.size() ) return false;
651
if (pos == -1 || pos >= entrycount ) return false;
652         // return ((Boolean)isentrynew.get(pos)).booleanValue();
653
return isentrynew[pos];
654     }
655
656     public SnmpVarBind getRowStatusVarBind(int pos) {
657         if (entryoids == null) return null;
658         // if (pos == -1 || pos >= entryoids.size() ) return false;
659
if (pos == -1 || pos >= entrycount ) return null;
660         // return ((Boolean)isentrynew.get(pos)).booleanValue();
661
return rowstatus[pos];
662     }
663
664     public Vector JavaDoc getEntrySubList(int pos) {
665         if (entrylists == null) return null;
666         // if (pos == -1 || pos >= entrylists.size() ) return null;
667
if (pos == -1 || pos >= entrycount ) return null;
668         // return (Vector) entrylists.get(pos);
669
return entrylists[pos];
670     }
671
672     public Iterator JavaDoc getEntryOids() {
673         if (entryoids == null) return null;
674         // return entryoids.iterator();
675
return Arrays.asList(entryoids).iterator();
676     }
677
678     public int getEntryCount() {
679         if (entryoids == null) return 0;
680         // return entryoids.size();
681
return entrycount;
682     }
683     
684     }
685
686
687     //-------------------------------------------------------------------
688
//-------------------------------------------------------------------
689
// Public interface
690
//-------------------------------------------------------------------
691
//-------------------------------------------------------------------
692

693     //-------------------------------------------------------------------
694
// Returns the contextual object containing user-data allocated
695
// through the SnmpUserDataFactory for this request.
696
//-------------------------------------------------------------------
697

698     public Object JavaDoc getUserData() { return request.getUserData(); }
699
700     //-------------------------------------------------------------------
701
// Tells whether creation of new entries is allowed with respect
702
// to the operation involved (GET=>false/SET=>true)
703
//-------------------------------------------------------------------
704

705     public boolean isCreationAllowed() {
706     return creationflag;
707     }
708
709     //-------------------------------------------------------------------
710
// Tells whether we are currently processing a SET request (check/set)
711
//-------------------------------------------------------------------
712

713     public boolean isSetRequest() {
714     return setreqflag;
715     }
716
717     //-------------------------------------------------------------------
718
// Returns the protocol version in which the original request is
719
// evaluated.
720
//-------------------------------------------------------------------
721

722     public int getVersion() {
723     return version;
724     }
725
726     //-------------------------------------------------------------------
727
// Returns the actual protocol version of the request PDU.
728
//-------------------------------------------------------------------
729

730     public int getRequestPduVersion() {
731     return request.getRequestPduVersion();
732     }
733
734     //-------------------------------------------------------------------
735
// Returns the SnmpMibNode associated with the given handler
736
//-------------------------------------------------------------------
737

738     public SnmpMibNode getMetaNode(Handler handler) {
739     return handler.meta;
740     }
741
742     //-------------------------------------------------------------------
743
// Indicates the depth of the arc in the OID that identifies the
744
// SnmpMibNode associated with the given handler
745
//-------------------------------------------------------------------
746

747     public int getOidDepth(Handler handler) {
748     return handler.depth;
749     }
750
751     //-------------------------------------------------------------------
752
// returns an enumeration of the SnmpMibSubRequest's to be invoked on
753
// the SnmpMibNode associated with a given Handler node.
754
// If this node is a group, there will be a single subrequest.
755
// If it is a table, there will be one subrequest per entry involved.
756
//-------------------------------------------------------------------
757

758     public Enumeration JavaDoc getSubRequests(Handler handler) {
759     return new Enum JavaDoc(this,handler);
760     }
761
762     //-------------------------------------------------------------------
763
// returns an enumeration of the Handlers stored in the Hashtable.
764
//-------------------------------------------------------------------
765

766     public Enumeration JavaDoc getHandlers() {
767     return hashtable.elements();
768     }
769
770     //-------------------------------------------------------------------
771
// adds a varbind to a handler node sublist
772
//-------------------------------------------------------------------
773

774     public void add(SnmpMibNode meta, int depth, SnmpVarBind varbind)
775     throws SnmpStatusException {
776     registerNode(meta,depth,null,varbind,false,null);
777     }
778
779     //-------------------------------------------------------------------
780
// adds an entry varbind to a handler node sublist
781
//-------------------------------------------------------------------
782

783     public void add(SnmpMibNode meta, int depth, SnmpOid entryoid,
784             SnmpVarBind varbind, boolean isnew)
785     throws SnmpStatusException {
786     registerNode(meta,depth,entryoid,varbind,isnew,null);
787     }
788
789     //-------------------------------------------------------------------
790
// adds an entry varbind to a handler node sublist - specifying the
791
// varbind which holds the row status
792
//-------------------------------------------------------------------
793

794     public void add(SnmpMibNode meta, int depth, SnmpOid entryoid,
795             SnmpVarBind varbind, boolean isnew,
796             SnmpVarBind statusvb)
797         throws SnmpStatusException {
798     registerNode(meta,depth,entryoid,varbind,isnew,statusvb);
799     }
800
801
802     //-------------------------------------------------------------------
803
//-------------------------------------------------------------------
804
// Protected interface
805
//-------------------------------------------------------------------
806
//-------------------------------------------------------------------
807

808     //-------------------------------------------------------------------
809
// Type of the request (see SnmpDefinitions)
810
//-------------------------------------------------------------------
811

812     void setPduType(int pduType) {
813     type = pduType;
814     setreqflag = ((pduType == SnmpDefinitions.pduWalkRequest) ||
815         (pduType == SnmpDefinitions.pduSetRequestPdu));
816     }
817
818     //-------------------------------------------------------------------
819
// We deal with a GET-NEXT request
820
//-------------------------------------------------------------------
821

822     void setGetNextFlag() {
823     getnextflag = true;
824     }
825     
826     //-------------------------------------------------------------------
827
// Tell whether creation is allowed.
828
//-------------------------------------------------------------------
829
void switchCreationFlag(boolean flag) {
830     creationflag = flag;
831     }
832
833
834     //-------------------------------------------------------------------
835
// Returns the subrequest handled by the SnmpMibNode itself
836
// (in principle, only for Groups)
837
//-------------------------------------------------------------------
838

839     SnmpMibSubRequest getSubRequest(Handler handler) {
840     if (handler == null) return null;
841     return new SnmpMibSubRequestImpl(request,handler.getSubList(),
842                       null,false,getnextflag,null);
843     }
844
845     //-------------------------------------------------------------------
846
// Returns the subrequest associated with the entry identified by
847
// the given entry (only for tables)
848
//-------------------------------------------------------------------
849

850     SnmpMibSubRequest getSubRequest(Handler handler, SnmpOid oid) {
851     if (handler == null) return null;
852     final int pos = handler.getEntryPos(oid);
853     if (pos == -1) return null;
854     return new SnmpMibSubRequestImpl(request,
855                      handler.getEntrySubList(pos),
856                      handler.getEntryOid(pos),
857                      handler.isNewEntry(pos),
858                      getnextflag,
859                      handler.getRowStatusVarBind(pos));
860     }
861
862     //-------------------------------------------------------------------
863
// Returns the subrequest associated with the entry identified by
864
// the given entry (only for tables). The `entry' parameter is an
865
// index relative to the position of the entry in the handler sublist.
866
//-------------------------------------------------------------------
867

868     SnmpMibSubRequest getSubRequest(Handler handler, int entry) {
869     if (handler == null) return null;
870     return new
871         SnmpMibSubRequestImpl(request,handler.getEntrySubList(entry),
872                   handler.getEntryOid(entry),
873                   handler.isNewEntry(entry),getnextflag,
874                   handler.getRowStatusVarBind(entry));
875     }
876
877     //-------------------------------------------------------------------
878
//-------------------------------------------------------------------
879
// Private section
880
//-------------------------------------------------------------------
881
//-------------------------------------------------------------------
882

883
884     //-------------------------------------------------------------------
885
// stores a handler node in the Hashtable
886
//-------------------------------------------------------------------
887

888     private void put(Object JavaDoc key, Handler handler) {
889     if (handler == null) return;
890     if (key == null) return;
891     if (hashtable == null) hashtable = new Hashtable JavaDoc();
892     hashtable.put(key,handler);
893     }
894
895     //-------------------------------------------------------------------
896
// finds a handler node in the Hashtable
897
//-------------------------------------------------------------------
898

899     private Handler get(Object JavaDoc key) {
900     if (key == null) return null;
901     if (hashtable == null) return null;
902     return (Handler) hashtable.get(key);
903     }
904
905     //-------------------------------------------------------------------
906
// Search for the given oid in `oids'. If none is found, returns -1
907
// otherwise, returns the index at which the oid is located.
908
//-------------------------------------------------------------------
909

910     private static int findOid(SnmpOid[] oids, int count, SnmpOid oid) {
911     final int size = count;
912         int low= 0;
913         int max= size - 1;
914         int curr= low + (max-low)/2;
915         //System.out.println("Try to retrieve: " + oid.toString());
916
while (low <= max) {
917
918             final SnmpOid pos = oids[curr];
919       
920             //System.out.println("Compare with" + pos.toString());
921
// never know ...we might find something ...
922
//
923
final int comp = oid.compareTo(pos);
924             if (comp == 0)
925                 return curr;
926       
927             if (oid.equals(pos)) {
928                 return curr;
929             }
930             if (comp > 0) {
931                 low = curr + 1;
932             } else {
933                 max = curr - 1;
934             }
935             curr = low + (max-low)/2;
936         }
937         return -1;
938     }
939
940     //-------------------------------------------------------------------
941
// Return the index at which the given oid should be inserted in the
942
// `oids' array.
943
//-------------------------------------------------------------------
944

945     private static int getInsertionPoint(SnmpOid[] oids, int count,
946                      SnmpOid oid) {
947     final SnmpOid[] localoids = oids;
948     final int size = count;
949         int low= 0;
950         int max= size - 1;
951         int curr= low + (max-low)/2;
952
953
954         while (low <= max) {
955       
956             final SnmpOid pos = localoids[curr];
957       
958             // never know ...we might find something ...
959
//
960
final int comp= oid.compareTo(pos);
961
962         // In the calling method we will have to check for this case...
963
// if (comp == 0)
964
// return -1;
965
// Returning curr instead of -1 avoids having to call
966
// findOid() first and getInsertionPoint() afterwards.
967
// We can simply call getInsertionPoint() and then checks whether
968
// there's an OID at the returned position which equals the
969
// given OID.
970
if (comp == 0)
971                 return curr;
972       
973             if (comp>0) {
974                 low= curr +1;
975             } else {
976                 max= curr -1;
977             }
978             curr= low + (max-low)/2;
979         }
980         return curr;
981     }
982
983     //-------------------------------------------------------------------
984
// adds a varbind in a handler node sublist
985
//-------------------------------------------------------------------
986

987     private void registerNode(SnmpMibNode meta, int depth, SnmpOid entryoid,
988                   SnmpVarBind varbind, boolean isnew,
989                   SnmpVarBind statusvb)
990     throws SnmpStatusException {
991     if (meta == null) {
992         if (isDebugOn())
993         debug("registerNode","meta-node is null!!!");
994         return;
995     }
996     if (varbind == null) {
997         if (isDebugOn())
998         debug("registerNode","varbind is null!!!");
999         return ;
1000    }
1001
1002    final Object JavaDoc key = meta;
1003
1004    // retrieve the handler node associated with the given meta,
1005
// if any
1006
Handler handler = get(key);
1007
1008    // If no handler node was found for that meta, create one.
1009
if (handler == null) {
1010        // if (isDebugOn())
1011
// debug("registerNode", "adding node for " +
1012
// varbind.oid.toString());
1013
handler = new Handler(type);
1014        handler.meta = meta;
1015        handler.depth = depth;
1016        put(key,handler);
1017    }
1018    // else {
1019
// if (isDebugOn())
1020
// debug("registerNode","found node for " +
1021
// varbind.oid.toString());
1022
// }
1023

1024    // Adds the varbind in the handler node's sublist.
1025
if (entryoid == null)
1026        handler.addVarbind(varbind);
1027    else
1028        handler.addVarbind(varbind,entryoid,isnew,statusvb);
1029    return ;
1030    }
1031    
1032    private final static boolean isDebugOn() {
1033        return Trace.isSelected(Trace.LEVEL_DEBUG, Trace.INFO_ADAPTOR_SNMP);
1034    }
1035
1036    private final static void debug(String JavaDoc func, String JavaDoc info) {
1037        Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_ADAPTOR_SNMP,
1038           "SnmpRequestTree", func, info);
1039    }
1040
1041    //-------------------------------------------------------------------
1042
// private variables
1043
//-------------------------------------------------------------------
1044

1045    private Hashtable JavaDoc hashtable = null; // Hashtable of Handler objects
1046
private SnmpMibRequest request = null; // The original list of varbinds
1047
private int version = 0; // The protocol version
1048
private boolean creationflag = false; // Does the operation allow
1049
// creation of entries
1050
private boolean getnextflag = false; // Does the operation allow
1051
// creation of entries
1052
private int type = 0; // Request PDU type as defined
1053
// in SnmpDefinitions
1054
private boolean setreqflag = false; // True if we're processing a
1055
// SET request (check/set).
1056
}
1057
Popular Tags