/*_############################################################################
_##
_## SNMP4J-AgentJMX - JMXTableModel.java
_##
_## Copyright (C) 2006-2009 Frank Fock (SNMP4J.org)
_##
_## This program is free software; you can redistribute it and/or modify
_## it under the terms of the GNU General Public License version 2 as
_## published by the Free Software Foundation.
_##
_## This program 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 this program; if not, write to the Free Software
_## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
_## MA 02110-1301 USA
_##
_##########################################################################*/
package org.snmp4j.agent.mo.jmx;
import java.util.Iterator;
import org.snmp4j.agent.mo.*;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.smi.AbstractVariable;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.Variable;
import org.snmp4j.agent.mo.jmx.util.JMXArrayIndexKey;
/**
* The <code>JMXTableModel</code> implements the {@link MOTableModel} interface
* with the support of a {@link JMXTableSupport} instance.
*
* @author Frank Fock
* @version 1.0
*/
public class JMXTableModel implements MOTableModel {
protected OID tableOID;
protected JMXTableSupport table;
protected MOColumn[] columns;
protected MOTableRowFactory rowFactory = new JMXMutableTableRowFactory();
public JMXTableModel(OID tableEntryOID,
JMXTableSupport table,
MOColumn[] columns) {
this.table = table;
this.tableOID = tableEntryOID;
this.columns = columns;
}
protected Variable[] getInitialRowValues() {
Variable[] values = new Variable[getColumnCount()];
for (int i = 0; (i < values.length); i++) {
if (columns[i] instanceof MOMutableColumn) {
values[i] = ((MOMutableColumn) columns[i]).getDefaultValue();
if (values[i] == null) {
values[i] = AbstractVariable.createFromSyntax(columns[i].getSyntax());
}
}
else {
values[i] = AbstractVariable.createFromSyntax(columns[i].getSyntax());
}
}
return values;
}
public boolean containsRow(OID index) {
int i=0;
for (Iterator it = table.rowIdIterator(tableOID); it.hasNext(); i++) {
Object rowKey = it.next();
OID rowIndex = table.mapToIndex(tableOID, rowKey, i);
if (index.equals(rowIndex)) {
return true;
}
}
return false;
}
public OID firstIndex() {
Iterator it = table.rowIdIterator(tableOID);
if (it.hasNext()) {
return table.mapToIndex(tableOID, it.next(), 0);
}
return null;
}
public MOTableRow firstRow() {
OID firstIndex = firstIndex();
if (firstIndex != null) {
MOTableRow row = rowFactory.createRow(firstIndex, getInitialRowValues());
table.getRow(tableOID, row);
return row;
}
return null;
}
public int getColumnCount() {
return columns.length;
}
public MOTableRow getRow(OID index) {
MOTableRow row = rowFactory.createRow(index, getInitialRowValues());
int status = table.getRow(tableOID, row);
if (status == SnmpConstants.SNMP_ERROR_SUCCESS) {
return row;
}
return null;
}
public int getRowCount() {
return table.getRowCount(tableOID);
}
public Iterator iterator() {
return new JMXTableRowIterator(table.rowIdIterator(tableOID));
}
/**
* Returns the last row index in this model.
*
* @return the last index OID of this model.
*/
public OID lastIndex() {
return table.getLastIndex(tableOID);
}
/**
* Returns the last row contained in this model.
*
* @return the <code>MOTableRow</code> with the greatest index or
* <code>null</code> if the model is empty.
*/
public MOTableRow lastRow() {
OID lastIndex = lastIndex();
if (lastIndex != null) {
MOTableRow row = rowFactory.createRow(lastIndex, getInitialRowValues());
table.getRow(tableOID, row);
return row;
}
return null;
}
/**
* Returns an iterator on a view of the rows of this table model whose index
* values are greater or equal <code>lowerBound</code>.
*
* @param lowerBound the lower bound index (inclusive). If
* <code>lowerBound</code> is <code>null</code> the returned iterator is
* the same as returned by {@link #iterator}.
* @return an <code>Iterator</code> over the
*/
public Iterator tailIterator(OID lowerBound) {
int i=0;
Object rowId = table.mapToRowId(tableOID, lowerBound);
if (rowId != null) {
return new JMXTableRowIterator(table.rowIdTailIterator(tableOID, rowId));
}
else {
for (Iterator it = table.rowIdIterator(tableOID); it.hasNext(); i++) {
Object key = it.next();
OID index = table.mapToIndex(tableOID, key, i+1);
if ((lowerBound == null) || (index.compareTo(lowerBound) >= 0)) {
return new JMXTableRowIterator(it, key, i+1);
}
}
}
return null;
}
public class JMXTableRowIterator implements Iterator {
private Object nextKey;
private Iterator keys;
private int nativeIndex = 0;
private JMXTableRowIterator(Iterator keys) {
this.keys = keys;
}
private JMXTableRowIterator(Iterator keys, Object firstKey,
int firstNativeIndex) {
this(keys);
this.nextKey = firstKey;
this.nativeIndex = firstNativeIndex;
}
public boolean hasNext() {
return (nextKey != null) || keys.hasNext();
}
public Object next() {
Object key = nextKey;
if (key == null) {
key = keys.next();
}
else {
nextKey = null;
}
if (key instanceof JMXArrayIndexKey) {
nativeIndex = ((JMXArrayIndexKey)key).getIndex();
}
OID index = table.mapToIndex(tableOID, key, nativeIndex++);
MOTableRow row = rowFactory.createRow(index, getInitialRowValues());
int status = table.getRow(tableOID, row);
if (status == SnmpConstants.SNMP_ERROR_SUCCESS) {
return row;
}
return null;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
public MOTableRowFactory getRowFactory() {
return rowFactory;
}
public void setRowFactory(MOTableRowFactory rowFactory) {
this.rowFactory = rowFactory;
}
class JMXMutableTableRowFactory extends DefaultMOMutableRow2PCFactory {
public MOTableRow createRow(OID index, Variable[] values) throws
UnsupportedOperationException {
return new JMXMutableRow2PC(index, values);
}
}
class JMXMutableRow2PC extends DefaultMOMutableRow2PC {
public JMXMutableRow2PC(OID index, Variable[] values) {
super(index, values);
}
public void setValue(int column, Variable value) {
super.setValue(column, value);
table.setRow(tableOID, this, column);
}
}
}