FileDocCategorySizeDatePackage
SnmpMibOid.javaAPI DocJava SE 5 API15986Fri Aug 26 14:55:04 BST 2005com.sun.jmx.snmp.agent

SnmpMibOid

public class SnmpMibOid extends SnmpMibNode implements Serializable
Represents a node in an SNMP MIB which is neither a group nor a variable. This class defines a list of sub-nodes and the methods that allow to manipulate the sub-nodes.

This class is used internally and by the class generated by mibgen. You should not need to use this class directly.

This API is a Sun Microsystems internal API and is subject to change without notice.

version
4.21 02/25/04
author
Sun Microsystems, Inc

Fields Summary
private NonSyncVector
children
Contains the list of sub nodes.
private int
nbChildren
The number of sub nodes.
Constructors Summary
public SnmpMibOid()
Default constructor.

    
Methods Summary
public voidcheck(SnmpMibSubRequest req, int depth)
Generic handling of the check operation.

This method should be overridden in subclasses.

param
req The sub-request that must be handled by this node.
param
depth The depth reached in the OID tree.
exception
SnmpStatusException The default implementation (if not overriden) is to generate a SnmpStatusException.

        for (Enumeration e= req.getElements(); e.hasMoreElements();) {
            SnmpVarBind var= (SnmpVarBind) e.nextElement(); 
	    SnmpStatusException x = 
		new SnmpStatusException(SnmpStatusException.noAccess);
	    req.registerCheckException(var,x);
	}
    
voidexportChildren(com.sun.jmx.snmp.agent.SnmpMibOid brother)
Export this node's children to a brother node that will replace this node in the OID tree. This method is a patch that fixes the problem of registering a subnode before its father node.

	
	if (brother == null) return;
	final long[] oid = new long[1];
	for (int i=0; i<nbChildren; i++) {
	    final SnmpMibNode child = (SnmpMibNode)children.elementAt(i);
	    if (child == null) continue;
	    oid[0] = varList[i];
	    brother.registerNode(oid,0,child);
	}
    
voidfindHandlingNode(com.sun.jmx.snmp.SnmpVarBind varbind, long[] oid, int depth, SnmpRequestTree handlers)



	final int length = oid.length;
	SnmpMibNode node = null;
	
	if (handlers == null)
            throw new SnmpStatusException(SnmpStatusException.snmpRspGenErr);

	if (depth > length) {
	    // Nothing is left... the oid is not valid
            throw noSuchObjectException;

	} else if (depth == length) {
	    // The oid is not complete...
	    throw noSuchInstanceException;

	} else {
	    // Some children variable or subobject is being querried
	    // getChild() will raise an exception if no child is found.
	    // 
	    final SnmpMibNode child= getChild(oid[depth]);

	    // XXXX zzzz : what about null children? 
	    //             (variables for nested groups)
	    // if child==null, then we're dealing with a variable or
	    // a table: we register this node. 
	    // This behaviour should be overriden in subclasses,
	    // in particular in group meta classes: the group
	    // meta classes that hold tables should take care
	    // of forwarding this call to all the tables involved.
	    //
	    if (child == null)  
		handlers.add(this,depth,varbind);
	    else 
		child.findHandlingNode(varbind,oid,depth+1,handlers);
	}
    
