001: /*
002: * <copyright>
003: *
004: * Copyright 1997-2004 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026:
027: /**
028: * Mappings is a class of static methods for transforming Collections via
029: * mapping functions.
030: *
031: * The names of the methods are intended to echo CommonLisp functions
032: * with similar functionality.
033: *
034: * This is functionality which should be part of Java Collections framework
035: * but is sadly missing.
036: */package org.cougaar.util;
037:
038: import java.util.ArrayList;
039: import java.util.Collection;
040: import java.util.Iterator;
041:
042: public final class Mappings {
043: private Mappings() {
044: };
045:
046: /** Compute an element-by-element map of the input collection.
047: * Essentially, this means constructing a new Collection which is
048: * contains the results of applying the Mapping to each element
049: * of the input collection.
050: *
051: * The Mapping may not return null or an IllegalArgumentException will
052: * be thrown (use mapcan instead).
053: *
054: * @return a Collection representing the mapped collection.
055: * @param result a Collection to add elements to. If null, defaults to
056: * an new ArrayList.
057: **/
058: public static Collection mapcar(Mapping m, Collection input,
059: Collection result) {
060: if (result == null)
061: result = new ArrayList(input.size());
062:
063: for (Iterator i = input.iterator(); i.hasNext();) {
064: Object e = i.next();
065: Object me = m.map(e);
066: if (me == null)
067: throw new IllegalArgumentException("mapcar Mapping "
068: + m + " returned null when applied to" + e);
069: result.add(me);
070: }
071: return result;
072: }
073:
074: /** equivalent to mapcar(Mapping m, Collection c, null) which
075: * implies that the return value will be a new ArrayList.
076: */
077: public static Collection mapcar(Mapping m, Collection c) {
078: return mapcar(m, c, null);
079: }
080:
081: /** Compute an element-to-n-element map of the input collection.
082: * Essentially, this means constructing a new Collection which is
083: * a concatenation of the resulting collections resulting from the
084: * application of the Mapping to each element of the input collection.
085: *
086: * In general, the Mapping should return a Collection of zero or more
087: * elements to be added to the result map.
088: *
089: * As a convenience, the Mapping may also return null, which is equivalent
090: * to returning an empty collection, or a Non-Collection, which is equivalent
091: * to returning a Collection with one element.
092: *
093: * @return an ArrayList representing the mapped collection.
094: * @param result a Collection to add elements to. If null, creates a new ArrayList.
095: **/
096: public static Collection mapcan(Mapping m, Collection input,
097: Collection result) {
098: if (result == null)
099: result = new ArrayList();
100: for (Iterator i = input.iterator(); i.hasNext();) {
101: Object e = i.next();
102: Object me = m.map(e);
103: if (me != null) {
104: if (me instanceof Collection) {
105: result.addAll((Collection) me);
106: } else {
107: result.add(me);
108: }
109: }
110: }
111: return result;
112: }
113:
114: /** equivalent to mapcan(Mapping m, Collection c, null) which
115: * implies that the return value will be a new ArrayList.
116: */
117: public static Collection mapcan(Mapping m, Collection c) {
118: return mapcan(m, c, null);
119: }
120:
121: /** Map over an iterator **/
122: public static Iterator map(final Mapping m, final Iterator it) {
123: return new Iterator() {
124: public Object next() {
125: return m.map(it.next());
126: }
127:
128: public boolean hasNext() {
129: return it.hasNext();
130: }
131:
132: public void remove() {
133: it.remove();
134: }
135: };
136: }
137: }
|