/******************************************************************************* * This file is part of OpenNMS(R). * * Copyright (C) 2011 The OpenNMS Group, Inc. * OpenNMS(R) is Copyright (C) 1999-2011 The OpenNMS Group, Inc. * * OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc. * * OpenNMS(R) is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published * by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * OpenNMS(R) 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 for more details. * * You should have received a copy of the GNU General Public License * along with OpenNMS(R). If not, see: * http://www.gnu.org/licenses/ * * For more information contact: * OpenNMS(R) Licensing <license@opennms.org> * http://www.opennms.org/ * http://www.opennms.com/ *******************************************************************************/ package org.opennms.netmgt.snmp; import java.util.StringTokenizer; public class SnmpObjId implements Comparable<SnmpObjId> { /* FIXME: Change the implementation of this to cache oids and share common prefixes * This should enhance the amount of garbage we generate a great deal at least for * this class. */ private int[] m_ids; /** * These constructors are private. The get method should be called to create a new oid */ protected SnmpObjId(int[] ids, boolean clone) { m_ids = (clone ? cloneIds(ids) : ids); } /** * These constructors are private. The get method should be called to create a new oid */ protected SnmpObjId(int[] ids) { this(ids, true); } /** * These constructors are private. The get method should be called to create a new oid */ protected SnmpObjId(String oid) { this(convertStringToInts(oid), false); } /** * These constructors are private. The get method should be called to create a new oid */ protected SnmpObjId(SnmpObjId oid) { this(oid.m_ids); } /** * These constructors are private. The get method should be called to create a new oid */ private SnmpObjId(String objId, String instance) { this(appendArrays(convertStringToInts(objId), convertStringToInts(instance)), false); } /** * These constructors are private. The get method should be called to create a new oid */ private SnmpObjId(SnmpObjId objId, String instance) { this(appendArrays(objId.m_ids, convertStringToInts(instance)), false); } /** * These constructors are private. The get method should be called to create a new oid */ private SnmpObjId(SnmpObjId objId, SnmpObjId instance) { this(appendArrays(objId.m_ids, instance.m_ids), false); } public int[] getIds() { return cloneIds(m_ids); } private static int[] cloneIds(int[] ids) { return cloneIds(ids, ids.length); } private static int[] cloneIds(int[] ids, int lengthToClone) { int len = Math.min(lengthToClone, ids.length); int[] newIds = new int[len]; System.arraycopy(ids, 0, newIds, 0, len); return newIds; } private static int[] convertStringToInts(String oid) { oid = oid.trim(); if (oid.startsWith(".")) { oid = oid.substring(1); } final StringTokenizer tokenizer = new StringTokenizer(oid, "."); int[] ids = new int[tokenizer.countTokens()]; int index = 0; while (tokenizer.hasMoreTokens()) { try { String tok = tokenizer.nextToken(); ids[index] = Integer.parseInt(tok); if (ids[index] < 0) throw new IllegalArgumentException("String "+oid+" could not be converted to a SnmpObjId. It has a negative for subId "+index); index++; } catch(NumberFormatException e) { throw new IllegalArgumentException("String "+oid+" could not be converted to a SnmpObjId at subId "+index); } } return ids; } public boolean equals(Object obj) { if (obj instanceof SnmpObjId) return compareTo((SnmpObjId)obj) == 0; else return false; } public int hashCode() { return 0; } public String toString() { StringBuffer buf = new StringBuffer(length()*2+10); // a guess at the str len for(int i = 0; i < length(); i++) { if (i != 0 || addPrefixDotInToString()) { buf.append('.'); } buf.append(m_ids[i]); } return buf.toString(); } protected boolean addPrefixDotInToString() { return true; } public int compareTo(SnmpObjId o) { if (o == null) throw new NullPointerException("o is null"); SnmpObjId other = (SnmpObjId)o; // compare each element in order for as much length as they have in common // which is the entire length of one or both oids int minLen = Math.min(length(), other.length()); for(int i = 0; i < minLen; i++) { int diff = m_ids[i] - other.m_ids[i]; // the first one that is not equal indicates which is bigger if (diff != 0) return diff; } // if they get to hear then both are identifical for their common length // so which ever is longer is then greater return length() - other.length(); } public SnmpObjId append(String inst) { return append(convertStringToInts(inst)); } public SnmpObjId append(SnmpObjId inst) { return append(inst.m_ids); } public SnmpObjId append(int[] instIds) { int[] ids = appendArrays(m_ids, instIds); return new SnmpObjId(ids, false); } private static int[] appendArrays(int[] objIds, int[] instIds) { int[] ids = new int[objIds.length+instIds.length]; System.arraycopy(objIds, 0, ids, 0, objIds.length); System.arraycopy(instIds, 0, ids, objIds.length, instIds.length); return ids; } public static SnmpObjId get(String oid) { return new SnmpObjId(oid); } public static SnmpObjId get(int[] ids) { return new SnmpObjId(ids); } public static SnmpObjId get(SnmpObjId oid) { return new SnmpObjId(oid); } public static SnmpObjId get(String objId, String instance) { return new SnmpObjId(objId, instance); } public static SnmpObjId get(SnmpObjId objId, String instance) { return new SnmpObjId(objId, instance); } public static SnmpObjId get(SnmpObjId objId, SnmpObjId instance) { return new SnmpObjId(objId, instance); } public boolean isPrefixOf(final SnmpObjId other) { if (other == null || length() > other.length()) return false; for(int i = 0; i < m_ids.length; i++) { if (m_ids[i] != other.m_ids[i]) return false; } return true; } public SnmpInstId getInstance(SnmpObjId base) { if (!base.isPrefixOf(this)) return null; int[] instanceIds = new int[length() - base.length()]; System.arraycopy(m_ids, base.length(), instanceIds, 0, instanceIds.length); return new SnmpInstId(instanceIds); } public int length() { return m_ids.length; } public int getSubIdAt(int index) { return m_ids[index]; } public int getLastSubId() { return getSubIdAt(length()-1); } public SnmpObjId decrement() { if (getLastSubId() == 0) { return new SnmpObjId(cloneIds(m_ids, length() - 1), false); } else { int[] newIds = cloneIds(m_ids, length()); newIds[newIds.length-1] -= 1; return new SnmpObjId(newIds, false); } } }