001: /*_############################################################################
002: _##
003: _## SNMP4J-AgentJMX - MBeanAttributeKeyProvider.java
004: _##
005: _## Copyright (C) 2006-2007 Frank Fock (SNMP4J.org)
006: _##
007: _## This program is free software; you can redistribute it and/or modify
008: _## it under the terms of the GNU General Public License version 2 as
009: _## published by the Free Software Foundation.
010: _##
011: _## This program is distributed in the hope that it will be useful,
012: _## but WITHOUT ANY WARRANTY; without even the implied warranty of
013: _## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: _## GNU General Public License for more details.
015: _##
016: _## You should have received a copy of the GNU General Public License
017: _## along with this program; if not, write to the Free Software
018: _## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
019: _## MA 02110-1301 USA
020: _##
021: _##########################################################################*/
022:
023: package org.snmp4j.agent.mo.jmx;
024:
025: import javax.management.ObjectName;
026: import java.util.Collection;
027: import java.util.Arrays;
028: import java.util.List;
029: import javax.management.MBeanServerConnection;
030: import java.util.Iterator;
031: import java.io.IOException;
032: import javax.management.MBeanException;
033: import javax.management.AttributeNotFoundException;
034: import javax.management.InstanceNotFoundException;
035: import javax.management.ReflectionException;
036: import org.snmp4j.agent.mo.jmx.util.JMXArrayIndexKey;
037: import org.snmp4j.agent.mo.jmx.types.*;
038: import java.util.AbstractList;
039: import java.util.Collections;
040: import java.util.ArrayList;
041:
042: /**
043: * The <code>MBeanAttributeKeyProvider</code> provides the row keys of a
044: * conceptual table from a MBean attribute. The keys are returned in the same
045: * order as provided by the MBean attribute by default. If the
046: * <code>keysNeedSorting</code> is set, keys are returned always in their
047: * natural order.
048: *
049: * @author Frank Fock
050: * @version 1.0
051: */
052: public class MBeanAttributeKeyProvider extends MBeanAttributeMOInfo {
053:
054: private boolean keysNeedSorting;
055:
056: /**
057: * Creates a key provider with a MBean name and a attribute description.
058: * @param name
059: * a MBean's <code>ObjectName</code>.
060: * @param attribute
061: * the description of an attribute of the MBean identified by
062: * <code>name</code>.
063: */
064: public MBeanAttributeKeyProvider(ObjectName name,
065: TypedAttribute attribute) {
066: super (name, attribute);
067: }
068:
069: /**
070: * Creates a key provider with a MBean name and a attribute description.
071: * @param name
072: * a MBean's <code>ObjectName</code>.
073: * @param attribute
074: * the description of an attribute of the MBean identified by
075: * <code>name</code>.
076: * @param keysNeedSorting
077: * if <code>true</code> keys will be sorted by their natural order.
078: */
079: public MBeanAttributeKeyProvider(ObjectName name,
080: TypedAttribute attribute, boolean keysNeedSorting) {
081: super (name, attribute);
082: this .keysNeedSorting = keysNeedSorting;
083: }
084:
085: /**
086: * Returns an iterator on the keys provided by this MBean attribute.
087: * @param server
088: * the <code>MBeanServerConnection</code> to be used to access the MBean.
089: * @return Iterator
090: * an iterator providing the keys returned by the key provider attribute.
091: * @throws IOException
092: * @throws MBeanException
093: * @throws AttributeNotFoundException
094: * @throws InstanceNotFoundException
095: * @throws ReflectionException
096: */
097: public Iterator keyIterator(MBeanServerConnection server)
098: throws IOException, MBeanException,
099: AttributeNotFoundException, InstanceNotFoundException,
100: ReflectionException {
101: Object keys = getAttribute(server);
102: if (keys instanceof Collection) {
103: if (keysNeedSorting) {
104: List l = new ArrayList((Collection) keys);
105: Collections.sort(l);
106: keys = l;
107: }
108: return ((Collection) keys).iterator();
109: } else if (keys instanceof Object[]) {
110: List l = Arrays.asList((Object[]) keys);
111: return getAscendingIterator(l);
112: } else if (keys instanceof long[]) {
113: List l = asList((long[]) keys);
114: return getAscendingIterator(l);
115: } else if (keys instanceof int[]) {
116: List l = asList((int[]) keys);
117: return getAscendingIterator(l);
118: } else {
119: throw new ClassCastException(keys.getClass()
120: + " is not a supported list");
121: }
122: }
123:
124: private Iterator getAscendingIterator(List l) {
125: if (keysNeedSorting) {
126: l = new ArrayList(l);
127: Collections.sort(l);
128: }
129: return l.iterator();
130: }
131:
132: public static List<Integer> asList(final int[] a) {
133: return new AbstractList<Integer>() {
134: public Integer get(int i) {
135: return a[i];
136: }
137:
138: // Throws NullPointerException if val == null
139: public Integer set(int i, Integer val) {
140: Integer oldVal = a[i];
141: a[i] = val;
142: return oldVal;
143: }
144:
145: public int size() {
146: return a.length;
147: }
148: };
149: }
150:
151: public static List<Long> asList(final long[] a) {
152: return new AbstractList<Long>() {
153: public Long get(int i) {
154: return a[i];
155: }
156:
157: // Throws NullPointerException if val == null
158: public Long set(int i, Integer val) {
159: Long oldVal = a[i];
160: a[i] = val;
161: return oldVal;
162: }
163:
164: public int size() {
165: return a.length;
166: }
167: };
168: }
169:
170: /**
171: * Returns an iterator on the keys provided by this MBean attribute starting
172: * from the supplied row key.
173: *
174: * @param server
175: * the <code>MBeanServerConnection</code> to be used to access the MBean.
176: * @param firstRowId
177: * the lower bound (including) row key for the iterator.
178: * @return Iterator
179: * an iterator providing the keys returned by the key provider attribute.
180: * @throws IOException
181: * @throws MBeanException
182: * @throws AttributeNotFoundException
183: * @throws InstanceNotFoundException
184: * @throws ReflectionException
185: */
186: public Iterator keyTailIterator(MBeanServerConnection server,
187: Object firstRowId) throws IOException, MBeanException,
188: AttributeNotFoundException, InstanceNotFoundException,
189: ReflectionException {
190: Object keys = getAttribute(server);
191: if (keys instanceof Collection) {
192: keys = ((Collection) keys).toArray();
193: }
194: if (keys instanceof Object[]) {
195: if (keysNeedSorting) {
196: Arrays.sort((Object[]) keys);
197: }
198: List l = Arrays.asList((Object[]) keys);
199: int pos = 0;
200: if (firstRowId instanceof JMXArrayIndexKey) {
201: pos = ((JMXArrayIndexKey) firstRowId).getIndex();
202: } else {
203: pos = Arrays.binarySearch((Object[]) keys, firstRowId);
204: }
205: if (Math.abs(pos) >= l.size()) {
206: return Collections.emptyList().iterator();
207: }
208: return createTailIterator(l.listIterator(Math.abs(pos)),
209: pos);
210: } else if (keys instanceof long[]) {
211: if (keysNeedSorting) {
212: Arrays.sort((long[]) keys);
213: }
214: List l = asList((long[]) keys);
215: int pos = 0;
216: if (firstRowId instanceof JMXArrayIndexKey) {
217: pos = ((JMXArrayIndexKey) firstRowId).getIndex();
218: } else {
219: pos = Arrays.binarySearch((long[]) keys,
220: (Long) firstRowId);
221: }
222: if (Math.abs(pos) >= l.size()) {
223: return Collections.emptyList().iterator();
224: }
225: return createTailIterator(l.listIterator(Math.abs(pos)),
226: pos);
227: } else if (keys instanceof int[]) {
228: if (keysNeedSorting) {
229: Arrays.sort((int[]) keys);
230: }
231: List l = asList((int[]) keys);
232: int pos = 0;
233: if (firstRowId instanceof JMXArrayIndexKey) {
234: pos = ((JMXArrayIndexKey) firstRowId).getIndex();
235: } else {
236: pos = Arrays.binarySearch((int[]) keys,
237: (Integer) firstRowId);
238: }
239: if (Math.abs(pos) >= l.size()) {
240: return Collections.emptyList().iterator();
241: }
242: return createTailIterator(l.listIterator(Math.abs(pos)),
243: pos);
244: } else {
245: throw new ClassCastException(keys.getClass()
246: + " is not a supported list");
247: }
248: }
249:
250: protected Iterator createTailIterator(Iterator it, int indexPos) {
251: return it;
252: }
253:
254: /**
255: * Returns the number of row keys available.
256: * @param server
257: * the <code>MBeanServerConnection</code> to be used to access the MBean.
258: * @return
259: * the number of keys.
260: * @throws IOException
261: * @throws MBeanException
262: * @throws AttributeNotFoundException
263: * @throws InstanceNotFoundException
264: * @throws ReflectionException
265: */
266: public int getKeyCount(MBeanServerConnection server)
267: throws IOException, MBeanException,
268: AttributeNotFoundException, InstanceNotFoundException,
269: ReflectionException {
270: Object keys = getAttribute(server);
271: if (keys instanceof Collection) {
272: return ((Collection) keys).size();
273: } else if (keys instanceof Object[]) {
274: return ((Object[]) keys).length;
275: } else if (keys instanceof long[]) {
276: return ((long[]) keys).length;
277: } else if (keys instanceof int[]) {
278: return ((int[]) keys).length;
279: }
280: return 0;
281: }
282:
283: public Object getRowValues(MBeanServerConnection server,
284: Object indexObject) throws IOException, MBeanException,
285: AttributeNotFoundException, InstanceNotFoundException,
286: ReflectionException {
287: return indexObject;
288: }
289:
290: }
|