long[]findNextHandlingNode(com.sun.jmx.snmp.SnmpVarBind varbind, long[] oid, int pos, int depth, SnmpRequestTree handlers, AcmChecker checker)



	final int length = oid.length;
	SnmpMibNode node = null;
	long[] result = null;
	if (handlers == null)
	    // This should be considered as a genErr, but we do not want to
	    // abort the whole request, so we're going to throw
	    // a noSuchObject...
	    //
            throw noSuchObjectException;

	final Object data = handlers.getUserData();
	final int pduVersion = handlers.getRequestPduVersion();

        if (pos >= length) {
            long[] newOid= new long[1];
	    newOid[0]=  getNextVarId(-1,data,pduVersion);
            result = findNextHandlingNode(varbind,newOid,0,depth,handlers,
					  checker);
	    return result;
        }

        // search the element specified in the oid
        //
        long[] newOid= new long[1];
        long index= oid[pos];
   
        while (true) {
     
            try {
                final SnmpMibNode child = getChild(index);
		// SnmpOid result = null;
		if (child == null) {
		    // shouldn't happen
		    throw noSuchObjectException;
		    // validateVarId(index);
		    // handlers.add(this,varbind,depth);
		    // result = new SnmpOid(0);
		} else {
		    checker.add(depth, index);
		    try {
			result = child.findNextHandlingNode(varbind,oid,pos+1,
							    depth+1,handlers, 
							    checker);
		    } finally {
			checker.remove(depth);
		    } 
		}
		
		// Build up the leaf OID
                result[depth] = index;
                return result;
		
            } catch(SnmpStatusException e) {
                // If there is no such element go one level up ...
                //
                index= getNextVarId(index,data,pduVersion);

                // There is no need to carry the original oid ...
                newOid[0]=index;
                pos= 1;
                oid=newOid;	
            }
        }
    
public voidget(SnmpMibSubRequest req, int depth)
Generic handling of the get operation.

This method should be overridden in subclasses.

param
req The sub-request that must be handled by this node.
param
depth The depth reached in the OID tree.
exception
SnmpStatusException The default implementation (if not overridden) is to generate a SnmpStatusException.

        for (Enumeration e= req.getElements(); e.hasMoreElements();) {
            SnmpVarBind var= (SnmpVarBind) e.nextElement(); 
	    SnmpStatusException x = 
		new SnmpStatusException(SnmpStatusException.noSuchObject);
	    req.registerGetException(var,x);
	}
    
SnmpMibNodegetChild(long id)

        
        // first we need to retrieve the identifier in the list of children 
        //
        final int pos= getInsertAt(id);
        if (pos >= nbChildren)
            throw noSuchObjectException;
    
        if (varList[pos] != (int) id) 
            throw noSuchObjectException;

        // Access the node
        //
	SnmpMibNode child = null;
        try {
            child = (SnmpMibNode) children.elementAtNonSync(pos);
        } catch(ArrayIndexOutOfBoundsException e) {
            throw noSuchObjectException;
        }
	if (child == null) 
            throw noSuchInstanceException;
	return child;
    
private intgetInsertAt(long val)

        
        int low= 0;
        final int index= (int) val;
	if (varList == null) 
            return -1;
        int max= varList.length -1 ;
        int elmt=0;
	//final int[] v = varList;

        //if (index > a[max])
        //return max +1;
    
  
        int curr= low + (max-low)/2;    
        while (low <= max) {

            elmt= varList[curr];

            // never know ...we might find something ...
            // 
            if (index == elmt)
                return curr;

            if (elmt < index) {
                low= curr +1;
            } else {
                max= curr -1;
            }  
            curr= low + (max-low)/2;
        }

        return curr;
    
public voidgetRootOid(java.util.Vector result)
Computes the root OID of the MIB.


        // If a node has several children, let assume that we are one step to
        // far in order to get the MIB root.
        //
        if (nbChildren != 1)
            return;
        
        result.addElement(new Integer(varList[0]));

        // Now query our child.
        //
        ((SnmpMibNode)children.firstElement()).getRootOid(result);
    
    
public voidregisterNode(java.lang.String oidString, SnmpMibNode node)
Registers a specific node in the tree.

        SnmpOid oid= new SnmpOid(oidString);
        registerNode(oid.longValue(), 0, node);
    
