📄 variable.java
字号:
/*_############################################################################
_##
_## SNMP4J - Variable.java
_##
_## Copyright 2003-2005 Frank Fock and Jochen Katz (SNMP4J.org)
_##
_## Licensed under the Apache License, Version 2.0 (the "License");
_## you may not use this file except in compliance with the License.
_## You may obtain a copy of the License at
_##
_## http://www.apache.org/licenses/LICENSE-2.0
_##
_## Unless required by applicable law or agreed to in writing, software
_## distributed under the License is distributed on an "AS IS" BASIS,
_## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
_## See the License for the specific language governing permissions and
_## limitations under the License.
_##
_##########################################################################*/
package org.snmp4j.smi;
import java.io.*;
import java.util.*;
import org.snmp4j.log.*;
import org.snmp4j.asn1.*;
import org.snmp4j.SNMP4JSettings;
/**
* The <code>Variable</code> abstract class is the base class for all SNMP
* variables.
* <p>
* All derived classes need to be registered with their SMI BER type in the
* <code>smisyntaxes.properties</code>so that the
* {@link #createFromBER(BERInputStream inputStream)} method
* is able to decode a variable from a BER encoded stream.
* <p>
* To register additional syntaxes, set the system property
* {@link #SMISYNTAXES_PROPERTIES} before decoding a Variable for the first
* time. The path of the property file must be accessible from the classpath
* and it has to be specified relative to the <code>Variable</code> class.
*
* @author Jochen Katz & Frank Fock
* @version 1.5
* @since 1.0
*/
public abstract class Variable implements Cloneable, Comparable,
BERSerializable {
public static final String SMISYNTAXES_PROPERTIES =
"org.snmp4j.smisyntaxes";
private static final String SMISYNTAXES_PROPERTIES_DEFAULT =
"smisyntaxes.properties";
private static Hashtable registeredSyntaxes = null;
private static final LogAdapter logger = LogFactory.getLogger(Variable.class);
/**
* The abstract <code>Variable</code> class serves as the base class for all
* specific SNMP syntax types.
*/
public Variable() {
}
public abstract boolean equals(Object o);
public abstract int compareTo(Object o);
public abstract int hashCode();
/**
* Returns the length of this <code>Variable</code> in bytes when encoded
* according to the Basic Encoding Rules (BER).
* @return
* the BER encoded length of this variable.
*/
public abstract int getBERLength();
public int getBERPayloadLength() {
return getBERLength();
}
/**
* Decodes a <code>Variable</code> from an <code>InputStream</code>.
* @param inputStream
* an <code>InputStream</code> containing a BER encoded byte stream.
* @throws IOException
* if the stream could not be decoded by using BER rules.
*/
public abstract void decodeBER(BERInputStream inputStream) throws IOException;
/**
* Encodes a <code>Variable</code> to an <code>OutputStream</code>.
* @param outputStream
* an <code>OutputStream</code>.
* @throws IOException
* if an error occurs while writing to the stream.
*/
public abstract void encodeBER(OutputStream outputStream) throws IOException;
/**
* Creates a <code>Variable</code> from a BER encoded <code>InputStream</code>.
* Subclasses of <code>Variable</code> are registered using the properties file
* <code>smisyntaxes.properties</code> in this package. The properties are
* read when this method is called first.
*
* @param inputStream
* an <code>BERInputStream</code> containing a BER encoded byte stream.
* @return
* an instance of a subclass of <code>Variable</code>.
* @throws IOException
*/
public static Variable createFromBER(BERInputStream inputStream) throws
IOException {
if (!inputStream.markSupported()) {
throw new IOException(
"InputStream for decoding a Variable must support marks");
}
if (SNMP4JSettings.isExtensibilityEnabled() &&
(registeredSyntaxes == null)) {
registerSyntaxes();
}
inputStream.mark(2);
int type = inputStream.read();
Variable variable;
if (SNMP4JSettings.isExtensibilityEnabled()) {
Class c = (Class) registeredSyntaxes.get(new Integer(type));
if (c == null) {
throw new IOException("Encountered unsupported variable syntax: " +
type);
}
try {
variable = (Variable) c.newInstance();
}
catch (IllegalAccessException aex) {
throw new IOException("Could not access variable syntax class for: " +
c.getName());
}
catch (InstantiationException iex) {
throw new IOException(
"Could not instantiate variable syntax class for: " +
c.getName());
}
}
else {
variable = createVariable(type);
}
inputStream.reset();
variable.decodeBER(inputStream);
return variable;
}
private static Variable createVariable(int smiSyntax) {
switch (smiSyntax) {
case SMIConstants.SYNTAX_OBJECT_IDENTIFIER: {
return new OID();
}
case SMIConstants.SYNTAX_INTEGER: {
return new Integer32();
}
case SMIConstants.SYNTAX_OCTET_STRING: {
return new OctetString();
}
case SMIConstants.SYNTAX_GAUGE32: {
return new Gauge32();
}
case SMIConstants.SYNTAX_COUNTER32: {
return new Counter32();
}
case SMIConstants.SYNTAX_COUNTER64: {
return new Counter64();
}
case SMIConstants.SYNTAX_NULL: {
return new Null();
}
case SMIConstants.SYNTAX_TIMETICKS: {
return new TimeTicks();
}
case SMIConstants.EXCEPTION_END_OF_MIB_VIEW: {
return new Null(SMIConstants.EXCEPTION_END_OF_MIB_VIEW);
}
case SMIConstants.EXCEPTION_NO_SUCH_INSTANCE: {
return new Null(SMIConstants.EXCEPTION_NO_SUCH_INSTANCE);
}
case SMIConstants.EXCEPTION_NO_SUCH_OBJECT: {
return new Null(SMIConstants.EXCEPTION_NO_SUCH_OBJECT);
}
case SMIConstants.SYNTAX_OPAQUE: {
return new Opaque();
}
case SMIConstants.SYNTAX_IPADDRESS: {
return new IpAddress();
}
default: {
throw new IllegalArgumentException("Unsupported variable syntax: " +
smiSyntax);
}
}
}
/**
* Creates a <code>Variable</code> from the supplied SMI syntax identifier.
* Subclasses of <code>Variable</code> are registered using the properties file
* <code>smisyntaxes.properties</code> in this package. The properties are
* read when this method is called first.
*
* @param smiSyntax
* an SMI syntax identifier of the registered types, which is typically
* defined by {@link SMIConstants}.
* @return
* a <code>Variable</code> variable instance of the supplied SMI syntax.
*/
public static Variable createFromSyntax(int smiSyntax) {
if (!SNMP4JSettings.isExtensibilityEnabled()) {
return createVariable(smiSyntax);
}
if (registeredSyntaxes == null) {
registerSyntaxes();
}
Class c = (Class) registeredSyntaxes.get(new Integer(smiSyntax));
if (c == null) {
throw new IllegalArgumentException("Unsupported variable syntax: " +
smiSyntax);
}
try {
Variable variable = (Variable) c.newInstance();
return variable;
}
catch (IllegalAccessException aex) {
throw new RuntimeException("Could not access variable syntax class for: " +
c.getName());
}
catch (InstantiationException iex) {
throw new RuntimeException(
"Could not instantiate variable syntax class for: " +
c.getName());
}
}
/**
* Register SNMP syntax classes from a properties file. The registered
* syntaxes are used by the {@link createFromBER} method to type-safe
* instantiate sub-classes from <code>Variable</code> from an BER encoded
* <code>InputStream</code>.
*/
private synchronized static void registerSyntaxes() {
String syntaxes = System.getProperty(SMISYNTAXES_PROPERTIES,
SMISYNTAXES_PROPERTIES_DEFAULT);
InputStream is = Variable.class.getResourceAsStream(syntaxes);
if (is == null) {
throw new InternalError("Could not read '" + syntaxes +
"' from classpath!");
}
Properties props = new Properties();
try {
props.load(is);
Hashtable regSyntaxes = new Hashtable(props.size());
for (Enumeration en = props.propertyNames(); en.hasMoreElements(); ) {
String id = (String) en.nextElement();
String className = props.getProperty(id);
try {
Class c = Class.forName(className);
regSyntaxes.put(new Integer(id), c);
}
catch (ClassNotFoundException cnfe) {
logger.error(cnfe);
}
}
// atomic syntax registration
registeredSyntaxes = regSyntaxes;
}
catch (IOException iox) {
String txt = "Could not read '" + syntaxes + "': " +
iox.getMessage();
logger.error(txt);
throw new InternalError(txt);
}
finally {
try {
is.close();
}
catch (IOException ex) {
logger.warn(ex);
}
}
}
/**
* Gets the ASN.1 syntax identifier value of this SNMP variable.
* @return
* an integer value < 128 for regular SMI objects and a value >= 128
* for exception values like noSuchObject, noSuchInstance, and
* endOfMibView.
*/
public abstract int getSyntax();
/**
* Checks whether this variable represents an exception like
* noSuchObject, noSuchInstance, and endOfMibView.
* @return
* <code>true</code> if the syntax of this variable is an instance of
* <code>Null</code> and its syntax equals one of the following:
* <UL>
* <LI>{@link SMIConstants#EXCEPTION_NO_SUCH_OBJECT}</LI>
* <LI>{@link SMIConstants#EXCEPTION_NO_SUCH_INSTANCE}</LI>
* <LI>{@link SMIConstants#EXCEPTION_END_OF_MIB_VIEW}</LI>
* </UL>
*/
public boolean isException() {
return Null.isExceptionSyntax(getSyntax());
}
/**
* Gets a string representation of the variable.
* @return String
*/
public abstract String toString();
public abstract Object clone();
/**
* Gets a textual description of the supplied syntax type.
* @param syntax
* the BER code of the syntax.
* @return
* a textual description like 'Integer32' for <code>syntax</code>
* as used in the Structure of Management Information (SMI) modules.
* '?' is returned if the supplied syntax is unknown.
*/
public static String getSyntaxString(int syntax) {
switch (syntax) {
case BER.INTEGER:
return "Integer32";
case BER.OCTETSTRING:
return "OCTET STRING";
case BER.OID:
return "OBJECT IDENTIFIER";
case BER.TIMETICKS:
return "TimeTicks";
case BER.COUNTER:
return "Counter";
case BER.COUNTER64:
return "Counter64";
case BER.ENDOFMIBVIEW:
return "EndOfMibView";
case BER.GAUGE32:
return "Gauge";
case BER.IPADDRESS:
return "IpAddress";
case BER.NOSUCHINSTANCE:
return "NoSuchInstance";
case BER.NOSUCHOBJECT:
return "NoSuchObject";
case BER.NULL:
return "Null";
case BER.OPAQUE:
return "Opaque";
}
return "?";
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -