001: /*_############################################################################
002: _##
003: _## SNMP4J-Agent - DefaultMOMutableTableModel.java
004: _##
005: _## Copyright (C) 2005-2007 Frank Fock (SNMP4J.org)
006: _##
007: _## Licensed under the Apache License, Version 2.0 (the "License");
008: _## you may not use this file except in compliance with the License.
009: _## You may obtain a copy of the License at
010: _##
011: _## http://www.apache.org/licenses/LICENSE-2.0
012: _##
013: _## Unless required by applicable law or agreed to in writing, software
014: _## distributed under the License is distributed on an "AS IS" BASIS,
015: _## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016: _## See the License for the specific language governing permissions and
017: _## limitations under the License.
018: _##
019: _##########################################################################*/
020:
021: package org.snmp4j.agent.mo;
022:
023: import java.util.*;
024:
025: import org.snmp4j.smi.*;
026:
027: public class DefaultMOMutableTableModel extends DefaultMOTableModel
028: implements MOMutableTableModel {
029:
030: protected MOTableRowFactory rowFactory;
031: private transient Vector moTableModelListeners;
032:
033: public MOTableRowFactory getRowFactory() {
034: return rowFactory;
035: }
036:
037: /**
038: * Returns a lexicographic ordered list of the rows in the specified index
039: * range.
040: * @param lowerBound
041: * the lower bound index (inclusive) for the rows in the returned list.
042: * @param upperBoundEx
043: * the upper bound index (exclusive) for the rows in the returned list.
044: * @return
045: * the possibly empty lexicographically ordered <code>List</code>
046: * of rows of this table model in the specified index range. Modifications
047: * to the list will not affect the underlying table model, although
048: * modifications to the row elements will.
049: */
050: public synchronized List getRows(OID lowerBound, OID upperBoundEx) {
051: List view = new ArrayList(getView(lowerBound, upperBoundEx)
052: .values());
053: return view;
054: }
055:
056: /**
057: * Returns a lexicographic ordered list of the rows in the specified index
058: * range that match the supplied filter.
059: * @param lowerBound
060: * the lower bound index (inclusive) for the rows in the returned list.
061: * @param upperBoundEx
062: * the upper bound index (exclusive) for the rows in the returned list.
063: * @param filter
064: * the filter to exclude rows in the range from the returned
065: * @return
066: * the possibly empty lexicographically ordered <code>List</code>
067: * of rows of this table model in the specified index range. Modifications
068: * to the list will not affect the underlying table model, although
069: * modifications to the row elements will.
070: */
071: public synchronized List getRows(OID lowerBound, OID upperBoundEx,
072: MOTableRowFilter filter) {
073: LinkedList result = new LinkedList();
074: SortedMap view = getView(lowerBound, upperBoundEx);
075: for (Iterator it = view.values().iterator(); it.hasNext();) {
076: MOTableRow row = (MOTableRow) it.next();
077: if (filter.passesFilter(row)) {
078: result.add(row);
079: }
080: }
081: return result;
082: }
083:
084: private SortedMap getView(OID lowerBound, OID upperBoundEx) {
085: SortedMap view;
086: if ((lowerBound == null) && (upperBoundEx == null)) {
087: view = rows;
088: } else if (lowerBound == null) {
089: view = rows.headMap(upperBoundEx);
090: } else if (upperBoundEx == null) {
091: view = rows.tailMap(lowerBound);
092: } else {
093: view = rows.subMap(lowerBound, upperBoundEx);
094: }
095: return view;
096: }
097:
098: public synchronized MOTableRow removeRow(OID index) {
099: MOTableRow row = (MOTableRow) rows.remove(index);
100: if ((row != null) && (moTableModelListeners != null)) {
101: MOTableModelEvent event = new MOTableModelEvent(this ,
102: MOTableModelEvent.ROW_REMOVED, row);
103: fireTableModelChanged(event);
104: }
105: return row;
106: }
107:
108: public synchronized void removeRows(OID lowerBoundIncl,
109: OID upperBoundExcl) {
110: Map m = rows.tailMap(lowerBoundIncl);
111: for (Iterator it = m.entrySet().iterator(); it.hasNext();) {
112: Map.Entry item = (Map.Entry) it.next();
113: if (upperBoundExcl.compareTo(item.getKey()) > 0) {
114: if (moTableModelListeners != null) {
115: MOTableModelEvent event = new MOTableModelEvent(
116: this , MOTableModelEvent.ROW_REMOVED,
117: (MOTableRow) item.getValue());
118: fireTableModelChanged(event);
119: }
120: it.remove();
121: } else {
122: break;
123: }
124: }
125: }
126:
127: public synchronized void clear() {
128: fireTableModelChanged(new MOTableModelEvent(this ,
129: MOTableModelEvent.TABLE_CLEAR));
130: rows.clear();
131: }
132:
133: /**
134: * Remove all rows that do not match the given filter criteria
135: * from the model.
136: * @param filter
137: * the <code>MOTableRowFilter</code> that filters out the rows to
138: * delete.
139: */
140: public synchronized void clear(MOTableRowFilter filter) {
141: for (Iterator it = rows.values().iterator(); it.hasNext();) {
142: MOTableRow row = (MOTableRow) it.next();
143: if (!filter.passesFilter(row)) {
144: it.remove();
145: }
146: }
147: }
148:
149: /**
150: * Returns an iterator over all rows in this table that pass the
151: * given filter. If the table might be modified while the iterator
152: * is used, it is recommended to synchronize on this model while
153: * iterating.
154: * @param filter
155: * a MOTableRowFilter instance that defines the rows to return.
156: * @return
157: * an Iterator.
158: */
159: public synchronized Iterator iterator(MOTableRowFilter filter) {
160: return new FilteredRowIterator(filter);
161: }
162:
163: /**
164: * Create a new row and return it. The new row will not be added to the
165: * table. To add it to the model use the {@link #addRow} method.
166: * If this mutable table does not support row creation, it should
167: * throw an {@link UnsupportedOperationException}.
168: * @param index
169: * the index OID for the new row.
170: * @param values
171: * the values to be contained in the new row.
172: * @return
173: * the created <code>MOTableRow</code>.
174: * @throws java.lang.UnsupportedOperationException
175: * if the specified row cannot be created.
176: */
177: public MOTableRow createRow(OID index, Variable[] values)
178: throws UnsupportedOperationException {
179: if (rowFactory == null) {
180: throw new UnsupportedOperationException("No row factory");
181: }
182: return rowFactory.createRow(index, values);
183: }
184:
185: public void setRowFactory(MOTableRowFactory rowFactory) {
186: this .rowFactory = rowFactory;
187: }
188:
189: public void setColumnCount(int columnCount) {
190: this .columnCount = columnCount;
191: }
192:
193: public void freeRow(MOTableRow row) {
194: if (rowFactory != null) {
195: rowFactory.freeRow(row);
196: }
197: }
198:
199: public synchronized void addMOTableModelListener(
200: MOTableModelListener l) {
201: if (moTableModelListeners == null) {
202: moTableModelListeners = new Vector(2);
203: }
204: moTableModelListeners.add(l);
205: }
206:
207: public synchronized void removeMOTableModelListener(
208: MOTableModelListener l) {
209: if (moTableModelListeners != null) {
210: moTableModelListeners.remove(l);
211: }
212: }
213:
214: protected void fireTableModelChanged(MOTableModelEvent event) {
215: if (moTableModelListeners != null) {
216: Vector listeners = moTableModelListeners;
217: int count = listeners.size();
218: for (int i = 0; i < count; i++) {
219: ((MOTableModelListener) listeners.elementAt(i))
220: .tableModelChanged(event);
221: }
222: }
223: }
224:
225: public class FilteredRowIterator implements Iterator {
226:
227: private Iterator iterator;
228: private MOTableRowFilter filter;
229: private MOTableRow next;
230:
231: FilteredRowIterator(MOTableRowFilter filter) {
232: this .filter = filter;
233: this .iterator = iterator();
234: }
235:
236: public void remove() {
237: iterator.remove();
238: }
239:
240: public boolean hasNext() {
241: if (next != null) {
242: return true;
243: }
244: findNext();
245: return (next != null);
246: }
247:
248: private void findNext() {
249: while (iterator.hasNext()) {
250: next = (MOTableRow) iterator.next();
251: if (filter.passesFilter(next)) {
252: break;
253: } else {
254: next = null;
255: }
256: }
257: }
258:
259: public Object next() {
260: if (next == null) {
261: findNext();
262: }
263: if (next != null) {
264: Object retval = next;
265: next = null;
266: return retval;
267: }
268: throw new NoSuchElementException();
269: }
270:
271: }
272:
273: public MOTableRow addRow(MOTableRow row) {
274: MOTableRow newRow = super .addRow(row);
275: if (moTableModelListeners != null) {
276: MOTableModelEvent event = new MOTableModelEvent(this,
277: MOTableModelEvent.ROW_ADDED, row);
278: fireTableModelChanged(event);
279: }
280: return newRow;
281: }
282: }
|