Package com.sun.jmx.snmp.agent

Source Code of com.sun.jmx.snmp.agent.SnmpRequestTree$Handler

/*
* @(#)file      SnmpRequestTree.java
* @(#)author    Sun Microsystems, Inc.
* @(#)version   1.27
* @(#)date      09/10/11
*
* Copyright 2006 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).
}
TOP

Related Classes of com.sun.jmx.snmp.agent.SnmpRequestTree$Handler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.