voidregisterNode(long[] oid, int cursor, SnmpMibNode node)
Registers a specific node in the tree.

        
        if (cursor >= oid.length)
            throw new IllegalAccessException();
    
        // Check if the node is already defined 
        //
        long var= oid[cursor];

        //System.out.println("entering registration for val=" 
	// + String.valueOf(var) + " position= " + cursor);

        int pos = retrieveIndex(var);
        if (pos  == nbChildren) {
            nbChildren++;
            varList= new int[nbChildren];
            varList[0]= (int) var;
            pos =0;
            if ( (cursor + 1) == oid.length) {
                // That 's the end of the trip. 
		// Do not forward the registration 

                //System.out.println("End of trip for val=" 
		//      + String.valueOf(var) + " position= " + cursor);
                children.insertElementAt(node,pos);
                return;
            }

            //System.out.println("Create node for val=" 
	    //       + String.valueOf(var) + " position= " + cursor);
            SnmpMibOid child= new SnmpMibOid();
            children.insertElementAt(child, pos);
            child.registerNode(oid, cursor + 1, node);
            return;
        }
        if (pos == -1) {
            // The node is not yet registered
            //
            int[] tmp= new int[nbChildren + 1];
            tmp[nbChildren]= (int) var;
            System.arraycopy(varList, 0, tmp, 0, nbChildren);
            varList= tmp;
            nbChildren++;
            SnmpMibNode.sort(varList);
            int newPos = retrieveIndex(var);
            varList[newPos]= (int) var;
            if ( (cursor + 1) == oid.length) {
                // That 's the end of the trip.
		// Do not forward the registration 
                
                //System.out.println("End of trip for val=" 
		//     + String.valueOf(var) + " position= " + cursor);
                children.insertElementAt(node, newPos);
                return;
            }
            SnmpMibOid child= new SnmpMibOid();
            // System.out.println("Create node for val=" + 
	    //     String.valueOf(var) + " position= " + cursor);
            children.insertElementAt(child, newPos);
            child.registerNode(oid, cursor + 1, node);
            return;
        } 
        else {
            // The node is already registered
            //
            SnmpMibNode child= (SnmpMibNode) children.elementAt(pos);
            if ( (cursor + 1) == oid.length ) {
                //System.out.println("Node already registered val=" + 
		//          String.valueOf(var) + " position= " + cursor);
		if (child == node) return;
		if (child != null && node != null) {
		    // Now we're going to patch the tree the following way:
		    //   if a subgroup has been registered before its father,
		    //   we're going to replace the father OID node with 
		    //   the actual group-node and export the children from 
		    //   the temporary OID node to the actual group node.
		    //

		    if (node instanceof SnmpMibGroup) {
			// `node' is a group => replace `child' with `node'
			// export the child's subtree to `node'.
			//
			((SnmpMibOid)child).exportChildren((SnmpMibOid)node);
			children.setElementAt(node,pos);
			return;

		    } else if ((node instanceof SnmpMibOid) &&
			     (child instanceof SnmpMibGroup)) {
			// `node' is a temporary node, and `child' is a 
			//  group => keep child and export the node's 
			//  subtree to `child'.
			//
			((SnmpMibOid)node).exportChildren((SnmpMibOid)child);
			return;
		    } else if (node instanceof SnmpMibOid) {
			// `node' and `child' are both temporary OID nodes
			// => replace `child' with `node' and export child's
			// subtree to `node'.
			//
			((SnmpMibOid)child).exportChildren((SnmpMibOid)node);
			children.setElementAt(node,pos);
			return;
		    }
		}
		children.setElementAt(node,pos);
                return;
            } else {
		if (child == null)
		    throw new IllegalAccessException();
                ((SnmpMibOid)child).registerNode(oid, cursor + 1, node);
            }
        }
    
private intretrieveIndex(long val)


        int low= 0;
        int cursor= (int) val;
	if (varList == null || varList.length < 1) 
	    return nbChildren;

        int max= varList.length -1 ;
        int curr= low + (max-low)/2;
        int elmt= 0;
        while (low <= max) {
            elmt= varList[curr];
            if (cursor == elmt) {
                // We need to get the next index ...
                //
                return curr;
            }  
            if (elmt < cursor) {
                low= curr +1;
            } else {
                max= curr -1;
            }  
            curr= low + (max-low)/2;
        }
        return -1;
    
public voidset(SnmpMibSubRequest req, int depth)
Generic handling of the set operation.

This method should be overridden in subclasses.

param
req The sub-request that must be handled by this node.
param
depth The depth reached in the OID tree.
exception
SnmpStatusException The default implementation (if not overridden) is to generate a SnmpStatusException.

        for (Enumeration e= req.getElements(); e.hasMoreElements();) {
            SnmpVarBind var= (SnmpVarBind) e.nextElement(); 
	    SnmpStatusException x = 
		new SnmpStatusException(SnmpStatusException.noAccess);
	    req.registerSetException(var,x);
	}