001: package bsh.collection;
002:
003: import bsh.Capabilities;
004: import bsh.CollectionManager;
005: import bsh.UtilTargetError;
006: import bsh.InterpreterError;
007:
008: import java.lang.reflect.Method;
009: import java.lang.reflect.InvocationTargetException;
010:
011: import java.util.Iterator;
012: import java.util.Collection;
013: import java.util.Enumeration;
014:
015: import java.lang.reflect.Array;
016:
017: /**
018: * This is the implementation of:
019: * BshIterator - a dynamically loaded extension that supports the collections
020: * API supported by JDK1.2 and greater.
021: *
022: * @author Daniel Leuck
023: * @author Pat Niemeyer
024: */
025: public class CollectionIterator implements bsh.BshIterator {
026: private Iterator iterator;
027:
028: /**
029: * Construct a basic CollectionIterator
030: *
031: * @param The object over which we are iterating
032: *
033: * @throws java.lang.IllegalArgumentException If the argument is not a
034: * supported (i.e. iterable) type.
035: *
036: * @throws java.lang.NullPointerException If the argument is null
037: */
038: public CollectionIterator(Object iterateOverMe) {
039: iterator = createIterator(iterateOverMe);
040: }
041:
042: /**
043: * Create an iterator over the given object
044: *
045: * @param iterateOverMe Object of type Iterator, Collection,
046: * Iterable, or types supported by
047: * CollectionManager.BasicBshIterator
048: *
049: * @return an Iterator
050: *
051: * @throws java.lang.IllegalArgumentException If the argument is not a
052: * supported (i.e. iterable) type.
053: *
054: * @throws java.lang.NullPointerException If the argument is null
055: */
056: protected Iterator createIterator(Object iterateOverMe)
057: throws java.lang.IllegalArgumentException {
058:
059: if (iterateOverMe == null)
060: throw new NullPointerException(
061: "Object arguments passed to "
062: + "the CollectionIterator constructor cannot be null.");
063:
064: if (iterateOverMe instanceof Iterator)
065: return (Iterator) iterateOverMe;
066:
067: if (iterateOverMe instanceof Collection)
068: return ((Collection) iterateOverMe).iterator();
069:
070: Iterator it = getIteratorForIterable(iterateOverMe);
071: if (it != null)
072: return it;
073:
074: final CollectionManager.BasicBshIterator bbi = new CollectionManager.BasicBshIterator(
075: iterateOverMe);
076:
077: return new Iterator() {
078: public boolean hasNext() {
079: return bbi.hasNext();
080: }
081:
082: public Object next() {
083: return bbi.next();
084: }
085:
086: public void remove() {
087: throw new UnsupportedOperationException(
088: "remove() is not supported");
089: }
090: };
091: }
092:
093: /**
094: Get an Iterator for a Java 5 Iterable object.
095: Rather than resorting to another loadable module for Java 5 we'll
096: use reflection here to invoke the Iterable iterator() method.
097:
098: @return the Iterator or null if the object is not an Iterable.
099: @author Daniel Leuck
100: */
101: Iterator getIteratorForIterable(Object iterateOverMe) {
102: Iterator it = null;
103: try {
104: Class c = Class.forName("java.lang.Iterable");
105: if (c.isInstance(iterateOverMe)) {
106: try {
107: Method m = c.getMethod("iterator", new Class[0]);
108: it = (Iterator) m.invoke(iterateOverMe,
109: new Object[0]);
110: } catch (Exception e) {
111: throw new InterpreterError(
112: "Unexpected problem calling "
113: + "\"iterator()\" on instance of java.lang.Iterable."
114: + e);
115: }
116: }
117: } catch (ClassNotFoundException cnfe) {
118: // we are pre-Java 5 and should continue without an exception
119: }
120: return it;
121: }
122:
123: /**
124: * Fetch the next object in the iteration
125: *
126: * @return The next object
127: */
128: public Object next() {
129: return iterator.next();
130: }
131:
132: /**
133: * Returns true if and only if there are more objects available
134: * via the <code>next()</code> method
135: *
136: * @return The next object
137: */
138: public boolean hasNext() {
139: return iterator.hasNext();
140: }
141: }
|