jdk/src/jdk.snmp/share/classes/com/sun/jmx/snmp/agent/SnmpMib.java
changeset 27193 db6241373358
parent 27175 2c33a5c73a2e
parent 27192 a16236cd61d7
child 27194 48c1741d0f2a
equal deleted inserted replaced
27175:2c33a5c73a2e 27193:db6241373358
     1 /*
       
     2  * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  * questions.
       
    24  */
       
    25 
       
    26 package com.sun.jmx.snmp.agent;
       
    27 
       
    28 import java.io.Serializable;
       
    29 import java.util.Enumeration;
       
    30 import java.util.logging.Level;
       
    31 import java.util.Vector;
       
    32 
       
    33 import javax.management.ObjectName;
       
    34 import javax.management.MBeanServer;
       
    35 import javax.management.MalformedObjectNameException;
       
    36 import javax.management.InstanceAlreadyExistsException;
       
    37 import javax.management.MBeanRegistrationException;
       
    38 import javax.management.NotCompliantMBeanException;
       
    39 
       
    40 import static com.sun.jmx.defaults.JmxProperties.SNMP_ADAPTOR_LOGGER;
       
    41 import com.sun.jmx.snmp.SnmpOid;
       
    42 import com.sun.jmx.snmp.SnmpVarBind;
       
    43 import com.sun.jmx.snmp.SnmpDefinitions;
       
    44 import com.sun.jmx.snmp.SnmpStatusException;
       
    45 
       
    46 /**
       
    47  * Abstract class for representing an SNMP MIB.
       
    48  * <P>
       
    49  * When compiling a SNMP MIB, among all the classes generated by
       
    50  * <CODE>mibgen</CODE>, there is one which extends <CODE>SnmpMib</CODE>
       
    51  * for representing a whole MIB.
       
    52  * <BR>The class is used by the SNMP protocol adaptor as the entry point in
       
    53  * the MIB.
       
    54  *
       
    55  * <p>This generated class can be subclassed in your code in order to
       
    56  * plug in your own specific behaviour.
       
    57  * </p>
       
    58  *
       
    59  * <p><b>This API is a Sun Microsystems internal API  and is subject
       
    60  * to change without notice.</b></p>
       
    61  */
       
    62 @SuppressWarnings("serial") // JDK implementation class
       
    63 public abstract class SnmpMib extends SnmpMibAgent implements Serializable {
       
    64 
       
    65     /**
       
    66      * Default constructor.
       
    67      * Initializes the OID tree.
       
    68      */
       
    69     public SnmpMib() {
       
    70         root= new SnmpMibOid();
       
    71     }
       
    72 
       
    73 
       
    74     // --------------------------------------------------------------------
       
    75     // POLYMORHIC METHODS
       
    76     // --------------------------------------------------------------------
       
    77 
       
    78     /**
       
    79      * <p>
       
    80      * This callback should return the OID associated to the group
       
    81      * identified by the given <code>groupName</code>.
       
    82      * </p>
       
    83      *
       
    84      * <p>
       
    85      * This method is provided as a hook to plug-in some custom
       
    86      * specific behavior. Although doing so is discouraged you might
       
    87      * want to subclass this method in order to store & provide more metadata
       
    88      * information (mapping OID <-> symbolic name) within the agent,
       
    89      * or to "change" the root of the MIB OID by prefixing the
       
    90      * defaultOid by an application dependant OID string, for instance.
       
    91      * </p>
       
    92      *
       
    93      * <p>
       
    94      * The default implementation of this method is to return the given
       
    95      * <code>defaultOid</code>
       
    96      * </p>
       
    97      *
       
    98      * @param groupName   The java-ized name of the SNMP group.
       
    99      * @param defaultOid  The OID defined in the MIB for that group
       
   100      *                    (in dot notation).
       
   101      *
       
   102      * @return The OID of the group identified by <code>groupName</code>,
       
   103      *         in dot-notation.
       
   104      */
       
   105     protected String getGroupOid(String groupName, String defaultOid) {
       
   106         return defaultOid;
       
   107     }
       
   108 
       
   109     /**
       
   110      * <p>
       
   111      * This callback should return the ObjectName associated to the
       
   112      * group identified by the given <code>groupName</code>.
       
   113      * </p>
       
   114      *
       
   115      * <p>
       
   116      * This method is provided as a hook to plug-in some custom
       
   117      * specific behavior. You might want to override this method
       
   118      * in order to provide a different object naming scheme than
       
   119      * that proposed by default by <code>mibgen</code>.
       
   120      * </p>
       
   121      *
       
   122      * <p>
       
   123      * This method is only meaningful if the MIB is registered
       
   124      * in the MBeanServer, otherwise, it will not be called.
       
   125      * </p>
       
   126      *
       
   127      * <p>
       
   128      * The default implementation of this method is to return an ObjectName
       
   129      * built from the given <code>defaultName</code>.
       
   130      * </p>
       
   131      *
       
   132      * @param name  The java-ized name of the SNMP group.
       
   133      * @param oid   The OID returned by getGroupOid() - in dot notation.
       
   134      * @param defaultName The name by default generated by <code>
       
   135      *                    mibgen</code>
       
   136      *
       
   137      * @return The ObjectName of the group identified by <code>name</code>
       
   138      */
       
   139     protected ObjectName getGroupObjectName(String name, String oid,
       
   140                                             String defaultName)
       
   141         throws MalformedObjectNameException {
       
   142         return new ObjectName(defaultName);
       
   143     }
       
   144 
       
   145     /**
       
   146      * <p>
       
   147      * Register an SNMP group and its metadata node in the MIB.
       
   148      * </p>
       
   149      *
       
   150      * <p>
       
   151      * This method is provided as a hook to plug-in some custom
       
   152      * specific behavior. You might want to override this method
       
   153      * if you want to set special links between the MBean, its metadata
       
   154      * node, its OID or ObjectName etc..
       
   155      * </p>
       
   156      *
       
   157      * <p>
       
   158      * If the MIB is not registered in the MBeanServer, the <code>
       
   159      * server</code> and <code>groupObjName</code> parameters will be
       
   160      * <code>null</code>.<br>
       
   161      * If the given group MBean is not <code>null</code>, and if the
       
   162      * <code>server</code> and <code>groupObjName</code> parameters are
       
   163      * not null, then this method will also automatically register the
       
   164      * group MBean with the given MBeanServer <code>server</code>.
       
   165      * </p>
       
   166      *
       
   167      * @param groupName  The java-ized name of the SNMP group.
       
   168      * @param groupOid   The OID as returned by getGroupOid() - in dot
       
   169      *                   notation.
       
   170      * @param groupObjName The ObjectName as returned by getGroupObjectName().
       
   171      *                   This parameter may be <code>null</code> if the
       
   172      *                   MIB is not registered in the MBeanServer.
       
   173      * @param node       The metadata node, as returned by the metadata
       
   174      *                   factory method for this group.
       
   175      * @param group      The MBean for this group, as returned by the
       
   176      *                   MBean factory method for this group.
       
   177      * @param server     The MBeanServer in which the groups are to be
       
   178      *                   registered. This parameter will be <code>null</code>
       
   179      *                   if the MIB is not registered, otherwise it is a
       
   180      *                   reference to the MBeanServer in which the MIB is
       
   181      *                   registered.
       
   182      *
       
   183      */
       
   184     protected void registerGroupNode(String groupName,   String groupOid,
       
   185                                      ObjectName groupObjName, SnmpMibNode node,
       
   186                                      Object group, MBeanServer server)
       
   187         throws NotCompliantMBeanException, MBeanRegistrationException,
       
   188         InstanceAlreadyExistsException, IllegalAccessException {
       
   189         root.registerNode(groupOid,node);
       
   190         if (server != null && groupObjName != null && group != null)
       
   191             server.registerMBean(group,groupObjName);
       
   192     }
       
   193 
       
   194     /**
       
   195      * <p>
       
   196      * Register an SNMP Table metadata node in the MIB.
       
   197      * </p>
       
   198      *
       
   199      * <p>
       
   200      * <b><i>
       
   201      * This method is used internally and you should never need to
       
   202      * call it directly.</i></b><br> It is used to establish the link
       
   203      * between an SNMP table metadata node and its bean-like counterpart.
       
   204      * <br>
       
   205      * The group metadata nodes will create and register their
       
   206      * underlying table metadata nodes in the MIB using this
       
   207      * method. <br>
       
   208      * The metadata nodes will be later retrieved from the MIB by the
       
   209      * bean-like table objects using the getRegisterTableMeta() method.
       
   210      * </p>
       
   211      *
       
   212      * @param name      The java-ized name of the SNMP table.
       
   213      * @param table     The SNMP table metadata node - usually this
       
   214      *                  corresponds to a <code>mibgen</code> generated
       
   215      *                  object.
       
   216      */
       
   217     public abstract void registerTableMeta(String name, SnmpMibTable table);
       
   218 
       
   219     /**
       
   220      * Returns a registered SNMP Table metadata node.
       
   221      *
       
   222      * <p><b><i>
       
   223      * This method is used internally and you should never need to
       
   224      * call it directly.
       
   225      * </i></b></p>
       
   226      *
       
   227      */
       
   228     public abstract SnmpMibTable getRegisteredTableMeta(String name);
       
   229 
       
   230     // --------------------------------------------------------------------
       
   231     // PUBLIC METHODS
       
   232     // --------------------------------------------------------------------
       
   233 
       
   234     /**
       
   235      * Processes a <CODE>get</CODE> operation.
       
   236      *
       
   237      **/
       
   238     // Implements the method defined in SnmpMibAgent. See SnmpMibAgent
       
   239     // for java-doc
       
   240     //
       
   241     @Override
       
   242     public void get(SnmpMibRequest req) throws SnmpStatusException {
       
   243 
       
   244         // Builds the request tree: creation is not allowed, operation
       
   245         // is not atomic.
       
   246 
       
   247         final int reqType = SnmpDefinitions.pduGetRequestPdu;
       
   248         SnmpRequestTree handlers = getHandlers(req,false,false,reqType);
       
   249 
       
   250         SnmpRequestTree.Handler h = null;
       
   251         SnmpMibNode meta = null;
       
   252 
       
   253         if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
       
   254             SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, SnmpMib.class.getName(),
       
   255                     "get", "Processing handlers for GET... ");
       
   256         }
       
   257 
       
   258         // For each sub-request stored in the request-tree, invoke the
       
   259         // get() method.
       
   260         for (Enumeration<SnmpRequestTree.Handler> eh=handlers.getHandlers();eh.hasMoreElements();) {
       
   261             h = eh.nextElement();
       
   262 
       
   263             // Gets the Meta node. It can be either a Group Meta or a
       
   264             // Table Meta.
       
   265             //
       
   266             meta = handlers.getMetaNode(h);
       
   267 
       
   268             // Gets the depth of the Meta node in the OID tree
       
   269             final int depth = handlers.getOidDepth(h);
       
   270 
       
   271             for (Enumeration<SnmpMibSubRequest> rqs=handlers.getSubRequests(h);
       
   272                  rqs.hasMoreElements();) {
       
   273 
       
   274                 // Invoke the get() operation.
       
   275                 meta.get(rqs.nextElement(),depth);
       
   276             }
       
   277         }
       
   278     }
       
   279 
       
   280     /**
       
   281      * Processes a <CODE>set</CODE> operation.
       
   282      *
       
   283      */
       
   284     // Implements the method defined in SnmpMibAgent. See SnmpMibAgent
       
   285     // for java-doc
       
   286     //
       
   287     @Override
       
   288     public void set(SnmpMibRequest req) throws SnmpStatusException {
       
   289 
       
   290         SnmpRequestTree handlers = null;
       
   291 
       
   292         // Optimization: we're going to get the whole SnmpRequestTree
       
   293         // built in the "check" method, so that we don't have to rebuild
       
   294         // it here.
       
   295         //
       
   296         if (req instanceof SnmpMibRequestImpl)
       
   297             handlers = ((SnmpMibRequestImpl)req).getRequestTree();
       
   298 
       
   299         // Optimization didn't work: we have to rebuild the tree.
       
   300         //
       
   301         // Builds the request tree: creation is not allowed, operation
       
   302         // is atomic.
       
   303         //
       
   304         final int reqType = SnmpDefinitions.pduSetRequestPdu;
       
   305         if (handlers == null) handlers = getHandlers(req,false,true,reqType);
       
   306         handlers.switchCreationFlag(false);
       
   307         handlers.setPduType(reqType);
       
   308 
       
   309         SnmpRequestTree.Handler h;
       
   310         SnmpMibNode meta;
       
   311 
       
   312         if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
       
   313             SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, SnmpMib.class.getName(),
       
   314                     "set", "Processing handlers for SET... ");
       
   315         }
       
   316 
       
   317         // For each sub-request stored in the request-tree, invoke the
       
   318         // get() method.
       
   319         for (Enumeration<SnmpRequestTree.Handler> eh=handlers.getHandlers();eh.hasMoreElements();) {
       
   320             h = eh.nextElement();
       
   321 
       
   322             // Gets the Meta node. It can be either a Group Meta or a
       
   323             // Table Meta.
       
   324             //
       
   325             meta = handlers.getMetaNode(h);
       
   326 
       
   327             // Gets the depth of the Meta node in the OID tree
       
   328             final int depth = handlers.getOidDepth(h);
       
   329 
       
   330             for (Enumeration<SnmpMibSubRequest> rqs=handlers.getSubRequests(h);
       
   331                  rqs.hasMoreElements();) {
       
   332 
       
   333                 // Invoke the set() operation
       
   334                 meta.set(rqs.nextElement(),depth);
       
   335             }
       
   336         }
       
   337     }
       
   338 
       
   339     /**
       
   340      * Checks if a <CODE>set</CODE> operation can be performed.
       
   341      * If the operation cannot be performed, the method will raise a
       
   342      * <CODE>SnmpStatusException</CODE>.
       
   343      *
       
   344      */
       
   345     // Implements the method defined in SnmpMibAgent. See SnmpMibAgent
       
   346     // for java-doc
       
   347     //
       
   348     @Override
       
   349     public void check(SnmpMibRequest req) throws SnmpStatusException {
       
   350 
       
   351         final int reqType = SnmpDefinitions.pduWalkRequest;
       
   352         // Builds the request tree: creation is allowed, operation
       
   353         // is atomic.
       
   354         SnmpRequestTree handlers = getHandlers(req,true,true,reqType);
       
   355 
       
   356         SnmpRequestTree.Handler h;
       
   357         SnmpMibNode meta;
       
   358 
       
   359         if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
       
   360             SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, SnmpMib.class.getName(),
       
   361                     "check", "Processing handlers for CHECK... ");
       
   362         }
       
   363 
       
   364         // For each sub-request stored in the request-tree, invoke the
       
   365         // check() method.
       
   366         for (Enumeration<SnmpRequestTree.Handler> eh=handlers.getHandlers();eh.hasMoreElements();) {
       
   367             h = eh.nextElement();
       
   368 
       
   369             // Gets the Meta node. It can be either a Group Meta or a
       
   370             // Table Meta.
       
   371             //
       
   372             meta = handlers.getMetaNode(h);
       
   373 
       
   374             // Gets the depth of the Meta node in the OID tree
       
   375             final int depth = handlers.getOidDepth(h);
       
   376 
       
   377             for (Enumeration<SnmpMibSubRequest> rqs=handlers.getSubRequests(h);
       
   378                  rqs.hasMoreElements();) {
       
   379 
       
   380                 // Invoke the check() operation
       
   381                 meta.check(rqs.nextElement(),depth);
       
   382             }
       
   383         }
       
   384 
       
   385         // Optimization: we're going to pass the whole SnmpRequestTree
       
   386         // to the "set" method, so that we don't have to rebuild it there.
       
   387         //
       
   388         if (req instanceof SnmpMibRequestImpl) {
       
   389             ((SnmpMibRequestImpl)req).setRequestTree(handlers);
       
   390         }
       
   391 
       
   392     }
       
   393 
       
   394     /**
       
   395      * Processes a <CODE>getNext</CODE> operation.
       
   396      *
       
   397      */
       
   398     // Implements the method defined in SnmpMibAgent. See SnmpMibAgent
       
   399     // for java-doc
       
   400     //
       
   401     @Override
       
   402     public void getNext(SnmpMibRequest req) throws SnmpStatusException {
       
   403         // Build the request tree for the operation
       
   404         // The subrequest stored in the request tree are valid GET requests
       
   405         SnmpRequestTree handlers = getGetNextHandlers(req);
       
   406 
       
   407         SnmpRequestTree.Handler h;
       
   408         SnmpMibNode meta;
       
   409 
       
   410         if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
       
   411             SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, SnmpMib.class.getName(),
       
   412                     "getNext", "Processing handlers for GET-NEXT... ");
       
   413         }
       
   414 
       
   415         // Now invoke get() for each subrequest of the request tree.
       
   416         for (Enumeration<SnmpRequestTree.Handler> eh=handlers.getHandlers();eh.hasMoreElements();) {
       
   417             h = eh.nextElement();
       
   418 
       
   419             // Gets the Meta node. It can be either a Group Meta or a
       
   420             // Table Meta.
       
   421             //
       
   422             meta = handlers.getMetaNode(h);
       
   423 
       
   424             // Gets the depth of the Meta node in the OID tree
       
   425             int depth = handlers.getOidDepth(h);
       
   426 
       
   427             for (Enumeration<SnmpMibSubRequest> rqs=handlers.getSubRequests(h);
       
   428                  rqs.hasMoreElements();) {
       
   429 
       
   430                 // Invoke the get() operation
       
   431                 meta.get(rqs.nextElement(),depth);
       
   432             }
       
   433         }
       
   434     }
       
   435 
       
   436 
       
   437     /**
       
   438      * Processes a <CODE>getBulk</CODE> operation.
       
   439      * The method implements the <CODE>getBulk</CODE> operation by calling
       
   440      * appropriately the <CODE>getNext</CODE> method.
       
   441      *
       
   442      */
       
   443     // Implements the method defined in SnmpMibAgent. See SnmpMibAgent
       
   444     // for java-doc
       
   445     //
       
   446     @Override
       
   447     public void getBulk(SnmpMibRequest req, int nonRepeat, int maxRepeat)
       
   448         throws SnmpStatusException {
       
   449 
       
   450         getBulkWithGetNext(req, nonRepeat, maxRepeat);
       
   451     }
       
   452 
       
   453     /**
       
   454      * Gets the root object identifier of the MIB.
       
   455      * <P>In order to be accurate, the method should be called once the
       
   456      * MIB is fully initialized (that is, after a call to <CODE>init</CODE>
       
   457      * or <CODE>preRegister</CODE>).
       
   458      *
       
   459      * @return The root object identifier.
       
   460      */
       
   461     @Override
       
   462     public long[] getRootOid() {
       
   463 
       
   464         if( rootOid == null) {
       
   465             Vector<Integer> list= new Vector<>(10);
       
   466 
       
   467             // Ask the tree to do the job !
       
   468             //
       
   469             root.getRootOid(list);
       
   470 
       
   471             // Now format the result
       
   472             //
       
   473             rootOid= new long[list.size()];
       
   474             int i=0;
       
   475             for(Enumeration<Integer> e= list.elements(); e.hasMoreElements(); ) {
       
   476                 Integer val= e.nextElement();
       
   477                 rootOid[i++]= val.longValue();
       
   478             }
       
   479         }
       
   480         return rootOid.clone();
       
   481     }
       
   482 
       
   483     // --------------------------------------------------------------------
       
   484     // PRIVATE METHODS
       
   485     //---------------------------------------------------------------------
       
   486 
       
   487     /**
       
   488      * This method builds the temporary request-tree that will be used to
       
   489      * perform the SNMP request associated with the given vector of varbinds
       
   490      * `list'.
       
   491      *
       
   492      * @param req The SnmpMibRequest object holding the varbind list
       
   493      *             concerning this MIB.
       
   494      * @param createflag Indicates whether the operation allow for creation
       
   495      *        of new instances (ie: it is a SET).
       
   496      * @param atomic Indicates whether the operation is atomic or not.
       
   497      * @param type Request type (from SnmpDefinitions).
       
   498      *
       
   499      * @return The request-tree where the original varbind list has been
       
   500      *         dispatched to the appropriate nodes.
       
   501      */
       
   502     private SnmpRequestTree getHandlers(SnmpMibRequest req,
       
   503                                         boolean createflag, boolean atomic,
       
   504                                         int type)
       
   505         throws SnmpStatusException {
       
   506 
       
   507         // Build an empty request tree
       
   508         SnmpRequestTree handlers =
       
   509             new SnmpRequestTree(req,createflag,type);
       
   510 
       
   511         int index=0;
       
   512         SnmpVarBind var;
       
   513         final int ver= req.getVersion();
       
   514 
       
   515         // For each varbind in the list finds its handling node.
       
   516         for (Enumeration<SnmpVarBind> e= req.getElements(); e.hasMoreElements(); index++) {
       
   517 
       
   518             var= e.nextElement();
       
   519 
       
   520             try {
       
   521                 // Find the handling node for this varbind.
       
   522                 root.findHandlingNode(var,var.oid.longValue(false),
       
   523                                       0,handlers);
       
   524             } catch(SnmpStatusException x) {
       
   525 
       
   526                 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
       
   527                     SNMP_ADAPTOR_LOGGER.logp(Level.FINEST,
       
   528                             SnmpMib.class.getName(),
       
   529                             "getHandlers",
       
   530                             "Couldn't find a handling node for " +
       
   531                             var.oid.toString());
       
   532                 }
       
   533 
       
   534                 // If the operation is atomic (Check/Set) or the version
       
   535                 // is V1 we must generate an exception.
       
   536                 //
       
   537                 if (ver == SnmpDefinitions.snmpVersionOne) {
       
   538 
       
   539                     if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
       
   540                         SNMP_ADAPTOR_LOGGER.logp(Level.FINEST,
       
   541                                 SnmpMib.class.getName(),
       
   542                                 "getHandlers", "\tV1: Throwing exception");
       
   543                     }
       
   544 
       
   545                     // The index in the exception must correspond to the
       
   546                     // SNMP index ...
       
   547                     //
       
   548                     final SnmpStatusException sse =
       
   549                         new SnmpStatusException(x, index + 1);
       
   550                     sse.initCause(x);
       
   551                     throw sse;
       
   552                 } else if ((type == SnmpDefinitions.pduWalkRequest)   ||
       
   553                            (type == SnmpDefinitions.pduSetRequestPdu)) {
       
   554                     final int status =
       
   555                         SnmpRequestTree.mapSetException(x.getStatus(),ver);
       
   556 
       
   557                     if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
       
   558                         SNMP_ADAPTOR_LOGGER.logp(Level.FINEST,
       
   559                                 SnmpMib.class.getName(),
       
   560                                 "getHandlers", "\tSET: Throwing exception");
       
   561                     }
       
   562 
       
   563                     final SnmpStatusException sse =
       
   564                         new SnmpStatusException(status, index + 1);
       
   565                     sse.initCause(x);
       
   566                     throw sse;
       
   567                 } else if (atomic) {
       
   568 
       
   569                     // Should never come here...
       
   570                     if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
       
   571                         SNMP_ADAPTOR_LOGGER.logp(Level.FINEST,
       
   572                                 SnmpMib.class.getName(),
       
   573                                 "getHandlers", "\tATOMIC: Throwing exception");
       
   574                     }
       
   575 
       
   576                     final SnmpStatusException sse =
       
   577                         new SnmpStatusException(x, index + 1);
       
   578                     sse.initCause(x);
       
   579                     throw sse;
       
   580                 }
       
   581 
       
   582                 final int status =
       
   583                     SnmpRequestTree.mapGetException(x.getStatus(),ver);
       
   584 
       
   585                 if (status == SnmpStatusException.noSuchInstance) {
       
   586 
       
   587                     if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
       
   588                         SNMP_ADAPTOR_LOGGER.logp(Level.FINEST,
       
   589                                 SnmpMib.class.getName(),
       
   590                                 "getHandlers",
       
   591                                 "\tGET: Registering noSuchInstance");
       
   592                     }
       
   593 
       
   594                     var.value= SnmpVarBind.noSuchInstance;
       
   595 
       
   596                 } else if (status == SnmpStatusException.noSuchObject) {
       
   597                     if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
       
   598                         SNMP_ADAPTOR_LOGGER.logp(Level.FINEST,
       
   599                                 SnmpMib.class.getName(),
       
   600                                 "getHandlers",
       
   601                                 "\tGET: Registering noSuchObject");
       
   602                     }
       
   603 
       
   604                         var.value= SnmpVarBind.noSuchObject;
       
   605 
       
   606                 } else {
       
   607 
       
   608                     if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
       
   609                         SNMP_ADAPTOR_LOGGER.logp(Level.FINEST,
       
   610                                 SnmpMib.class.getName(),
       
   611                                 "getHandlers",
       
   612                                 "\tGET: Registering global error: " + status);
       
   613                     }
       
   614 
       
   615                     final SnmpStatusException sse =
       
   616                         new SnmpStatusException(status, index + 1);
       
   617                     sse.initCause(x);
       
   618                     throw sse;
       
   619                 }
       
   620             }
       
   621         }
       
   622         return handlers;
       
   623     }
       
   624 
       
   625     /**
       
   626      * This method builds the temporary request-tree that will be used to
       
   627      * perform the SNMP GET-NEXT request associated with the given vector
       
   628      * of varbinds `list'.
       
   629      *
       
   630      * @param req The SnmpMibRequest object holding the varbind list
       
   631      *             concerning this MIB.
       
   632      *
       
   633      * @return The request-tree where the original varbind list has been
       
   634      *         dispatched to the appropriate nodes, and where the original
       
   635      *         OIDs have been replaced with the correct "next" OID.
       
   636      */
       
   637     private SnmpRequestTree getGetNextHandlers(SnmpMibRequest req)
       
   638         throws SnmpStatusException {
       
   639 
       
   640         // Creates an empty request tree, no entry creation is allowed (false)
       
   641         SnmpRequestTree handlers = new
       
   642             SnmpRequestTree(req,false,SnmpDefinitions.pduGetNextRequestPdu);
       
   643 
       
   644         // Sets the getNext flag: if version=V2, status exception are
       
   645         // transformed in  endOfMibView
       
   646         handlers.setGetNextFlag();
       
   647 
       
   648         if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
       
   649             SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, SnmpMib.class.getName(),
       
   650                     "getGetNextHandlers", "Received MIB request : " + req);
       
   651         }
       
   652         AcmChecker checker = new AcmChecker(req);
       
   653         int index=0;
       
   654         SnmpVarBind var = null;
       
   655         final int ver= req.getVersion();
       
   656         SnmpOid original = null;
       
   657         // For each varbind, finds the handling node.
       
   658         // This function has the side effect of transforming a GET-NEXT
       
   659         // request into a valid GET request, replacing the OIDs in the
       
   660         // original GET-NEXT request with the OID of the first leaf that
       
   661         // follows.
       
   662         for (Enumeration<SnmpVarBind> e= req.getElements(); e.hasMoreElements(); index++) {
       
   663 
       
   664             var = e.nextElement();
       
   665             SnmpOid result;
       
   666             try {
       
   667                 // Find the node handling the OID that follows the varbind
       
   668                 // OID. `result' contains this next leaf OID.
       
   669                 //ACM loop.
       
   670                 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
       
   671                     SNMP_ADAPTOR_LOGGER.logp(Level.FINEST,
       
   672                             SnmpMib.class.getName(),
       
   673                             "getGetNextHandlers", " Next OID of : " + var.oid);
       
   674                 }
       
   675                 result = new SnmpOid(root.findNextHandlingNode
       
   676                                      (var,var.oid.longValue(false),0,
       
   677                                       0,handlers, checker));
       
   678 
       
   679                 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
       
   680                     SNMP_ADAPTOR_LOGGER.logp(Level.FINEST,
       
   681                             SnmpMib.class.getName(),
       
   682                             "getGetNextHandlers", " is : " + result);
       
   683                 }
       
   684                 // We replace the varbind original OID with the OID of the
       
   685                 // leaf object we have to return.
       
   686                 var.oid = result;
       
   687             } catch(SnmpStatusException x) {
       
   688 
       
   689                 // if (isDebugOn())
       
   690                 //    debug("getGetNextHandlers",
       
   691                 //        "Couldn't find a handling node for "
       
   692                 //        + var.oid.toString());
       
   693 
       
   694                 if (ver == SnmpDefinitions.snmpVersionOne) {
       
   695                     if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
       
   696                         SNMP_ADAPTOR_LOGGER.logp(Level.FINEST,
       
   697                                 SnmpMib.class.getName(),
       
   698                                 "getGetNextHandlers",
       
   699                                 "\tThrowing exception " + x.toString());
       
   700                     }
       
   701                     // The index in the exception must correspond to the
       
   702                     // SNMP index ...
       
   703                     //
       
   704                     throw new SnmpStatusException(x, index + 1);
       
   705                 }
       
   706                 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
       
   707                     SNMP_ADAPTOR_LOGGER.logp(Level.FINEST,
       
   708                             SnmpMib.class.getName(),
       
   709                             "getGetNextHandlers",
       
   710                             "Exception : " + x.getStatus());
       
   711                 }
       
   712 
       
   713                 var.setSnmpValue(SnmpVarBind.endOfMibView);
       
   714             }
       
   715         }
       
   716         return handlers;
       
   717     }
       
   718 
       
   719     // --------------------------------------------------------------------
       
   720     // PROTECTED VARIABLES
       
   721     // --------------------------------------------------------------------
       
   722 
       
   723     /**
       
   724      * The top element in the Mib tree.
       
   725      * @serial
       
   726      */
       
   727     protected SnmpMibOid root;
       
   728 
       
   729 
       
   730     // --------------------------------------------------------------------
       
   731     // PRIVATE VARIABLES
       
   732     // --------------------------------------------------------------------
       
   733 
       
   734     /**
       
   735      * The root object identifier of the MIB.
       
   736      */
       
   737     private transient long[] rootOid= null;
       
   738 }