blob: 66fe5f8a313776f865b5aea175ac353736a27d48 [file] [log] [blame]
/*
* Copyright (c) 1998, 2006, 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.daemon;
// java imports
//
import java.util.Vector;
import java.util.Enumeration;
// jmx imports
//
import com.sun.jmx.snmp.SnmpOid;
// SNMP Runtime imports
//
import com.sun.jmx.snmp.agent.SnmpMibAgent;
/**
* The class is used for building a tree representation of the different
* root oids of the supported MIBs. Each node is associated to a specific MIB.
*/
final class SnmpMibTree {
public SnmpMibTree() {
defaultAgent= null;
root= new TreeNode(-1, null, null);
}
public void setDefaultAgent(SnmpMibAgent def) {
defaultAgent= def;
root.agent= def;
}
public SnmpMibAgent getDefaultAgent() {
return defaultAgent;
}
public void register(SnmpMibAgent agent) {
root.registerNode(agent);
}
public void register(SnmpMibAgent agent, long[] oid) {
root.registerNode(oid, 0, agent);
}
public SnmpMibAgent getAgentMib(SnmpOid oid) {
TreeNode node= root.retrieveMatchingBranch(oid.longValue(), 0);
if (node == null)
return defaultAgent;
else
if(node.getAgentMib() == null)
return defaultAgent;
else
return node.getAgentMib();
}
public void unregister(SnmpMibAgent agent, SnmpOid[] oids) {
for(int i = 0; i < oids.length; i++) {
long[] oid = oids[i].longValue();
TreeNode node = root.retrieveMatchingBranch(oid, 0);
if (node == null)
continue;
node.removeAgent(agent);
}
}
public void unregister(SnmpMibAgent agent) {
root.removeAgentFully(agent);
}
/*
public void unregister(SnmpMibAgent agent) {
long[] oid= agent.getRootOid();
TreeNode node= root.retrieveMatchingBranch(oid, 0);
if (node == null)
return;
node.removeAgent(agent);
}
*/
public void printTree() {
root.printTree(">");
}
private SnmpMibAgent defaultAgent;
private TreeNode root;
// A SnmpMibTree object is a tree of TreeNode
//
final class TreeNode {
void registerNode(SnmpMibAgent agent) {
long[] oid= agent.getRootOid();
registerNode(oid, 0, agent);
}
TreeNode retrieveMatchingBranch(long[] oid, int cursor) {
TreeNode node= retrieveChild(oid, cursor);
if (node == null)
return this;
if (children.size() == 0) {
// In this case, the node does not have any children. So no point to
// continue the search ...
return node;
}
if( cursor + 1 == oid.length) {
// In this case, the oid does not have any more element. So the search
// is over.
return node;
}
TreeNode n = node.retrieveMatchingBranch(oid, cursor + 1);
//If the returned node got a null agent, we have to replace it by
//the current one (in case it is not null)
//
return n.agent == null ? this : n;
}
SnmpMibAgent getAgentMib() {
return agent;
}
public void printTree(String ident) {
StringBuffer buff= new StringBuffer();
if (agents == null) {
return;
}
for(Enumeration e= agents.elements(); e.hasMoreElements(); ) {
SnmpMibAgent mib= (SnmpMibAgent) e.nextElement();
if (mib == null)
buff.append("empty ");
else
buff.append(mib.getMibName() + " ");
}
ident+= " ";
if (children == null) {
return;
}
for(Enumeration e= children.elements(); e.hasMoreElements(); ) {
TreeNode node= (TreeNode) e.nextElement();
node.printTree(ident);
}
}
// PRIVATE STUFF
//--------------
/**
* Only the treeNode class can create an instance of treeNode.
* The creation occurs when registering a new oid.
*/
private TreeNode(long nodeValue, SnmpMibAgent agent, TreeNode sup) {
this.nodeValue= nodeValue;
this.parent= sup;
agents.addElement(agent);
}
private void removeAgentFully(SnmpMibAgent agent) {
Vector<TreeNode> v = new Vector<TreeNode>();
for(Enumeration<TreeNode> e= children.elements();
e.hasMoreElements(); ) {
TreeNode node= e.nextElement();
node.removeAgentFully(agent);
if(node.agents.isEmpty())
v.add(node);
}
for(Enumeration<TreeNode> e= v.elements(); e.hasMoreElements(); ) {
children.removeElement(e.nextElement());
}
removeAgent(agent);
}
private void removeAgent(SnmpMibAgent mib) {
if (!agents.contains(mib))
return;
agents.removeElement(mib);
if (!agents.isEmpty())
agent= agents.firstElement();
}
private void setAgent(SnmpMibAgent agent) {
this.agent = agent;
}
private void registerNode(long[] oid, int cursor, SnmpMibAgent agent) {
if (cursor >= oid.length)
//That's it !
//
return;
TreeNode child = retrieveChild(oid, cursor);
if (child == null) {
// Create a child and register it !
//
long theValue= oid[cursor];
child= new TreeNode(theValue, agent, this);
children.addElement(child);
}
else
if (agents.contains(agent) == false) {
agents.addElement(agent);
}
// We have to set the agent attribute
//
if(cursor == (oid.length - 1)) {
child.setAgent(agent);
}
else
child.registerNode(oid, cursor+1, agent);
}
private TreeNode retrieveChild(long[] oid, int current) {
long theValue= oid[current];
for(Enumeration e= children.elements(); e.hasMoreElements(); ) {
TreeNode node= (TreeNode) e.nextElement();
if (node.match(theValue))
return node;
}
return null;
}
final private boolean match(long value) {
return (nodeValue == value) ? true : false;
}
private Vector<TreeNode> children= new Vector<TreeNode>();
private Vector<SnmpMibAgent> agents= new Vector<SnmpMibAgent>();
private long nodeValue;
private SnmpMibAgent agent;
private TreeNode parent;
}; // end of class TreeNode
}