414 lines · 14.2 KB · Java
RawDownload
/* * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.  Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */  package com.sun.jmx.snmp.agent;   // java imports//import java.io.Serializable;import java.util.Vector;import java.util.Hashtable;import java.util.Enumeration; // jmx imports//import com.sun.jmx.snmp.SnmpOid;import com.sun.jmx.snmp.SnmpValue;import com.sun.jmx.snmp.SnmpVarBind;import com.sun.jmx.snmp.SnmpDefinitions;import com.sun.jmx.snmp.SnmpStatusException; /** * The <CODE>SnmpMibNode</CODE> class represents a node in an SNMP MIB. * <P> * This class is used internally and by the class generated by * <CODE>mibgen</CODE>. * You should not need to use this class directly. * * <p><b>This API is a Sun Microsystems internal API  and is subject * to change without notice.</b></p> */ public abstract class SnmpMibNode implements Serializable {     // ---------------------------------------------------------------------    // PUBLIC METHODS    //----------------------------------------------------------------------     /**     * Get the next OID arc corresponding to a readable scalar variable,     * a branch leading to a subgroub, or a table.     *     * @param id Id we start from looking for the next.     * @param userData A contextual object containing user-data.     *        This object is allocated through the <code>     *        {@link com.sun.jmx.snmp.agent.SnmpUserDataFactory}</code>     *        for each incoming SNMP request.     *     * @return The next id in this group.     *     * @exception SnmpStatusException If no id is found after the given id.     */    public long getNextVarId(long id, Object userData)        throws SnmpStatusException {        return getNextIdentifier(varList,id);    }     /**     * Get the next OID arc corresponding to a readable scalar variable,     * a branch leading to a subgroub, or a table, possibly skipping over     * those arcs that must not or cannot be returned.     *     * Calls {@link #getNextVarId(long,java.lang.Object)} until     * {@link #skipVariable(long,java.lang.Object,int)} returns false.     *     * @param id Id we start from looking for the next.     * @param userData A contextual object containing user-data.     *        This object is allocated through the <code>     *        {@link com.sun.jmx.snmp.agent.SnmpUserDataFactory}</code>     *        for each incoming SNMP request.     * @param pduVersion Protocol version of the original request PDU.     *     * @return The next id in this group which can be returned using     *         the given PDU's protocol version.     *     * @exception SnmpStatusException If no id is found after the given id.     */    public long getNextVarId(long id, Object userData, int pduVersion)        throws SnmpStatusException {        long varid=id;        do {            varid = getNextVarId(varid,userData);        } while (skipVariable(varid,userData,pduVersion));         return varid;    }     /**     * Hook for subclasses.     * The default implementation of this method is to always return     * false. Subclasses should redefine this method so that it returns     * true when:     * <ul><li>the variable is a leaf that is not instantiated,</li>     * <li>or the variable is a leaf whose type cannot be returned by that     *     version of the protocol (e.g. an Counter64 with SNMPv1).</li>     * </ul>     *     * @param id Id we start from looking for the next.     * @param userData A contextual object containing user-data.     *        This object is allocated through the <code>     *        {@link com.sun.jmx.snmp.agent.SnmpUserDataFactory}</code>     *        for each incoming SNMP request.     * @param pduVersion Protocol version of the original request PDU.     *     * @return true if the variable must be skipped by the get-next     *         algorithm.     */    protected boolean skipVariable(long id, Object userData, int pduVersion) {        return false;    }     /**     * Find the node which handles a varbind, and register it in the     * SnmpRequestTree. This method is a pure internal method. You should     * never try to call it directly.     *     * @param varbind  The varbind to be handled     *     * @param oid      The OID array extracted from the varbind     *     * @param depth    The depth reached in the OID at this step of the     *                 processing.     *     * @param handlers The Hashtable in which the varbind will be registered     *                 with its handling node. This hashtable contains     *                 <CODE>SnmpRequestTree.Handler</CODE> items.     *     * @exception SnmpStatusException No handling node was found.     **/    void findHandlingNode(SnmpVarBind varbind,                          long[] oid, int depth,                          SnmpRequestTree handlers)        throws SnmpStatusException {        throw noSuchObjectException;    }     /**     * Find the node which handles the leaf that immediately follows the     * given varbind OID, and register the it in the SnmpRequestTree.     * This method is a pure internal method. You should never try to call     * it directly.     *     * @param varbind  The varbind to be handled     *     * @param oid      The OID array extracted from the varbind     *     * @param depth    The depth reached in the OID at this step of the     *                 processing.     *     * @param handlers The Hashtable in which the varbind will be registered     *                 with its handling node. This hashtable contains     *                 SnmpRequestTree.Handler items.     *     * @return The SnmpOid of the next leaf.     *     * @exception SnmpStatusException No handling node was found.     **/    long[] findNextHandlingNode(SnmpVarBind varbind,                                 long[] oid, int pos, int depth,                                 SnmpRequestTree handlers, AcmChecker checker)        throws SnmpStatusException {        throw noSuchObjectException;    }     /**     * Generic handling of the <CODE>get</CODE> operation.     *     * <p> You can override this method if you need to implement some     * specific policies for minimizing the accesses made to some remote     * underlying resources.     * <p>     *     * @param req   The sub-request that must be handled by this node.     *     * @param depth The depth reached in the OID tree.     *     * @exception SnmpStatusException An error occurred while accessing     *  the MIB node.     */    public abstract void get(SnmpMibSubRequest req, int depth)        throws SnmpStatusException;     /**     * Generic handling of the <CODE>set</CODE> operation.     * <p> You can override this method if you need to implement some     * specific policies for minimizing the accesses made to some remote     * underlying resources.     * <p>     *     * @param req   The sub-request that must be handled by this node.     *     * @param depth The depth reached in the OID tree.     *     * @exception SnmpStatusException An error occurred while accessing     *  the MIB node.     */    public abstract void set(SnmpMibSubRequest req, int depth)        throws SnmpStatusException;     /**     * Generic handling of the <CODE>check</CODE> operation.     * <p> You can override this method if you need to implement some     * specific policies for minimizing the accesses made to some remote     * underlying resources, or if you need to implement some consistency     * checks between the different values provided in the varbind list.     * <p>     *     * @param req   The sub-request that must be handled by this node.     *     * @param depth The depth reached in the OID tree.     *     * @exception SnmpStatusException An error occurred while accessing     *  the MIB node.     */    public abstract void check(SnmpMibSubRequest req, int depth)        throws SnmpStatusException;     /**     * Sorts the specified integer array.     *     * @param array An integer array.     */    static public void sort(int array[]) {        QuickSort(array, 0, array.length - 1);    }     /**     * Computes the root OID of the MIB.     */    public void getRootOid(Vector<Integer> result) {        return;    }     //----------------------------------------------------------------------    // PACKAGE METHODS    //----------------------------------------------------------------------     /**     * This is a generic version of C.A.R Hoare's Quick Sort     * algorithm.  This will handle arrays that are already     * sorted, and arrays with duplicate keys.     *     * If you think of a one dimensional array as going from     * the lowest index on the left to the highest index on the right     * then the parameters to this function are lowest index or     * left and highest index or right.  The first time you call     * this function it will be with the parameters 0, a.length - 1.     *     * @param a An integer array.     * @param lo0 Left boundary of array partition.     * @param hi0 Right boundary of array partition.     */    static void QuickSort(int a[], int lo0, int hi0) {        int lo = lo0;        int hi = hi0;        int mid;         if ( hi0 > lo0) {             /* Arbitrarily establishing partition element as the midpoint of             * the array.             */            mid = a[ ( lo0 + hi0 ) / 2 ];             // loop through the array until indices cross            while( lo <= hi ) {                /* find the first element that is greater than or equal to                 * the partition element starting from the left Index.                 */                while( ( lo < hi0 )  && ( a[lo] < mid ))                    ++lo;                 /* find an element that is smaller than or equal to                 * the partition element starting from the right Index.                 */                while( ( hi > lo0 ) && ( a[hi] > mid ))                    --hi;                 // if the indexes have not crossed, swap                if( lo <= hi ) {                    swap(a, lo, hi);                    ++lo;                    --hi;                }            }             /* If the right index has not reached the left side of array             * must now sort the left partition.             */            if( lo0 < hi )                QuickSort( a, lo0, hi );             /* If the left index has not reached the right side of array             * must now sort the right partition.             */            if( lo < hi0 )                QuickSort( a, lo, hi0 );         }    }     //----------------------------------------------------------------------    // PROTECTED METHODS    //----------------------------------------------------------------------     /**     * This will give the first element greater than <CODE>value</CODE>     * in a sorted array.     * If there is no element of the array greater than <CODE>value</CODE>,     * the method will throw a <CODE>SnmpStatusException</CODE>.     *     * @param table A sorted integer array.     *     * @param value The greatest value.     *     * @exception SnmpStatusException If there is no element greater than     *     <CODE>value</CODE>.     */    final static protected int getNextIdentifier(int table[], long value)        throws SnmpStatusException {         final int[] a = table;        final int val= (int) value;         if (a == null)            throw noSuchObjectException;         int low= 0;        int max= a.length;        int curr= low + (max-low)/2;        int elmt= 0;         // Basic check        //        if (max < 1)            throw noSuchObjectException;         if (a[max-1] <= val)            throw noSuchObjectException;         while (low <= max) {            elmt= a[curr];            if (val == elmt) {                // We ned to get the next index ...                //                curr++;                return a[curr];            }            if (elmt < val) {                low= curr +1;            } else {                max= curr -1;            }            curr= low + (max-low)/2;        }        return a[curr];    }      //----------------------------------------------------------------------    // PRIVATE METHODS    //----------------------------------------------------------------------     final static private void swap(int a[], int i, int j) {        int T;        T = a[i];        a[i] = a[j];        a[j] = T;    }     //----------------------------------------------------------------------    // PROTECTED VARIABLES    //----------------------------------------------------------------------     /**     * Contains the list of variable identifiers.     */    protected int[] varList;     /**     * Contains a predefined exception that is often fired when an     * object is not found in the MIB.     */    static final protected SnmpStatusException noSuchInstanceException =        new SnmpStatusException(SnmpStatusException.noSuchInstance);    static final protected SnmpStatusException noSuchObjectException =        new SnmpStatusException(SnmpStatusException.noSuchObject);    static final protected SnmpStatusException noSuchNameException =        new SnmpStatusException(SnmpDefinitions.snmpRspNoSuchName);}