TraversalList.java :  » Net » Mondrian-3.2.0 » mondrian » util » Java Open Source

Java Open Source » Net » Mondrian 3.2.0 
Mondrian 3.2.0 » mondrian » util » TraversalList.java
/*
// $Id: //open/mondrian-release/3.2/src/main/mondrian/util/TraversalList.java#1 $
// This software is subject to the terms of the Eclipse Public License v1.0
// Agreement, available at the following URL:
// http://www.eclipse.org/legal/epl-v10.html.
// Copyright (C) 2006-2009 Julian Hyde
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
*/
/*
// $Id: //open/mondrian-release/3.2/src/main/mondrian/util/TraversalList.java#1 $
// This software is subject to the terms of the Eclipse Public License v1.0
// Agreement, available at the following URL:
// http://www.eclipse.org/legal/epl-v10.html.
// Copyright (C) 2006-2009 Julian Hyde
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
*/
package mondrian.util;

import java.util.*;
import java.lang.reflect.Array;

/**
 * Implementation of {@link java.util.List} for transposing an array of
 * lists.
 *
 * @author Luis F. Canals
 * @version $Id: //open/mondrian-release/3.2/src/main/mondrian/util/TraversalList.java#1 $
 * @since Dec, 2007
 */
public class TraversalList<T> extends UnsupportedList<T[]> {
    private boolean asInternalArray = false;
    private T[][] internalArray = null;
    private final List<T>[] lists;
    private final Class<T> clazz;

    public TraversalList(
        final List<T>[] lists,
        Class<T> clazz)
    {
        this.lists = lists;
        this.clazz = clazz;
    }

    public T[] get(int index) {
        if (this.asInternalArray) {
            return internalArray[index];
        } else {
            final T[] tuples = (T[]) Array.newInstance(clazz, lists.length);
            for (int i = 0; i < lists.length; i++) {
                tuples[i] = lists[i].get(index);
            }
            return tuples;
        }
    }

    public Iterator<T[]> iterator() {
        return new Iterator<T[]>() {
            private int currentIndex = 0;
            private T[] precalculated;

            public T[] next() {
                if (precalculated != null) {
                    final T[] t = precalculated;
                    precalculated = null;
                    currentIndex++;
                    return t;
                } else {
                    return get(currentIndex++);
                }
            }

            public boolean hasNext() {
                try {
                    precalculated = get(currentIndex);
                    return true;
                } catch (IndexOutOfBoundsException e) {
                    return false;
                }
            }

            public void remove() {
                throw new UnsupportedOperationException();
            }
        };
    }

    // Used by Collections.sort
    public ListIterator<T[]> listIterator(final int index) {
        return new ListItr(index) {
            public void set(final T[] l) {
                TraversalList.this.set(cursor - 1, l);
            }
        };
    }

    // Used by Collections.sort
    public ListIterator<T[]> listIterator() {
        return new ListItr(0) {
            public void set(final T[] l) {
                TraversalList.this.set(cursor - 1, l);
            }
        };
    }

    public int size() {
        return lists[0].size();
    }

    public List<T[]> subList(final int first, final int last) {
        return new AbstractList<T[]>() {
            public T[] get(int index) {
                return TraversalList.this.get(index + first);
            }
            public int size() {
                return last - first;
            }
        };
    }

    private T[][] materialize(Object[][] a) {
        final T[][] array;
        if (a != null
            && a.length == size()
            && a.getClass().getComponentType() == clazz)
        {
            array = (T[][]) a;
        } else {
            // TODO: use reflection to create a real T[][]
            array = (T[][]) new Object[this.size()][];
        }
        int k = 0;
        for (T[] x : this) {
            array[k++] = x;
        }
        this.asInternalArray = true;
        this.internalArray = array;
        return array;
    }

    @Override
    public <S> S[] toArray(S[] a) {
        // Our requirements are stronger than the general toArray(T[] a)
        // contract. We will use the user's array 'a' only if it is PRECISELY
        // the right type and size; otherwise we will allocate our own array.
        return (S[]) materialize((Object[][]) a);
    }

    public Object[] toArray() {
        return materialize(null);
    }

    // Used by Collections.sort
    public T[] set(final int index, T[] l) {
        if (this.asInternalArray) {
            final T[] previous = this.internalArray[index];
            this.internalArray[index] = l;
            return previous;
        } else {
            throw new UnsupportedOperationException();
        }
    }
}

// End TraversalList.java
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.