Skip to content

Commit

Permalink
MONDRIAN: Fix UnionIterator and its test under retroweaver.
Browse files Browse the repository at this point in the history
[git-p4: depot-paths = "//open/mondrian/": change = 11006]
  • Loading branch information
julianhyde committed May 3, 2008
1 parent 021d400 commit 19cd65f
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 2 deletions.
25 changes: 24 additions & 1 deletion src/main/mondrian/olap/Util.java
Expand Up @@ -1313,7 +1313,7 @@ public static <T> String commaList(
* }</pre></blockquote>
*
* @param iterables Array of one or more iterables
* @return iterable over the union
* @return iterable over the union of the iterables
*/
public static <T> Iterable<T> union(
final Iterable<? extends T>... iterables) {
Expand All @@ -1324,6 +1324,29 @@ public Iterator<T> iterator() {
};
}

/**
* Returns the union of a list of collections.
*
* <p>This method exists for code that will be retrowoven to run on JDK 1.4.
* Retroweaver has its own version of the {@link Iterable} interface, which
* is problematic since the {@link Collection} classes don't implement it.
* This method solves some of these problems by working in terms of
* collections; retroweaver deals with these correctly.
*
* @see #union(Iterable[])
*
* @param collections Array of one or more collections
* @return iterable over the union of the collections
*/
public static <T> Iterable<T> union(
final Collection<? extends T>... collections) {
return new Iterable<T>() {
public Iterator<T> iterator() {
return new UnionIterator<T>(collections);
}
};
}

/**
* Makes a name distinct from other names which have already been used
* and shorter than a length limit, adds it to the list, and returns it.
Expand Down
54 changes: 53 additions & 1 deletion src/main/mondrian/util/UnionIterator.java
Expand Up @@ -8,6 +8,8 @@
*/
package mondrian.util;

import mondrian.olap.Util;

import java.util.*;

/**
Expand All @@ -23,8 +25,37 @@ public class UnionIterator<T> implements Iterator<T> {
private final Iterator<Iterable<? extends T>> iterableIterator;
private Iterator<? extends T> iterator;

/**
* Creates a UnionIterator.
*
* @param iterables Array of iterables
*/
public UnionIterator(Iterable<? extends T>... iterables) {
this.iterableIterator = Arrays.asList(iterables).iterator();
List<Iterable<? extends T>> list;
if (Util.PreJdk15) {
// Retroweaver has its own version of Iterable, but
// Collection doesn't implement it. Solve the problem by
// creating an explicit Iterable wrapper.
list = new ArrayList<Iterable<? extends T>>(iterables.length);
for (Iterable<? extends T> iterable : iterables) {
//noinspection unchecked
list.add(new MyIterable(iterable));
}
} else {
list = Arrays.asList(iterables);
}
this.iterableIterator = list.iterator();
moveToNext();
}

public UnionIterator(Collection<? extends T>... iterables) {
List<Iterable<? extends T>> list =
new ArrayList<Iterable<? extends T>>(iterables.length);
for (Iterable<? extends T> iterable : iterables) {
//noinspection unchecked
list.add(new MyIterable(iterable));
}
this.iterableIterator = list.iterator();
moveToNext();
}

Expand All @@ -40,6 +71,10 @@ public T next() {
return t;
}

/**
* Moves to the next iterator that has at least one element.
* Called after finishing an iterator, or at the start.
*/
private void moveToNext() {
do {
if (iterableIterator.hasNext()) {
Expand All @@ -54,6 +89,23 @@ private void moveToNext() {
public void remove() {
iterator.remove();
}

private static class MyIterable<T> implements Iterable {
private final Iterable<T> iterable;

/**
* Creates a MyIterable.
*
* @param iterable Iterable
*/
public MyIterable(Iterable<T> iterable) {
this.iterable = iterable;
}

public Iterator<T> iterator() {
return iterable.iterator();
}
}
}

// End UnionIterator.java
22 changes: 22 additions & 0 deletions testsrc/main/mondrian/olap/UtilTestCase.java
Expand Up @@ -13,6 +13,8 @@

import java.util.*;

import mondrian.util.UnionIterator;

/**
* Tests for methods in {@link mondrian.olap.Util}.
*/
Expand Down Expand Up @@ -426,6 +428,26 @@ public void testUnionIterator() {
total += s + ";";
}
assertEquals("", total);

total = "";
UnionIterator<String> unionIterator =
new UnionIterator<String>(xyList, abcList);
while (unionIterator.hasNext()) {
total += unionIterator.next() + ";";
}
assertEquals("x;y;a;b;c;", total);

if (Util.PreJdk15) {
// Retrowoven code gives 'ArrayStoreException' when it encounters
// 'Util.union()' applied to java.util.Iterator objects.
return;
}

total = "";
for (String s : Util.union((Iterable<String>) xyList, abcList)) {
total += s + ";";
}
assertEquals("x;y;a;b;c;", total);
}
}

Expand Down

0 comments on commit 19cd65f

Please sign in to comment.