@@ -0,0 +1,2660 @@
+package no.ssb.vtl.script.operations.join;%0A%0Aimport java.util.Arrays;%0Aimport java.util.Iterator;%0Aimport java.util.List;%0A%0A/**%0A * Iterates over Cartesian product for an array of Iterables,%0A * %3Cp%3E%0A * Returns an array of Objects on each step containing values from each of the Iterables.%0A *%0A * @author jacek.p.kolodziejczyk@gmail.com%0A * @created 01-08-2010%0A */%0A%0Apublic class CartesianIterator%3CT%3E implements Iterator%3CList%3CT%3E%3E %7B%0A%0A    private final Iterable%3CT%3E%5B%5D iterables;%0A%0A    private final Iterator%3CT%3E%5B%5D iterators;%0A%0A    private T%5B%5D values;%0A%0A    private int size;%0A%0A    private boolean empty;%0A%0A    /**%0A     * Constructor%0A     *%0A     * @param iterables array of Iterables being the source for the Cartesian product.%0A     */%0A    public CartesianIterator(Iterable%3CT%3E... iterables) %7B%0A        this.size = iterables.length;%0A        this.iterables = iterables;%0A        this.iterators = (Iterator%3CT%3E%5B%5D) new Iterator%5Bsize%5D;%0A%0A        // Initialize iterators%0A        for (int i = 0; i %3C size; i++) %7B%0A            iterators%5Bi%5D = iterables%5Bi%5D.iterator();%0A            // If one of the iterators is empty then the whole Cartesian product is empty%0A            if (!iterators%5Bi%5D.hasNext()) %7B%0A                empty = true;%0A                break;%0A            %7D%0A        %7D%0A%0A        // Initialize the tuple of the iteration values except the last one%0A        if (!empty) %7B%0A            values = (T%5B%5D) new Object%5Bsize%5D;%0A            for (int i = 0; i %3C size - 1; i++) setNextValue(i);%0A        %7D%0A%0A    %7D%0A%0A    @Override%0A    public boolean hasNext() %7B%0A        if (empty) return false;%0A        for (int i = 0; i %3C size; i++)%0A            if (iterators%5Bi%5D.hasNext())%0A                return true;%0A        return false;%0A%0A    %7D%0A%0A    @Override%0A    public List%3CT%3E next() %7B%0A        // Find first in reverse order iterator the has a next element%0A        int cursor;%0A        for (cursor = size - 1; cursor %3E= 0; cursor--)%0A            if (iterators%5Bcursor%5D.hasNext()) break;%0A        // Initialize iterators next from the current one%0A        for (int i = cursor + 1; i %3C size; i++) iterators%5Bi%5D = iterables%5Bi%5D.iterator();%0A        // Get the next value from the current iterator and all the next ones%0A        for (int i = cursor; i %3C size; i++) setNextValue(i);%0A        return Arrays.asList((T%5B%5D) values.clone());%0A    %7D%0A%0A    /**%0A     * Gets the next value provided there is one from the iterator at the given index.%0A     *%0A     * @param index%0A     */%0A    private void setNextValue(int index) %7B%0A        Iterator%3CT%3E it = iterators%5Bindex%5D;%0A        if (it.hasNext())%0A            values%5Bindex%5D = it.next();%0A    %7D%0A%0A    @Override%0A    public void remove() %7B%0A        throw new UnsupportedOperationException();%0A    %7D%0A%0A%7D%0A%0A

Add CartesianIterator