/*
* $Id: AnyBindingEnumeration.java,v 1.23 2002/09/16 08:05:02 jkl Exp $
*
* Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
*
* Use is subject to license terms, as defined in
* Anvil Sofware License, Version 1.1. See LICENSE
* file, or http://njet.org/license-1.1.txt
*/
package anvil.core;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.Iterator;
import anvil.core.Any;
import anvil.script.Context;
import anvil.java.util.BindingEnumeration;
/// @class Enumeration
/// Enumeration generates ordered series of (keys and) values.
/// These keys and values can be retrived one at a time.
///
/// @operator toBoolean
/// Returns <code>true</code> if there are more elements available
/// @synopsis boolean (boolean)self
/// @operator enumeration
/// Returns next element from enumeration.
/// @synopsis object *self
/**
* class AnyBindingEnumeration
*
* @author: Jani Lehtim�ki
*/
public class AnyBindingEnumeration extends AnyAbstractClass implements BindingEnumeration
{
/// @constructor enumeration
/// Creates new enumeration from given value.
/// @synopsis enumeration(object value)
public static final Object[] newInstance = { "value" };
public static final Any newInstance(Any value)
{
return new AnyBindingEnumeration(value.enumeration());
}
private BindingEnumeration _enumeration;
public AnyBindingEnumeration(BindingEnumeration enumeration)
{
super();
_enumeration = enumeration;
}
public AnyBindingEnumeration(Enumeration enumeration)
{
super();
_enumeration = new IndexedEnumeration(enumeration);
}
public AnyBindingEnumeration(Iterator iterator)
{
super();
_enumeration = new AnyUtils.IteratorToEnumeration(iterator);
}
public final anvil.script.ClassType classOf()
{
return __class__;
}
public int typeOf()
{
return IS_ENUMERATION;
}
public boolean isEnumeration()
{
return true;
}
public boolean toBoolean()
{
return _enumeration.hasMoreElements();
}
public Object toObject()
{
return _enumeration;
}
public BindingEnumeration enumeration()
{
return _enumeration;
}
public boolean hasMoreElements()
{
return _enumeration.hasMoreElements();
}
public Object nextKey()
{
return _enumeration.nextKey();
}
public Object nextElement()
{
return _enumeration.nextElement();
}
/// @method hasMore
/// Checks if there are more elements available.
/// @synopsis boolean hasMore()
public Any m_hasMore()
{
return _enumeration.hasMoreElements() ? TRUE : FALSE;
}
/// @method hasNext
/// Checks if there are more elements available.
/// @synopsis boolean hasNext()
public Any m_hasNext()
{
return _enumeration.hasMoreElements() ? TRUE : FALSE;
}
/// @method next
/// Retrieves the next element from enumeration.
/// @synopsis object next()
public Any m_next()
{
return Any.create(_enumeration.nextElement());
}
/// @method skip
/// @synopsis boolean skip() ;
/// Skips the next element
/// @synopsis boolean skip(int amount) ;
/// Skips up to given amount of elements
/// @param amount Number of elements to skip
/// @return true if there are still more elements
public static final Object[] p_skip = new Object[] { "*amount", null };
public Any m_skip(Any amount)
{
if (amount != null) {
int n = amount.toInt();
if (n >= 0) {
BindingEnumeration e = _enumeration;
while(n-- > 0 && e.hasMoreElements()) {
e.nextElement();
}
}
} else {
_enumeration.nextElement();
}
return _enumeration.hasMoreElements() ? TRUE : FALSE;
}
/// @method key
/// Takes the key of <b>next</b> element. This method must
/// be called before <code>next()</code>.
/// @synopsis object key()
public Any m_key()
{
return Any.create(_enumeration.nextKey());
}
/// @method both
/// Returns next key and element as map.
/// @synopsis map both()
public Any m_both()
{
Any key = Any.create(_enumeration.nextKey());
Any value = Any.create(_enumeration.nextElement());
return new AnyMap(key, value);
}
/// @method pipe
/// Returns new enumeration containing all the values of
/// this enumeration <i>piped</i> through converter.
/// Generated enumeration is evaluted lazily - only when more elements
/// are retrieved.
/// @synopsis enumeration pipe(object converter)
/// @synopsis enumeration pipe(object converter, object data)
/// @param converter Callable converter, receiving parameters <code>(value, key, data)</code>
/// @param data Optional data, passed as a third parameter to converter.
public static final Object[] p_pipe = new Object[] { null, "converter", "*data", Any.UNDEFINED };
public Any m_pipe(Context context, Any pipe, Any data)
{
return new AnyBindingEnumeration(new AnyUtils.PipeEnumeration(
context, pipe, _enumeration, data));
}
/// @method select
/// Returns new enumeration that contains all values for
/// which the given selector returned <code>true</code>.
/// Generated enumeration is evaluted lazily - only when more elements
/// are retrieved.
/// @synopsis enumeration select(object selector)
/// @synopsis enumeration select(object selector, object data)
/// @param selector Callable selector, receiving parameters <code>(value, key, data)</code>
/// @param data Optional data, passed as a third parameter to selector.
public static final Object[] p_select = new Object[] { null, "selector", "*data", Any.UNDEFINED };
public Any m_select(Context context, Any selector, Any data)
{
return new AnyBindingEnumeration(new AnyUtils.SelectEnumeration(
context, selector, _enumeration, data));
}
/// @method sort
/// Sorts the elements in this enumeration using given sort function.
/// This operation unfolds the enumeration to tree, and
/// returns depth-first enumeration to generated tree.
/// @synopsis enumeration sort(object comparator)
/// @synopsis enumeration sort(object comparator, object data)
/// @param comparator Callable comparator, receiving parameters <code>(value1, value2, data)</code>
/// @param data Optional data, passed as a third parameter to copmarator.
public static final Object[] p_sort = new Object[] { null, "callable", "*data", Any.UNDEFINED };
public Any m_sort(Context context, Any callable, Any data)
{
Comparator comparator = new AnyUtils.EnumerationComparator(context, callable, data);
java.util.TreeSet set = new java.util.TreeSet(comparator);
BindingEnumeration enum = _enumeration;
while(enum.hasMoreElements()) {
set.add(Any.create(enum.nextElement()));
}
return new AnyBindingEnumeration(new AnyUtils.IteratorToEnumeration(set.iterator()));
}
/// @method join
/// Joins the elements of enumeration together with given clue.
/// @synopsis string join()
/// @synopsis string join(string clue)
/// @param clue Clue to join with, default is <code>", "</code>.
public static final Object[] p_join = new Object[] { "*clue", null };
public Any m_join(String clue)
{
if (clue == null) {
clue = ", ";
}
StringBuffer buffer = new StringBuffer();
BindingEnumeration enum = _enumeration;
boolean more = enum.hasMoreElements();
while(more) {
buffer.append(enum.nextElement().toString());
more = enum.hasMoreElements();
if (more) {
buffer.append(clue);
}
}
return new AnyString(buffer.toString());
}
/// @method purge
/// Iterates to end of enumeration and returns last element.
/// If enumeration didn't have any more elements, returns undefined.
/// @synopsis object purge()
public Any m_purge()
{
Any rv = Any.UNDEFINED;
BindingEnumeration enum = _enumeration;
while(enum.hasMoreElements()) {
rv = Any.create(enum.nextElement());
}
return rv;
}
/// @method reverse
/// Creates a new enumeration which contains the rest of remainig
/// elements (and keys) of this enumeration reversed.
/// Operation exhausts this enumeration.
/// @synopsis enumeration reverse()
public Any m_reverse()
{
ArrayList list = new ArrayList();
BindingEnumeration enum = _enumeration;
while(enum.hasMoreElements()) {
list.add(new AnyMap(
Any.create(enum.nextKey()),
Any.create(enum.nextElement())));
}
return new AnyBindingEnumeration(new MapArrayEnumeration(
(AnyMap[])list.toArray(new AnyMap[list.size()]), false));
}
public static final anvil.script.compiler.NativeClass __class__ =
new anvil.script.compiler.NativeClass("enumeration", AnyBindingEnumeration.class,
//DOC{{
""+
" @class Enumeration\n" +
" Enumeration generates ordered series of (keys and) values.\n" +
" These keys and values can be retrived one at a time.\n" +
"\n" +
" @operator toBoolean\n" +
" Returns <code>true</code> if there are more elements available\n" +
" @synopsis boolean (boolean)self\n" +
" @operator enumeration \n" +
" Returns next element from enumeration.\n" +
" @synopsis object *self\n" +
" @constructor enumeration\n" +
" Creates new enumeration from given value.\n" +
" @synopsis enumeration(object value)\n" +
" @method hasMore\n" +
" Checks if there are more elements available.\n" +
" @synopsis boolean hasMore()\n" +
" @method hasNext\n" +
" Checks if there are more elements available.\n" +
" @synopsis boolean hasNext()\n" +
" @method next\n" +
" Retrieves the next element from enumeration.\n" +
" @synopsis object next()\n" +
" @method skip\n" +
" @synopsis boolean skip() ;\n" +
" Skips the next element\n" +
" @synopsis boolean skip(int amount) ;\n" +
" Skips up to given amount of elements\n" +
" @param amount Number of elements to skip\n" +
" @return true if there are still more elements\n" +
" @method key\n" +
" Takes the key of <b>next</b> element. This method must\n" +
" be called before <code>next()</code>.\n" +
" @synopsis object key()\n" +
" @method both\n" +
" Returns next key and element as map.\n" +
" @synopsis map both()\n" +
" @method pipe\n" +
" Returns new enumeration containing all the values of \n" +
" this enumeration <i>piped</i> through converter.\n" +
" Generated enumeration is evaluted lazily - only when more elements\n" +
" are retrieved.\n" +
" @synopsis enumeration pipe(object converter)\n" +
" @synopsis enumeration pipe(object converter, object data)\n" +
" @param converter Callable converter, receiving parameters <code>(value, key, data)</code>\n" +
" @param data Optional data, passed as a third parameter to converter.\n" +
" @method select\n" +
" Returns new enumeration that contains all values for\n" +
" which the given selector returned <code>true</code>.\n" +
" Generated enumeration is evaluted lazily - only when more elements\n" +
" are retrieved.\n" +
" @synopsis enumeration select(object selector)\n" +
" @synopsis enumeration select(object selector, object data)\n" +
" @param selector Callable selector, receiving parameters <code>(value, key, data)</code>\n" +
" @param data Optional data, passed as a third parameter to selector.\n" +
" @method sort\n" +
" Sorts the elements in this enumeration using given sort function.\n" +
" This operation unfolds the enumeration to tree, and\n" +
" returns depth-first enumeration to generated tree.\n" +
" @synopsis enumeration sort(object comparator)\n" +
" @synopsis enumeration sort(object comparator, object data)\n" +
" @param comparator Callable comparator, receiving parameters <code>(value1, value2, data)</code>\n" +
" @param data Optional data, passed as a third parameter to copmarator.\n" +
" @method join\n" +
" Joins the elements of enumeration together with given clue.\n" +
" @synopsis string join()\n" +
" @synopsis string join(string clue)\n" +
" @param clue Clue to join with, default is <code>\", \"</code>.\n" +
" @method purge\n" +
" Iterates to end of enumeration and returns last element.\n" +
" If enumeration didn't have any more elements, returns undefined.\n" +
" @synopsis object purge()\n" +
" @method reverse\n" +
" Creates a new enumeration which contains the rest of remainig \n" +
" elements (and keys) of this enumeration reversed. \n" +
" Operation exhausts this enumeration.\n" +
" @synopsis enumeration reverse()\n"
//}}DOC
);
}