| /* |
| * 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); |
| } |