- /*
- * @(#)file SnmpRequestTree.java
- * @(#)author Sun Microsystems, Inc.
- * @(#)version 1.26
- * @(#)date 04/09/15
- *
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- */
- package com.sun.jmx.snmp.agent;
-
- import java.util.Vector;
- import java.util.ArrayList;
- import java.util.Hashtable;
- import java.util.Enumeration;
- import java.util.Iterator;
- import java.util.List;
- import java.util.NoSuchElementException;
- import java.util.Arrays;
- import com.sun.jmx.snmp.SnmpVarBind;
- import com.sun.jmx.snmp.SnmpStatusException;
- import com.sun.jmx.snmp.SnmpDefinitions;
- import com.sun.jmx.snmp.SnmpOid;
- import com.sun.jmx.snmp.SnmpPdu;
- import com.sun.jmx.snmp.SnmpEngine;
- import com.sun.jmx.trace.Trace;
-
- // XXX: things to do: use SnmpOid rather than `instance' for future
- // evolutions.
- // XXX: Maybe use hashlists rather than vectors for entries?
- // => in that case, the key should be SnmpOid.toString()
- //
- /**
- * This class is used to register varbinds from a SNMP varbind list with
- * the SnmpMibNode responsible for handling the requests concerning that
- * varbind.
- * This class holds a hashtable of Handler nodes, whith the involved
- * SnmpMibNode as a key.
- * When the involved SnmpMibNode is a group, the sublist of varbind is
- * directly stored in the Handler node.
- * When the involved SnmpMibNode is a table, the sublist is stored in a
- * sorted array indexed by the OID of the entry involved.
- */
- final class SnmpRequestTree {
-
- // Constructor:
- // @param req The SnmpMibRequest that will be segmented in this
- // tree. It holds the original varbind vector passed
- // by the SnmpSubRequestHandler to this MIB. This
- // varbind vector is used to retrieve the "real"
- // position of a varbind in the vector. There is no other easy
- // way to do this - since as a result of the segmentation the
- // original positions will be lost.
- // @param creationflag indicates whether the operation involved
- // allows for entry creation (ie: it is a SET request).
- // @param pdutype indicates the type of the request PDU as defined
- // in SnmpDefinitions
- //
- SnmpRequestTree(SnmpMibRequest req, boolean creationflag, int pdutype) {
- this.request = req;
- this.version = req.getVersion();
- this.creationflag = creationflag;
- this.hashtable = new Hashtable();
- setPduType(pdutype);
- }
-
- public static int mapSetException(int errorStatus, int version)
- throws SnmpStatusException {
-
- final int errorCode = errorStatus;
-
- if (version == SnmpDefinitions.snmpVersionOne)
- return errorCode;
-
- int mappedErrorCode = errorCode;
-
- // Now take care of V2 errorCodes that can be stored
- // in the varbind itself:
- if (errorCode == SnmpStatusException.noSuchObject)
- // noSuchObject => notWritable
- mappedErrorCode = SnmpStatusException.snmpRspNotWritable;
-
- else if (errorCode == SnmpStatusException.noSuchInstance)
- // noSuchInstance => notWritable
- mappedErrorCode = SnmpStatusException.snmpRspNotWritable;
-
- return mappedErrorCode;
- }
-
- public static int mapGetException(int errorStatus, int version)
- throws SnmpStatusException {
-
- final int errorCode = errorStatus;
- if (version == SnmpDefinitions.snmpVersionOne)
- return errorCode;
-
- int mappedErrorCode = errorCode;
-
- // Now take care of V2 errorCodes that can be stored
- // in the varbind itself:
- if (errorCode ==
- SnmpStatusException.noSuchObject)
- // noSuchObject => noSuchObject
- mappedErrorCode = errorCode;
-
- else if (errorCode ==
- SnmpStatusException.noSuchInstance)
- // noSuchInstance => noSuchInstance
- mappedErrorCode = errorCode;
-
- // Now we're going to try to transform every other
- // global code in either noSuchInstance or noSuchObject,
- // so that the get can return a partial result.
- //
- // Only noSuchInstance or noSuchObject can be stored
- // in the varbind itself.
- //
-
- // According to RFC 1905: noAccess is emitted when the
- // the access is denied because it is not in the MIB view...
- //
- else if (errorCode ==
- SnmpStatusException.noAccess)
- // noAccess => noSuchInstance
- mappedErrorCode = SnmpStatusException.noSuchInstance;
-
- // According to RFC 1905: (my interpretation because it is not
- // really clear) The specified variable name exists - but the
- // variable does not exists and cannot be created under the
- // present circumstances (probably because the request specifies
- // another variable/value which is incompatible, or because the
- // value of some other variable in the MIB prevents the creation)
- //
- // Note that this error should never be raised in a GET context
- // but who knows?
- //
- else if (errorCode == SnmpStatusException.snmpRspInconsistentName)
- // inconsistentName => noSuchInstance
- mappedErrorCode = SnmpStatusException.noSuchInstance;
-
- // All the errors comprised between snmpRspWrongType and
- // snmpRspInconsistentValue concern values: so we're going
- // to assume the OID was correct, and reply with noSuchInstance.
- //
- // Note that this error should never be raised in a GET context
- // but who knows?
- //
- else if ((errorCode >= SnmpStatusException.snmpRspWrongType) &&
- (errorCode <= SnmpStatusException.snmpRspInconsistentValue))
- mappedErrorCode = SnmpStatusException.noSuchInstance;
-
- // We're going to assume the OID was correct, and reply
- // with noSuchInstance.
- //
- else if (errorCode == SnmpStatusException.readOnly)
- mappedErrorCode = SnmpStatusException.noSuchInstance;
-
- // For all other errors but genErr, we're going to reply with
- // noSuchObject
- //
- else if (errorCode != SnmpStatusException.snmpRspAuthorizationError &&
- errorCode != SnmpStatusException.snmpRspGenErr)
- mappedErrorCode = SnmpStatusException.noSuchObject;
-
- // Only genErr will abort the GET and be returned as global
- // error.
- //
- return mappedErrorCode;
-
- }
-
- //-------------------------------------------------------------------
- // This class is a package implementation of the enumeration of
- // SnmSubRequest associated with an Handler node.
- //-------------------------------------------------------------------
-
- static final class Enum implements Enumeration {
- Enum(SnmpRequestTree hlist,Handler h) {
- handler = h;
- this.hlist = hlist;
- size = h.getSubReqCount();
- }
- private final Handler handler;
- private final SnmpRequestTree hlist;
- private int entry = 0;
- private int iter = 0;
- private int size = 0;
-
- public boolean hasMoreElements() {
- return iter < size;
- }
-
- public Object nextElement() throws NoSuchElementException {
- if (iter == 0) {
- if (handler.sublist != null) {
- iter++;
- return hlist.getSubRequest(handler);
- }
- }
- iter ++;
- if (iter > size) throw new NoSuchElementException();
- Object result = hlist.getSubRequest(handler,entry);
- entry++;
- return result;
- }
- }
-
- //-------------------------------------------------------------------
- // This class is a package implementation of the SnmpMibSubRequest
- // interface. It can only be instantiated by SnmpRequestTree.
- //-------------------------------------------------------------------
-
- static final class SnmpMibSubRequestImpl implements SnmpMibSubRequest {
- SnmpMibSubRequestImpl(SnmpMibRequest global, Vector sublist,
- SnmpOid entryoid, boolean isnew,
- boolean getnextflag, SnmpVarBind rs) {
- this.global = global;
- varbinds = sublist;
- this.version = global.getVersion();
- this.entryoid = entryoid;
- this.isnew = isnew;
- this.getnextflag = getnextflag;
- this.statusvb = rs;
- }
-
- final private Vector varbinds;
- final private SnmpMibRequest global;
- final private int version;
- final private boolean isnew;
- final private SnmpOid entryoid;
- final private boolean getnextflag;
- final private SnmpVarBind statusvb;
-
- // -------------------------------------------------------------
- // Implements the method defined in SnmpMibRequest interface.
- // See SnmpMibRequest for the java doc.
- // -------------------------------------------------------------
- public Enumeration getElements() {
- return varbinds.elements();
- }
-
- // -------------------------------------------------------------
- // Implements the method defined in SnmpMibRequest interface.
- // See SnmpMibRequest for the java doc.
- // -------------------------------------------------------------
- public Vector getSubList() {
- return varbinds;
- }
-
- // -------------------------------------------------------------
- // Implements the method defined in SnmpMibRequest interface.
- // See SnmpMibRequest for the java doc.
- // -------------------------------------------------------------
- public final int getSize() {
- if (varbinds == null) return 0;
- return varbinds.size();
- }
-
- // -------------------------------------------------------------
- // Implements the method defined in SnmpMibRequest interface.
- // See SnmpMibRequest for the java doc.
- // -------------------------------------------------------------
- public void addVarBind(SnmpVarBind varbind) {
- // XXX not sure we must also add the varbind in the global
- // request? or whether we should raise an exception:
- // in principle, this method should not be called!
- varbinds.addElement(varbind);
- global.addVarBind(varbind);
- }
-
- // -------------------------------------------------------------
- // Implements the method defined in SnmpMibSubRequest interface.
- // See SnmpMibSubRequest for the java doc.
- // -------------------------------------------------------------
- public boolean isNewEntry() {
- return isnew;
- }
-
- // -------------------------------------------------------------
- // Implements the method defined in SnmpMibSubRequest interface.
- // See SnmpMibSubRequest for the java doc.
- // -------------------------------------------------------------
- public SnmpOid getEntryOid() {
- return entryoid;
- }
-
- // -------------------------------------------------------------
- // Implements the method defined in SnmpMibRequest interface.
- // See SnmpMibRequest for the java doc.
- // -------------------------------------------------------------
- public int getVarIndex(SnmpVarBind varbind) {
- if (varbind == null) return 0;
- return global.getVarIndex(varbind);
- }
-
- // -------------------------------------------------------------
- // Implements the method defined in SnmpMibRequest interface.
- // See SnmpMibRequest for the java doc.
- // -------------------------------------------------------------
- public Object getUserData() { return global.getUserData(); }
-
-
- // -------------------------------------------------------------
- // Implements the method defined in SnmpMibSubRequest interface.
- // See SnmpMibSubRequest for the java doc.
- // -------------------------------------------------------------
-
- public void registerGetException(SnmpVarBind var,
- SnmpStatusException exception)
- throws SnmpStatusException {
- // The index in the exception must correspond to
- // the SNMP index ...
- //
- if (version == SnmpDefinitions.snmpVersionOne)
- throw new SnmpStatusException(exception, getVarIndex(var)+1);
-
- if (var == null)
- throw exception;
-
- // If we're doing a getnext ==> endOfMibView
- if (getnextflag) {
- var.value = SnmpVarBind.endOfMibView;
- return;
- }
-
- final int errorCode = mapGetException(exception.getStatus(),
- version);
-
- // Now take care of V2 errorCodes that can be stored
- // in the varbind itself:
- if (errorCode ==
- SnmpStatusException.noSuchObject)
- // noSuchObject => noSuchObject
- var.value= SnmpVarBind.noSuchObject;
-
- else if (errorCode ==
- SnmpStatusException.noSuchInstance)
- // noSuchInstance => noSuchInstance
- var.value= SnmpVarBind.noSuchInstance;
-
- else
- throw new SnmpStatusException(errorCode, getVarIndex(var)+1);
-
- }
-
- // -------------------------------------------------------------
- // Implements the method defined in SnmpMibSubRequest interface.
- // See SnmpMibSubRequest for the java doc.
- // -------------------------------------------------------------
- public void registerSetException(SnmpVarBind var,
- SnmpStatusException exception)
- throws SnmpStatusException {
- // The index in the exception must correspond to
- // the SNMP index ...
- //
- if (version == SnmpDefinitions.snmpVersionOne)
- throw new SnmpStatusException(exception, getVarIndex(var)+1);
-
- // Although the first pass of check() did not fail,
- // the set() phase could not be carried out correctly.
- // Since we don't know how to make an "undo", and some
- // assignation may already have been performed, we're going
- // to throw an snmpRspUndoFailed.
- //
- throw new SnmpStatusException(SnmpDefinitions.snmpRspUndoFailed,
- getVarIndex(var)+1);
- }
-
- // -------------------------------------------------------------
- // Implements the method defined in SnmpMibSubRequest interface.
- // See SnmpMibSubRequest for the java doc.
- // -------------------------------------------------------------
- public void registerCheckException(SnmpVarBind var,
- SnmpStatusException exception)
- throws SnmpStatusException {
- // The index in the exception must correspond to
- // the SNMP index ...
- //
- // We throw the exception in order to abort the SET operation
- // in an atomic way.
- final int errorCode = exception.getStatus();
- final int mappedErrorCode = mapSetException(errorCode,
- version);
-
- if (errorCode != mappedErrorCode)
- throw new
- SnmpStatusException(mappedErrorCode, getVarIndex(var)+1);
- else
- throw new SnmpStatusException(exception, getVarIndex(var)+1);
- }
-
- // -------------------------------------------------------------
- // Implements the method defined in SnmpMibRequest interface.
- // See SnmpMibRequest for the java doc.
- // -------------------------------------------------------------
- public int getVersion() {
- return version;
- }
-
- public SnmpVarBind getRowStatusVarBind() {
- return statusvb;
- }
-
- public SnmpPdu getPdu() {
- return global.getPdu();
- }
-
- public int getRequestPduVersion() {
- return global.getRequestPduVersion();
- }
-
- public SnmpEngine getEngine() {
- return global.getEngine();
- }
-
- public String getPrincipal() {
- return global.getPrincipal();
- }
-
- public int getSecurityLevel() {
- return global.getSecurityLevel();
- }
-
- public int getSecurityModel() {
- return global.getSecurityModel();
- }
-
- public byte[] getContextName() {
- return global.getContextName();
- }
-
- public byte[] getAccessContextName() {
- return global.getAccessContextName();
- }
- }
-
- //-------------------------------------------------------------------
- // This class implements a node in the SnmpRequestTree.
- // It stores:
- // o The SnmpMibNode involved (key)
- // o The sublist of varbind directly handled by this node
- // o A vector of sublists concerning the entries (existing or not)
- // of the SnmpMIbNode (when it is a table).
- //-------------------------------------------------------------------
-
- static final class Handler {
- SnmpMibNode meta; // The meta which handles the sublist.
- int depth; // The depth of the meta node.
- Vector sublist; // The sublist of varbinds to be handled.
- // List entryoids; // Sorted array of entry oids
- // List entrylists; // Sorted array of entry lists
- // List isentrynew; // Sorted array of booleans
- SnmpOid[] entryoids = null; // Sorted array of entry oids
- Vector[] entrylists = null; // Sorted array of entry lists
- boolean[] isentrynew = null; // Sorted array of booleans
- SnmpVarBind[] rowstatus = null; // RowStatus varbind, if any
- int entrycount = 0;
- int entrysize = 0;
-
- final int type; // request PDU type as defined in SnmpDefinitions
- final private static int Delta = 10;
-
- public Handler(int pduType) {
- this.type = pduType;
- }
-
- /**
- * Adds a varbind in this node sublist.
- */
- public void addVarbind(SnmpVarBind varbind) {
- if (sublist == null) sublist = new Vector();
- sublist.addElement(varbind);
- }
-
- /**
- * register an entry for the given oid at the given position with
- * the given sublist.
- */
- void add(int pos,SnmpOid oid, Vector v, boolean isnew,
- SnmpVarBind statusvb) {
-
- if (entryoids == null) {
- // Vectors are null: Allocate new vectors
-
- entryoids = new SnmpOid[Delta];
- entrylists = new Vector[Delta];
- isentrynew = new boolean[Delta];
- rowstatus = new SnmpVarBind[Delta];
- entrysize = Delta;
- pos = 0;
-
- } else if (pos >= entrysize || entrycount == entrysize) {
- // Vectors must be enlarged
-
- // Save old vectors
- SnmpOid[] olde = entryoids;
- Vector[] oldl = entrylists;
- boolean[] oldn = isentrynew;
- SnmpVarBind[] oldr = rowstatus;
-
- // Allocate larger vectors
- entrysize += Delta;
- entryoids = new SnmpOid[entrysize];
- entrylists = new Vector[entrysize];
- isentrynew = new boolean[entrysize];
- rowstatus = new SnmpVarBind[entrysize];
-
- // Check pos validity
- if (pos > entrycount) pos = entrycount;
- if (pos < 0) pos = 0;
-
- final int l1 = pos;
- final int l2 = entrycount - pos;
-
- // Copy original vectors up to `pos'
- if (l1 > 0) {
- java.lang.System.arraycopy(olde,0,entryoids,
- 0,l1);
- java.lang.System.arraycopy(oldl,0,entrylists,
- 0,l1);
- java.lang.System.arraycopy(oldn,0,isentrynew,
- 0,l1);
- java.lang.System.arraycopy(oldr,0,rowstatus,
- 0,l1);
- }
-
- // Copy original vectors from `pos' to end, leaving
- // an empty room at `pos' in the new vectors.
- if (l2 > 0) {
- final int l3 = l1+1;
- java.lang.System.arraycopy(olde,l1,entryoids,
- l3,l2);
- java.lang.System.arraycopy(oldl,l1,entrylists,
- l3,l2);
- java.lang.System.arraycopy(oldn,l1,isentrynew,
- l3,l2);
- java.lang.System.arraycopy(oldr,l1,rowstatus,
- l3,l2);
- }
-
-
- } else if (pos < entrycount) {
- // Vectors are large enough to accomodate one additional
- // entry.
- //
- // Shift vectors, making an empty room at `pos'
- final int l1 = pos+1;
- final int l2 = entrycount - pos;
-
- java.lang.System.arraycopy(entryoids,pos,entryoids,
- l1,l2);
- java.lang.System.arraycopy(entrylists,pos,entrylists,
- l1,l2);
- java.lang.System.arraycopy(isentrynew,pos,isentrynew,
- l1,l2);
- java.lang.System.arraycopy(rowstatus,pos,rowstatus,
- l1,l2);
- }
-
- // Fill the gap at `pos'
- entryoids[pos] = oid;
- entrylists[pos] = v;
- isentrynew[pos] = isnew;
- rowstatus[pos] = statusvb;
- entrycount++;
- }
-
- public void addVarbind(SnmpVarBind varbind, SnmpOid entryoid,
- boolean isnew, SnmpVarBind statusvb)
- throws SnmpStatusException {
- Vector v = null;
- SnmpVarBind rs = statusvb;
-
- if (entryoids == null) {
- // entryoids = new ArrayList();
- // entrylists = new ArrayList();
- // isentrynew = new ArrayList();
- v = new Vector();
- // entryoids.add(entryoid);
- // entrylists.add(v);
- // isentrynew.add(new Boolean(isnew));
- add(0,entryoid,v,isnew,rs);
- } else {
- // int pos = findOid(entryoids,entryoid);
- // int pos = findOid(entryoids,entrycount,entryoid);
- final int pos =
- getInsertionPoint(entryoids,entrycount,entryoid);
- if (pos > -1 && pos < entrycount &&
- entryoid.compareTo(entryoids[pos]) == 0) {
- v = entrylists[pos];
- rs = rowstatus[pos];
- } else {
- // if (pos == -1 || pos >= entryoids.size() ) {
- // if (pos == -1 || pos >= entrycount ) {
- // pos = getInsertionPoint(entryoids,entryoid);
- // pos = getInsertionPoint(entryoids,entrycount,entryoid);
- v = new Vector();
- // entryoids.add(pos,entryoid);
- // entrylists.add(pos,v);
- // isentrynew.add(pos,new Boolean(isnew));
- add(pos,entryoid,v,isnew,rs);
- }
- // } else v = (Vector) entrylists.get(pos);
- // } else v = entrylists[pos];
- if (statusvb != null) {
- if ((rs != null) && (rs != statusvb) &&
- ((type == SnmpDefinitions.pduWalkRequest) ||
- (type == SnmpDefinitions.pduSetRequestPdu))) {
- throw new SnmpStatusException(
- SnmpStatusException.snmpRspInconsistentValue);
- }
- rowstatus[pos] = statusvb;
- }
- }
-
- // We do not include the status variable in the varbind,
- // because we're going to set it separately...
- //
- if (statusvb != varbind)
- v.addElement(varbind);
- }
-
- public int getSubReqCount() {
- int count = 0;
- if (sublist != null) count++;
- // if (entryoids != null) count += entryoids.size();
- if (entryoids != null) count += entrycount;
- return count;
- }
-
- public Vector getSubList() {
- return sublist;
- }
-
- public int getEntryPos(SnmpOid entryoid) {
- // return findOid(entryoids,entryoid);
- return findOid(entryoids,entrycount,entryoid);
- }
-
- public SnmpOid getEntryOid(int pos) {
- if (entryoids == null) return null;
- // if (pos == -1 || pos >= entryoids.size() ) return null;
- if (pos == -1 || pos >= entrycount ) return null;
- // return (SnmpOid) entryoids.get(pos);
- return (SnmpOid) entryoids[pos];
- }
-
- public boolean isNewEntry(int pos) {
- if (entryoids == null) return false;
- // if (pos == -1 || pos >= entryoids.size() ) return false;
- if (pos == -1 || pos >= entrycount ) return false;
- // return ((Boolean)isentrynew.get(pos)).booleanValue();
- return isentrynew[pos];
- }
-
- public SnmpVarBind getRowStatusVarBind(int pos) {
- if (entryoids == null) return null;
- // if (pos == -1 || pos >= entryoids.size() ) return false;
- if (pos == -1 || pos >= entrycount ) return null;
- // return ((Boolean)isentrynew.get(pos)).booleanValue();
- return rowstatus[pos];
- }
-
- public Vector getEntrySubList(int pos) {
- if (entrylists == null) return null;
- // if (pos == -1 || pos >= entrylists.size() ) return null;
- if (pos == -1 || pos >= entrycount ) return null;
- // return (Vector) entrylists.get(pos);
- return entrylists[pos];
- }
-
- public Iterator getEntryOids() {
- if (entryoids == null) return null;
- // return entryoids.iterator();
- return Arrays.asList(entryoids).iterator();
- }
-
- public int getEntryCount() {
- if (entryoids == null) return 0;
- // return entryoids.size();
- return entrycount;
- }
-
- }
-
-
- //-------------------------------------------------------------------
- //-------------------------------------------------------------------
- // Public interface
- //-------------------------------------------------------------------
- //-------------------------------------------------------------------
-
- //-------------------------------------------------------------------
- // Returns the contextual object containing user-data allocated
- // through the SnmpUserDataFactory for this request.
- //-------------------------------------------------------------------
-
- public Object getUserData() { return request.getUserData(); }
-
- //-------------------------------------------------------------------
- // Tells whether creation of new entries is allowed with respect
- // to the operation involved (GET=>false/SET=>true)
- //-------------------------------------------------------------------
-
- public boolean isCreationAllowed() {
- return creationflag;
- }
-
- //-------------------------------------------------------------------
- // Tells whether we are currently processing a SET request (check/set)
- //-------------------------------------------------------------------
-
- public boolean isSetRequest() {
- return setreqflag;
- }
-
- //-------------------------------------------------------------------
- // Returns the protocol version in which the original request is
- // evaluated.
- //-------------------------------------------------------------------
-
- public int getVersion() {
- return version;
- }
-
- //-------------------------------------------------------------------
- // Returns the actual protocol version of the request PDU.
- //-------------------------------------------------------------------
-
- public int getRequestPduVersion() {
- return request.getRequestPduVersion();
- }
-
- //-------------------------------------------------------------------
- // Returns the SnmpMibNode associated with the given handler
- //-------------------------------------------------------------------
-
- public SnmpMibNode getMetaNode(Handler handler) {
- return handler.meta;
- }
-
- //-------------------------------------------------------------------
- // Indicates the depth of the arc in the OID that identifies the
- // SnmpMibNode associated with the given handler
- //-------------------------------------------------------------------
-
- public int getOidDepth(Handler handler) {
- return handler.depth;
- }
-
- //-------------------------------------------------------------------
- // returns an enumeration of the SnmpMibSubRequest's to be invoked on
- // the SnmpMibNode associated with a given Handler node.
- // If this node is a group, there will be a single subrequest.
- // If it is a table, there will be one subrequest per entry involved.
- //-------------------------------------------------------------------
-
- public Enumeration getSubRequests(Handler handler) {
- return new Enum(this,handler);
- }
-
- //-------------------------------------------------------------------
- // returns an enumeration of the Handlers stored in the Hashtable.
- //-------------------------------------------------------------------
-
- public Enumeration getHandlers() {
- return hashtable.elements();
- }
-
- //-------------------------------------------------------------------
- // adds a varbind to a handler node sublist
- //-------------------------------------------------------------------
-
- public void add(SnmpMibNode meta, int depth, SnmpVarBind varbind)
- throws SnmpStatusException {
- registerNode(meta,depth,null,varbind,false,null);
- }
-
- //-------------------------------------------------------------------
- // adds an entry varbind to a handler node sublist
- //-------------------------------------------------------------------
-
- public void add(SnmpMibNode meta, int depth, SnmpOid entryoid,
- SnmpVarBind varbind, boolean isnew)
- throws SnmpStatusException {
- registerNode(meta,depth,entryoid,varbind,isnew,null);
- }
-
- //-------------------------------------------------------------------
- // adds an entry varbind to a handler node sublist - specifying the
- // varbind which holds the row status
- //-------------------------------------------------------------------
-
- public void add(SnmpMibNode meta, int depth, SnmpOid entryoid,
- SnmpVarBind varbind, boolean isnew,
- SnmpVarBind statusvb)
- throws SnmpStatusException {
- registerNode(meta,depth,entryoid,varbind,isnew,statusvb);
- }
-
-
- //-------------------------------------------------------------------
- //-------------------------------------------------------------------
- // Protected interface
- //-------------------------------------------------------------------
- //-------------------------------------------------------------------
-
- //-------------------------------------------------------------------
- // Type of the request (see SnmpDefinitions)
- //-------------------------------------------------------------------
-
- void setPduType(int pduType) {
- type = pduType;
- setreqflag = ((pduType == SnmpDefinitions.pduWalkRequest) ||
- (pduType == SnmpDefinitions.pduSetRequestPdu));
- }
-
- //-------------------------------------------------------------------
- // We deal with a GET-NEXT request
- //-------------------------------------------------------------------
-
- void setGetNextFlag() {
- getnextflag = true;
- }
-
- //-------------------------------------------------------------------
- // Tell whether creation is allowed.
- //-------------------------------------------------------------------
- void switchCreationFlag(boolean flag) {
- creationflag = flag;
- }
-
-
- //-------------------------------------------------------------------
- // Returns the subrequest handled by the SnmpMibNode itself
- // (in principle, only for Groups)
- //-------------------------------------------------------------------
-
- SnmpMibSubRequest getSubRequest(Handler handler) {
- if (handler == null) return null;
- return new SnmpMibSubRequestImpl(request,handler.getSubList(),
- null,false,getnextflag,null);
- }
-
- //-------------------------------------------------------------------
- // Returns the subrequest associated with the entry identified by
- // the given entry (only for tables)
- //-------------------------------------------------------------------
-
- SnmpMibSubRequest getSubRequest(Handler handler, SnmpOid oid) {
- if (handler == null) return null;
- final int pos = handler.getEntryPos(oid);
- if (pos == -1) return null;
- return new SnmpMibSubRequestImpl(request,
- handler.getEntrySubList(pos),
- handler.getEntryOid(pos),
- handler.isNewEntry(pos),
- getnextflag,
- handler.getRowStatusVarBind(pos));
- }
-
- //-------------------------------------------------------------------
- // Returns the subrequest associated with the entry identified by
- // the given entry (only for tables). The `entry' parameter is an
- // index relative to the position of the entry in the handler sublist.
- //-------------------------------------------------------------------
-
- SnmpMibSubRequest getSubRequest(Handler handler, int entry) {
- if (handler == null) return null;
- return new
- SnmpMibSubRequestImpl(request,handler.getEntrySubList(entry),
- handler.getEntryOid(entry),
- handler.isNewEntry(entry),getnextflag,
- handler.getRowStatusVarBind(entry));
- }
-
- //-------------------------------------------------------------------
- //-------------------------------------------------------------------
- // Private section
- //-------------------------------------------------------------------
- //-------------------------------------------------------------------
-
-
- //-------------------------------------------------------------------
- // stores a handler node in the Hashtable
- //-------------------------------------------------------------------
-
- private void put(Object key, Handler handler) {
- if (handler == null) return;
- if (key == null) return;
- if (hashtable == null) hashtable = new Hashtable();
- hashtable.put(key,handler);
- }
-
- //-------------------------------------------------------------------
- // finds a handler node in the Hashtable
- //-------------------------------------------------------------------
-
- private Handler get(Object key) {
- if (key == null) return null;
- if (hashtable == null) return null;
- return (Handler) hashtable.get(key);
- }
-
- //-------------------------------------------------------------------
- // Search for the given oid in `oids'. If none is found, returns -1
- // otherwise, returns the index at which the oid is located.
- //-------------------------------------------------------------------
-
- private static int findOid(SnmpOid[] oids, int count, SnmpOid oid) {
- final int size = count;
- int low= 0;
- int max= size - 1;
- int curr= low + (max-low)/2;
- //System.out.println("Try to retrieve: " + oid.toString());
- while (low <= max) {
-
- final SnmpOid pos = oids[curr];
-
- //System.out.println("Compare with" + pos.toString());
- // never know ...we might find something ...
- //
- final int comp = oid.compareTo(pos);
- if (comp == 0)
- return curr;
-
- if (oid.equals(pos)) {
- return curr;
- }
- if (comp > 0) {
- low = curr + 1;
- } else {
- max = curr - 1;
- }
- curr = low + (max-low)/2;
- }
- return -1;
- }
-
- //-------------------------------------------------------------------
- // Return the index at which the given oid should be inserted in the
- // `oids' array.
- //-------------------------------------------------------------------
-
- private static int getInsertionPoint(SnmpOid[] oids, int count,
- SnmpOid oid) {
- final SnmpOid[] localoids = oids;
- final int size = count;
- int low= 0;
- int max= size - 1;
- int curr= low + (max-low)/2;
-
-
- while (low <= max) {
-
- final SnmpOid pos = localoids[curr];
-
- // never know ...we might find something ...
- //
- final int comp= oid.compareTo(pos);
-
- // In the calling method we will have to check for this case...
- // if (comp == 0)
- // return -1;
- // Returning curr instead of -1 avoids having to call
- // findOid() first and getInsertionPoint() afterwards.
- // We can simply call getInsertionPoint() and then checks whether
- // there's an OID at the returned position which equals the
- // given OID.
- if (comp == 0)
- return curr;
-
- if (comp>0) {
- low= curr +1;
- } else {
- max= curr -1;
- }
- curr= low + (max-low)/2;
- }
- return curr;
- }
-
- //-------------------------------------------------------------------
- // adds a varbind in a handler node sublist
- //-------------------------------------------------------------------
-
- private void registerNode(SnmpMibNode meta, int depth, SnmpOid entryoid,
- SnmpVarBind varbind, boolean isnew,
- SnmpVarBind statusvb)
- throws SnmpStatusException {
- if (meta == null) {
- if (isDebugOn())
- debug("registerNode","meta-node is null!!!");
- return;
- }
- if (varbind == null) {
- if (isDebugOn())
- debug("registerNode","varbind is null!!!");
- return ;
- }
-
- final Object key = meta;
-
- // retrieve the handler node associated with the given meta,
- // if any
- Handler handler = get(key);
-
- // If no handler node was found for that meta, create one.
- if (handler == null) {
- // if (isDebugOn())
- // debug("registerNode", "adding node for " +
- // varbind.oid.toString());
- handler = new Handler(type);
- handler.meta = meta;
- handler.depth = depth;
- put(key,handler);
- }
- // else {
- // if (isDebugOn())
- // debug("registerNode","found node for " +
- // varbind.oid.toString());
- // }
-
- // Adds the varbind in the handler node's sublist.
- if (entryoid == null)
- handler.addVarbind(varbind);
- else
- handler.addVarbind(varbind,entryoid,isnew,statusvb);
- return ;
- }
-
- private final static boolean isDebugOn() {
- return Trace.isSelected(Trace.LEVEL_DEBUG, Trace.INFO_ADAPTOR_SNMP);
- }
-
- private final static void debug(String func, String info) {
- Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_ADAPTOR_SNMP,
- "SnmpRequestTree", func, info);
- }
-
- //-------------------------------------------------------------------
- // private variables
- //-------------------------------------------------------------------
-
- private Hashtable hashtable = null; // Hashtable of Handler objects
- private SnmpMibRequest request = null; // The original list of varbinds
- private int version = 0; // The protocol version
- private boolean creationflag = false; // Does the operation allow
- // creation of entries
- private boolean getnextflag = false; // Does the operation allow
- // creation of entries
- private int type = 0; // Request PDU type as defined
- // in SnmpDefinitions
- private boolean setreqflag = false; // True if we're processing a
- // SET request (check/set).
- }