/*
* Mibble MIB Parser (www.mibble.org)
*
* See LICENSE.txt for licensing information.
*
* Copyright (c) 2004-2017 Per Cederberg. All rights reserved.
*/
package net.percederberg.mibble;
import net.percederberg.mibble.snmp.SnmpObjectType;
import net.percederberg.mibble.type.SequenceOfType;
import net.percederberg.mibble.type.SequenceType;
import net.percederberg.mibble.value.ObjectIdentifierValue;
/**
* A MIB value symbol. This class holds information relevant to a MIB
* value assignment, i.e. a type and a value. Normally the value is
* an object identifier.
*
* @author Per Cederberg
* @version 2.10
* @since 2.0
*/
public class MibValueSymbol extends MibSymbol {
/**
* The symbol type.
*/
private MibType type;
/**
* The symbol value.
*/
private MibValue value;
/**
* Creates a new value symbol.<p>
*
* <strong>NOTE:</strong> This is an internal constructor that
* should only be called by the MIB loader.
*
* @param fileRef the MIB file reference
* @param mib the symbol MIB file
* @param name the symbol name
* @param type the symbol type
* @param value the symbol value
*
* @since 2.2
*/
public MibValueSymbol(MibFileRef fileRef,
Mib mib,
String name,
MibType type,
MibValue value) {
super(fileRef, mib, name);
this.type = type;
this.value = value;
}
/**
* Initializes the MIB symbol. This will remove all levels of
* indirection present, such as references to types or values. No
* information is lost by this operation. This method may modify
* this object as a side-effect.<p>
*
* <strong>NOTE:</strong> This is an internal method that should
* only be called by the MIB loader.
*
* @param log the MIB loader log
*
* @throws MibException if an error was encountered during the
* initialization
*/
public void initialize(MibLoaderLog log) throws MibException {
if (type != null) {
try {
type = type.initialize(this, log);
} catch (MibException e) {
log.addError(e);
type = null;
}
}
if (value != null) {
try {
value = value.initialize(log, type);
} catch (MibException e) {
log.addError(e);
value = null;
}
}
if (type != null && value != null && !type.isCompatible(value)) {
log.addError(getFileRef(),
"value is not compatible with type");
}
if (value instanceof ObjectIdentifierValue) {
ObjectIdentifierValue oid = (ObjectIdentifierValue) value;
if (oid.getSymbol() == null) {
oid.setSymbol(this);
} else {
boolean loaded = getMib().isLoaded() || oid.getMib().isLoaded();
if (oid.getSymbol() != this && loaded) {
log.addWarning(getFileRef(),
"duplicate definition of " + oid +
", previously defined as '" +
oid.getSymbol().getName() + "' in " +
oid.getSymbol().getMib().getName());
}
}
}
}
/**
* Clears and prepares this MIB symbol for garbage collection.
* This method will recursively clear any associated types or
* values, making sure that no data structures references this
* symbol.
*/
void clear() {
type = null;
if (value != null) {
value.clear();
}
value = null;
}
/**
* Checks if this symbol corresponds to a scalar. A symbol is
* considered a scalar if it has an SnmpObjectType type and does
* not represent or reside within a table.
*
* @return true if this symbol is a scalar, or
* false otherwise
*
* @see #isTable()
* @see #isTableRow()
* @see #isTableColumn()
* @see net.percederberg.mibble.snmp.SnmpObjectType
*
* @since 2.5
*/
public boolean isScalar() {
return type instanceof SnmpObjectType
&& !isTable()
&& !isTableRow()
&& !isTableColumn();
}
/**
* Checks if this symbol corresponds to a table. A symbol is
* considered a table if it has an SnmpObjectType type with
* SEQUENCE OF syntax.
*
* @return true if this symbol is a table, or
* false otherwise
*
* @see #isScalar()
* @see #isTableRow()
* @see #isTableColumn()
* @see net.percederberg.mibble.snmp.SnmpObjectType
*
* @since 2.5
*/
public boolean isTable() {
if (type instanceof SnmpObjectType) {
MibType syntax = ((SnmpObjectType) type).getSyntax();
return syntax instanceof SequenceOfType;
} else {
return false;
}
}
/**
* Checks if this symbol corresponds to a table row (or entry). A
* symbol is considered a table row if it has an SnmpObjectType
* type with SEQUENCE syntax.
*
* @return true if this symbol is a table row, or
* false otherwise
*
* @see #isScalar()
* @see #isTable()
* @see #isTableColumn()
* @see net.percederberg.mibble.snmp.SnmpObjectType
*
* @since 2.5
*/
public boolean isTableRow() {
if (type instanceof SnmpObjectType) {
MibType syntax = ((SnmpObjectType) type).getSyntax();
return syntax instanceof SequenceType;
} else {
return false;
}
}
/**
* Checks if this symbol corresponds to a table column. A symbol
* is considered a table column if it has an SnmpObjectType type
* and a parent symbol that is a table row.
*
* @return true if this symbol is a table column, or
* false otherwise
*
* @see #isScalar()
* @see #isTable()
* @see #isTableRow()
* @see net.percederberg.mibble.snmp.SnmpObjectType
*
* @since 2.5
*/
public boolean isTableColumn() {
MibValueSymbol parent = getParent();
return type instanceof SnmpObjectType
&& parent != null
&& parent.isTableRow();
}
/**
* Returns the symbol type.
*
* @return the symbol type
*/
public MibType getType() {
return type;
}
/**
* Returns the symbol value.
*
* @return the symbol value
*/
public MibValue getValue() {
return value;
}
/**
* Returns the symbol object identifier value (if set). This is a
* convenience method for getValue() with an additional type
* check and cast.
*
* @return the symbol OID value
*
* @since 2.10
*/
public ObjectIdentifierValue getOid() {
if (value instanceof ObjectIdentifierValue) {
return (ObjectIdentifierValue) value;
} else {
return null;
}
}
/**
* Returns the parent symbol in the OID tree. This is a
* convenience method for value symbols that have object
* identifier values.
*
* @return the parent symbol in the OID tree, or
* null for none or if not applicable
*
* @see net.percederberg.mibble.value.ObjectIdentifierValue
*
* @since 2.5
*/
public MibValueSymbol getParent() {
ObjectIdentifierValue oid = getOid();
ObjectIdentifierValue parent = (oid != null) ? oid.getParent() : null;
return (parent != null) ? parent.getSymbol() : null;
}
/**
* Returns the number of child symbols in the OID tree. This is a
* convenience method for value symbols that have object
* identifier values.
*
* @return the number of child symbols in the OID tree, or
* zero (0) if not applicable
*
* @see net.percederberg.mibble.value.ObjectIdentifierValue
*
* @since 2.6
*/
public int getChildCount() {
ObjectIdentifierValue oid = getOid();
return (oid != null) ? oid.getChildCount() : 0;
}
/**
* Returns a specific child symbol in the OID tree. This is a
* convenience method for value symbols that have object
* identifier values.
*
* @param index the child position, starting from 0
*
* @return the child symbol in the OID tree, or
* null if not found or not applicable
*
* @see net.percederberg.mibble.value.ObjectIdentifierValue
*
* @since 2.6
*/
public MibValueSymbol getChild(int index) {
ObjectIdentifierValue oid = getOid();
ObjectIdentifierValue child = (oid != null) ? oid.getChild(index) : null;
return (child != null) ? child.getSymbol() : null;
}
/**
* Returns all child symbols in the OID tree. This is a
* convenience method for value symbols that have object
* identifier values.
*
* @return the array of child symbols in the OID tree, or
* an empty array if not applicable
*
* @see net.percederberg.mibble.value.ObjectIdentifierValue
*
* @since 2.6
*/
public MibValueSymbol[] getChildren() {
ObjectIdentifierValue oid = getOid();
int count = (oid != null) ? oid.getChildCount() : 0;
MibValueSymbol[] children = new MibValueSymbol[count];
for (int i = 0; oid != null && i < count; i++) {
children[i] = oid.getChild(i).getSymbol();
}
return children;
}
/**
* Returns a string representation of this object.
*
* @return a string representation of this object
*/
public String toString() {
StringBuilder buffer = new StringBuilder();
buffer.append("VALUE ");
buffer.append(getName());
buffer.append(" ");
buffer.append(getType());
buffer.append("\n ::= ");
buffer.append(getValue());
return buffer.toString();
}
}