📄 defaultmotable.java
字号:
/*_############################################################################
_##
_## SNMP4J-Agent - DefaultMOTable.java
_##
_## Copyright 2005-2006 Frank Fock (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.agent.mo;
import java.util.*;
import org.snmp4j.*;
import org.snmp4j.agent.*;
import org.snmp4j.agent.request.*;
import org.snmp4j.agent.util.*;
import org.snmp4j.smi.*;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.agent.mo.DefaultMOTable.ChangeSet;
import org.snmp4j.log.LogAdapter;
import org.snmp4j.log.LogFactory;
import org.snmp4j.agent.io.MOInput;
import org.snmp4j.agent.io.MOOutput;
import org.snmp4j.agent.io.Sequence;
import java.io.IOException;
import org.snmp4j.agent.io.IndexedVariables;
import org.snmp4j.agent.io.ImportModes;
public class DefaultMOTable implements MOTable, MOScope,
SerializableManagedObject {
private static LogAdapter logger =
LogFactory.getLogger(DefaultMOTable.class);
private OID oid;
private MOTableIndex indexDef;
private MOColumn[] columns;
private MOTableModel model;
private boolean isVolatile;
protected WeakHashMap newRows;
protected WeakHashMap pendingChanges;
private transient Vector moChangeListeners;
private transient Vector moTableRowListeners;
private static Comparator columnComparator = new Comparator() {
public int compare(Object o1, Object o2) {
int id1 = (o1 instanceof MOColumn) ?
((MOColumn)o1).getColumnID() : ((Integer)o1).intValue();
int id2 = (o2 instanceof MOColumn) ?
((MOColumn)o2).getColumnID() : ((Integer)o2).intValue();
return id1 - id2;
}
};
public DefaultMOTable(OID oid, MOTableIndex indexDef, MOColumn[] columns) {
this(oid, indexDef, columns, new DefaultMOMutableTableModel());
}
public DefaultMOTable(OID oid, MOTableIndex indexDef,
MOColumn[] columns, MOTableModel model) {
this.oid = oid;
this.indexDef = indexDef;
this.columns = columns;
this.model = model;
registerColumns();
}
private void registerColumns() {
for (int i=0; i<columns.length; i++) {
columns[i].setTable(this);
}
}
public MOTableCellInfo getCellInfo(OID oid) {
return new CellInfo(oid);
}
public int getColumnIndex(int id) {
int col = Arrays.binarySearch(columns, new Integer(id), columnComparator);
return col;
}
public MOColumn getColumn(int index) {
return columns[index];
}
public int getColumnCount() {
return columns.length;
}
/**
* Creates a new row for this table with the supplied index and initial
* values. If the underlying table model is not a {@link MOMutableTableModel}
* instance or if one of the {@link MOTableRowListener} deny the row creation
* attempt then <code>null</code> will be returned.
* @param index
* the index OID of the new row.
* @param initialValues
* the initial values that should be assigned to the new row. If the array
* contains less values than this table has columns, default values will
* be created for the missing columns.
* @return
* the created <code>MOTableRow</code> instance or <code>null</code> if
* the row cannot be created.
*/
public MOTableRow createRow(OID index, Variable[] initialValues) {
if (model instanceof MOMutableTableModel) {
Variable[] values = initialValues;
if (values.length < getColumnCount()) {
values = getDefaultValues();
System.arraycopy(initialValues, 0, values, 0, initialValues.length);
}
MOTableRow row =
((MOMutableTableModel)model).createRow(index, values);
MOTableRowEvent rowEvent =
new MOTableRowEvent(this, this, row, MOTableRowEvent.CREATE);
fireRowChanged(rowEvent);
if (rowEvent.getVetoStatus() == SnmpConstants.SNMP_ERROR_SUCCESS) {
return row;
}
}
return null;
}
public MOTableRow createRow(OID index) {
return createRow(index, getDefaultValues());
}
/**
* Adds the supplied row to the underlying table model and fires the
* appropriate {@link MOTableRowEvent}. Since this method is typically
* called during the commit phase of a SET request that creates a table,
* it should be avoided to return an error here. Instead, error checking
* should be placed in the {@link #prepare} method.
* @param row
* the <code>MOTableRow</code> to add.
* @return
* <code>true</code> if the row has been added or <code>false</code>
* if it could not be added.
*/
public boolean addRow(MOTableRow row) {
if (model instanceof MOMutableTableModel) {
MOTableRowEvent rowEvent =
new MOTableRowEvent(this, this, row, MOTableRowEvent.ADD);
fireRowChanged(rowEvent);
if (rowEvent.getVetoStatus() == SnmpConstants.SNMP_ERROR_SUCCESS) {
((MOMutableTableModel)model).addRow(row);
}
return true;
}
return false;
}
public MOTableRow removeRow(OID index) {
if (model instanceof MOMutableTableModel) {
MOTableRow row = model.getRow(index);
if (row == null) {
return null;
}
MOTableRowEvent rowEvent =
new MOTableRowEvent(this, this, row, MOTableRowEvent.DELETE);
fireRowChanged(rowEvent);
if (rowEvent.getVetoStatus() == SnmpConstants.SNMP_ERROR_SUCCESS) {
return ((MOMutableTableModel)model).removeRow(index);
}
}
return null;
}
/**
* Reomves all rows from this table. Before a row is removed the
* corresponding DELETE event is fired and listeners may veto these
* events for all rows. Only if there is no veto, a row will be deleted.
* The number of deleted rows is then returned.
* @return
* the number of removed rows.
*/
public int removeAll() {
int count = 0;
while (model.getRowCount() > 0) {
MOTableRow row = model.firstRow();
if (row != null) {
MOTableRowEvent rowEvent =
new MOTableRowEvent(this, this, row, MOTableRowEvent.DELETE);
fireRowChanged(rowEvent);
if (rowEvent.getVetoStatus() == SnmpConstants.SNMP_ERROR_SUCCESS) {
((MOMutableTableModel)model).removeRow(row.getIndex());
count++;
}
}
}
return count;
}
public void commit(SubRequest request) {
OID cellOID = request.getVariableBinding().getOid();
MOTableCellInfo cell = getCellInfo(cellOID);
MOMutableColumn col = (MOMutableColumn) getColumn(cell.getColumn());
if (logger.isDebugEnabled()) {
logger.debug("Committing sub-request ("+
request.getVariableBinding()+") for column: "+col);
}
// Make sure changes are atomic -> sync whole table model
synchronized (model) {
MOMutableTableRow row;
if (hasNewRows(request.getRequest())) {
row = (MOMutableTableRow)
getNewRows(request.getRequest()).get(cell.getIndex());
addRow(row);
}
else {
row = (MOMutableTableRow) model.getRow(cell.getIndex());
}
Variable oldValue = null;
if (moChangeListeners != null) {
oldValue = row.getValue(cell.getColumn());
MOChangeEvent changeEvent =
new MOChangeEvent(this, new CellProxy(cell),
cell.getCellOID(),
oldValue,
request.getVariableBinding().getVariable());
fireBeforeMOChange(changeEvent);
}
ChangeSet changeSet = getPendingChangeSet(request, cell.getIndex());
// commit
col.commit(request, row, changeSet, cell.getColumn());
if (moChangeListeners != null) {
MOChangeEvent changeEvent =
new MOChangeEvent(this, new CellProxy(cell),
cell.getCellOID(),
oldValue,
request.getVariableBinding().getVariable());
fireAfterMOChange(changeEvent);
}
if (isChangeSetComplete(request, cell.getIndex(), cell.getColumn())) {
if (row instanceof MOMutableRow2PC) {
((MOMutableRow2PC) row).commitRow(request, changeSet);
}
if (moTableRowListeners != null) {
MOTableRowEvent rowEvent =
new MOTableRowEvent(this, this, row, MOTableRowEvent.UPDATED);
fireRowChanged(rowEvent);
}
}
}
}
public final OID getIndexPart(OID anyOID) {
int offset = oid.size()+1;
if ((anyOID.size() <= offset) || (!anyOID.startsWith(oid))) {
return null;
}
return new OID(anyOID.getValue(), offset, anyOID.size() - offset);
}
public OID getCellOID(OID index, int col) {
OID retval = new OID(oid);
retval.append(columns[col].getColumnID());
retval.append(index);
return retval;
}
private MOTableCellInfo getNextCell(int col,
OID indexLowerBound,
boolean isLowerBoundIncluded) {
for (int i=col; i<columns.length; i++) {
Iterator it = model.tailIterator(indexLowerBound);
if (!it.hasNext()) {
if (indexLowerBound == null) {
return null;
}
indexLowerBound = null;
isLowerBoundIncluded = true;
continue;
}
else {
if ((indexLowerBound != null) && (!isLowerBoundIncluded)) {
MOTableRow row = (MOTableRow) it.next();
if (row.getIndex().compareTo(indexLowerBound) > 0) {
// the specified index does not exists so we can use this next one:
return new CellInfo(row.getIndex(), i, columns[i].getColumnID());
}
}
indexLowerBound = null;
isLowerBoundIncluded = true;
if (it.hasNext()) {
MOTableRow row = (MOTableRow) it.next();
return new CellInfo(row.getIndex(), i, columns[i].getColumnID());
}
}
}
return null;
}
public OID find(MOScope range) {
MOTableCellInfo cellInfo = findCell(range);
if (cellInfo != null) {
return cellInfo.getCellOID();
}
return null;
}
protected MOTableCellInfo findCell(MOScope range) {
synchronized (model) {
// determine column
if (model.getRowCount() == 0) {
return null;
}
MOTableCellInfo cellInfo = getCellInfo(range.getLowerBound());
int col = cellInfo.getColumn();
boolean exactMatch = true;
if (col < 0) {
col = (-col) - 1;
exactMatch = false;
}
if (col >= columns.length) {
return null;
}
MOTableCellInfo next = getNextCell(col, cellInfo.getIndex(),
(!exactMatch) ||
range.isLowerIncluded());
if (next != null) {
OID cellOID = next.getCellOID();
if (range.isCovered(new OIDScope(cellOID))) {
return next;
}
}
}
return null;
}
public MOScope getScope() {
return this;
}
public Variable getValue(OID cellOID) {
MOTableCellInfo cell = getCellInfo(cellOID);
if ((cell.getIndex() != null) &&
(cell.getColumn() >= 0) && (cell.getColumn() < columns.length)) {
return getValue(cell.getIndex(), cell.getColumn());
}
return null;
}
public Variable getValue(OID index, int col) {
MOTableRow row = model.getRow(index);
if (row != null) {
return columns[col].getValue(row, col);
}
return null;
}
public void get(SubRequest request) {
OID cellOID = request.getVariableBinding().getOid();
MOTableCellInfo cell = getCellInfo(cellOID);
if ((cell.getIndex() != null) &&
(cell.getColumn() >= 0) && (cell.getColumn() < columns.length)) {
MOColumn col = getColumn(cell.getColumn());
MOTableRow row = model.getRow(cell.getIndex());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -