001: /*
002: * $Id: AnyBindingEnumeration.java,v 1.23 2002/09/16 08:05:02 jkl Exp $
003: *
004: * Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
005: *
006: * Use is subject to license terms, as defined in
007: * Anvil Sofware License, Version 1.1. See LICENSE
008: * file, or http://njet.org/license-1.1.txt
009: */
010: package anvil.core;
011:
012: import java.util.ArrayList;
013: import java.util.Comparator;
014: import java.util.Enumeration;
015: import java.util.Iterator;
016: import anvil.core.Any;
017: import anvil.script.Context;
018: import anvil.java.util.BindingEnumeration;
019:
020: /// @class Enumeration
021: /// Enumeration generates ordered series of (keys and) values.
022: /// These keys and values can be retrived one at a time.
023: ///
024: /// @operator toBoolean
025: /// Returns <code>true</code> if there are more elements available
026: /// @synopsis boolean (boolean)self
027:
028: /// @operator enumeration
029: /// Returns next element from enumeration.
030: /// @synopsis object *self
031: /**
032: * class AnyBindingEnumeration
033: *
034: * @author: Jani Lehtimäki
035: */
036: public class AnyBindingEnumeration extends AnyAbstractClass implements
037: BindingEnumeration {
038:
039: /// @constructor enumeration
040: /// Creates new enumeration from given value.
041: /// @synopsis enumeration(object value)
042: public static final Object[] newInstance = { "value" };
043:
044: public static final Any newInstance(Any value) {
045: return new AnyBindingEnumeration(value.enumeration());
046: }
047:
048: private BindingEnumeration _enumeration;
049:
050: public AnyBindingEnumeration(BindingEnumeration enumeration) {
051: super ();
052: _enumeration = enumeration;
053: }
054:
055: public AnyBindingEnumeration(Enumeration enumeration) {
056: super ();
057: _enumeration = new IndexedEnumeration(enumeration);
058: }
059:
060: public AnyBindingEnumeration(Iterator iterator) {
061: super ();
062: _enumeration = new AnyUtils.IteratorToEnumeration(iterator);
063: }
064:
065: public final anvil.script.ClassType classOf() {
066: return __class__;
067: }
068:
069: public int typeOf() {
070: return IS_ENUMERATION;
071: }
072:
073: public boolean isEnumeration() {
074: return true;
075: }
076:
077: public boolean toBoolean() {
078: return _enumeration.hasMoreElements();
079: }
080:
081: public Object toObject() {
082: return _enumeration;
083: }
084:
085: public BindingEnumeration enumeration() {
086: return _enumeration;
087: }
088:
089: public boolean hasMoreElements() {
090: return _enumeration.hasMoreElements();
091: }
092:
093: public Object nextKey() {
094: return _enumeration.nextKey();
095: }
096:
097: public Object nextElement() {
098: return _enumeration.nextElement();
099: }
100:
101: /// @method hasMore
102: /// Checks if there are more elements available.
103: /// @synopsis boolean hasMore()
104: public Any m_hasMore() {
105: return _enumeration.hasMoreElements() ? TRUE : FALSE;
106: }
107:
108: /// @method hasNext
109: /// Checks if there are more elements available.
110: /// @synopsis boolean hasNext()
111: public Any m_hasNext() {
112: return _enumeration.hasMoreElements() ? TRUE : FALSE;
113: }
114:
115: /// @method next
116: /// Retrieves the next element from enumeration.
117: /// @synopsis object next()
118: public Any m_next() {
119: return Any.create(_enumeration.nextElement());
120: }
121:
122: /// @method skip
123: /// @synopsis boolean skip() ;
124: /// Skips the next element
125: /// @synopsis boolean skip(int amount) ;
126: /// Skips up to given amount of elements
127: /// @param amount Number of elements to skip
128: /// @return true if there are still more elements
129: public static final Object[] p_skip = new Object[] { "*amount",
130: null };
131:
132: public Any m_skip(Any amount) {
133: if (amount != null) {
134: int n = amount.toInt();
135: if (n >= 0) {
136: BindingEnumeration e = _enumeration;
137: while (n-- > 0 && e.hasMoreElements()) {
138: e.nextElement();
139: }
140: }
141: } else {
142: _enumeration.nextElement();
143: }
144: return _enumeration.hasMoreElements() ? TRUE : FALSE;
145: }
146:
147: /// @method key
148: /// Takes the key of <b>next</b> element. This method must
149: /// be called before <code>next()</code>.
150: /// @synopsis object key()
151: public Any m_key() {
152: return Any.create(_enumeration.nextKey());
153: }
154:
155: /// @method both
156: /// Returns next key and element as map.
157: /// @synopsis map both()
158: public Any m_both() {
159: Any key = Any.create(_enumeration.nextKey());
160: Any value = Any.create(_enumeration.nextElement());
161: return new AnyMap(key, value);
162: }
163:
164: /// @method pipe
165: /// Returns new enumeration containing all the values of
166: /// this enumeration <i>piped</i> through converter.
167: /// Generated enumeration is evaluted lazily - only when more elements
168: /// are retrieved.
169: /// @synopsis enumeration pipe(object converter)
170: /// @synopsis enumeration pipe(object converter, object data)
171: /// @param converter Callable converter, receiving parameters <code>(value, key, data)</code>
172: /// @param data Optional data, passed as a third parameter to converter.
173: public static final Object[] p_pipe = new Object[] { null,
174: "converter", "*data", Any.UNDEFINED };
175:
176: public Any m_pipe(Context context, Any pipe, Any data) {
177: return new AnyBindingEnumeration(new AnyUtils.PipeEnumeration(
178: context, pipe, _enumeration, data));
179:
180: }
181:
182: /// @method select
183: /// Returns new enumeration that contains all values for
184: /// which the given selector returned <code>true</code>.
185: /// Generated enumeration is evaluted lazily - only when more elements
186: /// are retrieved.
187: /// @synopsis enumeration select(object selector)
188: /// @synopsis enumeration select(object selector, object data)
189: /// @param selector Callable selector, receiving parameters <code>(value, key, data)</code>
190: /// @param data Optional data, passed as a third parameter to selector.
191: public static final Object[] p_select = new Object[] { null,
192: "selector", "*data", Any.UNDEFINED };
193:
194: public Any m_select(Context context, Any selector, Any data) {
195: return new AnyBindingEnumeration(
196: new AnyUtils.SelectEnumeration(context, selector,
197: _enumeration, data));
198: }
199:
200: /// @method sort
201: /// Sorts the elements in this enumeration using given sort function.
202: /// This operation unfolds the enumeration to tree, and
203: /// returns depth-first enumeration to generated tree.
204: /// @synopsis enumeration sort(object comparator)
205: /// @synopsis enumeration sort(object comparator, object data)
206: /// @param comparator Callable comparator, receiving parameters <code>(value1, value2, data)</code>
207: /// @param data Optional data, passed as a third parameter to copmarator.
208: public static final Object[] p_sort = new Object[] { null,
209: "callable", "*data", Any.UNDEFINED };
210:
211: public Any m_sort(Context context, Any callable, Any data)
212: {
213: Comparator comparator = new AnyUtils.EnumerationComparator(context, callable, data);
214: java.util.TreeSet set = new java.util.TreeSet(comparator);
215: BindingEnumeration enum = _enumeration;
216: while(enum.hasMoreElements()) {
217: set.add(Any.create(enum.nextElement()));
218: }
219: return new AnyBindingEnumeration(new AnyUtils.IteratorToEnumeration(set.iterator()));
220: } /// @method join
221: /// Joins the elements of enumeration together with given clue.
222: /// @synopsis string join()
223: /// @synopsis string join(string clue)
224: /// @param clue Clue to join with, default is <code>", "</code>.
225: public static final Object[] p_join = new Object[] { "*clue", null };
226:
227: public Any m_join(String clue)
228: {
229: if (clue == null) {
230: clue = ", ";
231: }
232: StringBuffer buffer = new StringBuffer();
233: BindingEnumeration enum = _enumeration;
234: boolean more = enum.hasMoreElements();
235: while(more) {
236: buffer.append(enum.nextElement().toString());
237: more = enum.hasMoreElements();
238: if (more) {
239: buffer.append(clue);
240: }
241: }
242: return new AnyString(buffer.toString());
243: }
244:
245: /// @method purge
246: /// Iterates to end of enumeration and returns last element.
247: /// If enumeration didn't have any more elements, returns undefined.
248: /// @synopsis object purge()
249: public Any m_purge()
250: {
251: Any rv = Any.UNDEFINED;
252: BindingEnumeration enum = _enumeration;
253: while(enum.hasMoreElements()) {
254: rv = Any.create(enum.nextElement());
255: }
256: return rv;
257: }
258:
259: /// @method reverse
260: /// Creates a new enumeration which contains the rest of remainig
261: /// elements (and keys) of this enumeration reversed.
262: /// Operation exhausts this enumeration.
263: /// @synopsis enumeration reverse()
264: public Any m_reverse()
265: {
266: ArrayList list = new ArrayList();
267: BindingEnumeration enum = _enumeration;
268: while(enum.hasMoreElements()) {
269: list.add(new AnyMap(
270: Any.create(enum.nextKey()),
271: Any.create(enum.nextElement())));
272: }
273: return new AnyBindingEnumeration(new MapArrayEnumeration(
274: (AnyMap[])list.toArray(new AnyMap[list.size()]), false));
275: }
276:
277: public static final anvil.script.compiler.NativeClass __class__ = new anvil.script.compiler.NativeClass(
278: "enumeration",
279: AnyBindingEnumeration.class,
280: //DOC{{
281: ""
282: + " @class Enumeration\n"
283: + " Enumeration generates ordered series of (keys and) values.\n"
284: + " These keys and values can be retrived one at a time.\n"
285: + "\n"
286: + " @operator toBoolean\n"
287: + " Returns <code>true</code> if there are more elements available\n"
288: + " @synopsis boolean (boolean)self\n"
289: + " @operator enumeration \n"
290: + " Returns next element from enumeration.\n"
291: + " @synopsis object *self\n"
292: + " @constructor enumeration\n"
293: + " Creates new enumeration from given value.\n"
294: + " @synopsis enumeration(object value)\n"
295: + " @method hasMore\n"
296: + " Checks if there are more elements available.\n"
297: + " @synopsis boolean hasMore()\n"
298: + " @method hasNext\n"
299: + " Checks if there are more elements available.\n"
300: + " @synopsis boolean hasNext()\n"
301: + " @method next\n"
302: + " Retrieves the next element from enumeration.\n"
303: + " @synopsis object next()\n"
304: + " @method skip\n"
305: + " @synopsis boolean skip() ;\n"
306: + " Skips the next element\n"
307: + " @synopsis boolean skip(int amount) ;\n"
308: + " Skips up to given amount of elements\n"
309: + " @param amount Number of elements to skip\n"
310: + " @return true if there are still more elements\n"
311: + " @method key\n"
312: + " Takes the key of <b>next</b> element. This method must\n"
313: + " be called before <code>next()</code>.\n"
314: + " @synopsis object key()\n"
315: + " @method both\n"
316: + " Returns next key and element as map.\n"
317: + " @synopsis map both()\n"
318: + " @method pipe\n"
319: + " Returns new enumeration containing all the values of \n"
320: + " this enumeration <i>piped</i> through converter.\n"
321: + " Generated enumeration is evaluted lazily - only when more elements\n"
322: + " are retrieved.\n"
323: + " @synopsis enumeration pipe(object converter)\n"
324: + " @synopsis enumeration pipe(object converter, object data)\n"
325: + " @param converter Callable converter, receiving parameters <code>(value, key, data)</code>\n"
326: + " @param data Optional data, passed as a third parameter to converter.\n"
327: + " @method select\n"
328: + " Returns new enumeration that contains all values for\n"
329: + " which the given selector returned <code>true</code>.\n"
330: + " Generated enumeration is evaluted lazily - only when more elements\n"
331: + " are retrieved.\n"
332: + " @synopsis enumeration select(object selector)\n"
333: + " @synopsis enumeration select(object selector, object data)\n"
334: + " @param selector Callable selector, receiving parameters <code>(value, key, data)</code>\n"
335: + " @param data Optional data, passed as a third parameter to selector.\n"
336: + " @method sort\n"
337: + " Sorts the elements in this enumeration using given sort function.\n"
338: + " This operation unfolds the enumeration to tree, and\n"
339: + " returns depth-first enumeration to generated tree.\n"
340: + " @synopsis enumeration sort(object comparator)\n"
341: + " @synopsis enumeration sort(object comparator, object data)\n"
342: + " @param comparator Callable comparator, receiving parameters <code>(value1, value2, data)</code>\n"
343: + " @param data Optional data, passed as a third parameter to copmarator.\n"
344: + " @method join\n"
345: + " Joins the elements of enumeration together with given clue.\n"
346: + " @synopsis string join()\n"
347: + " @synopsis string join(string clue)\n"
348: + " @param clue Clue to join with, default is <code>\", \"</code>.\n"
349: + " @method purge\n"
350: + " Iterates to end of enumeration and returns last element.\n"
351: + " If enumeration didn't have any more elements, returns undefined.\n"
352: + " @synopsis object purge()\n"
353: + " @method reverse\n"
354: + " Creates a new enumeration which contains the rest of remainig \n"
355: + " elements (and keys) of this enumeration reversed. \n"
356: + " Operation exhausts this enumeration.\n"
357: + " @synopsis enumeration reverse()\n"
358: //}}DOC
359: );
360:
361: }
|