com.lastcalc.TokenList.java Source code

Java tutorial

Introduction

Here is the source code for com.lastcalc.TokenList.java

Source

/*******************************************************************************
 * LastCalc - The last calculator you'll ever need
 * Copyright (C) 2011, 2012 Uprizer Labs LLC
 * 
 * This program is free software: you can redistribute it and/or modify it 
 * under the terms of the GNU Affero General Public License as published 
 * by the Free Software Foundation, either version 3 of the License, or 
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR 
 * PURPOSE.  See the GNU Affero General Public License for more 
 * details.
 ******************************************************************************/
package com.lastcalc;

import java.io.Serializable;
import java.util.*;

import com.google.common.collect.*;

public abstract class TokenList implements Iterable<Object>, Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 6411043222094812410L;

    public static SimpleTokenList create(final List<Object> list) {
        return new SimpleTokenList(Lists.newArrayList(list));
    }

    public static SimpleTokenList createD(final Object... list) {
        return new SimpleTokenList(list);
    }

    public int indexOf(final Object o) {
        for (int x = 0; x < size(); x++) {
            if (get(x).equals(o))
                return x;
        }
        return -1;
    }

    public final void addAllTo(final Collection<Object> coll) {
        for (final Object o : this) {
            coll.add(o);
        }
    }

    @Override
    public String toString() {
        return Misc.joiner.join(this);
    }

    public SubTokenList subList(final int start, final int end) {
        return new SubTokenList(this, start, end);
    }

    public CompositeTokenList replaceWithTokens(final int start, final int end, final Object... replaceWith) {
        return new CompositeTokenList(subList(0, start), new SimpleTokenList(replaceWith), subList(end, size()));
    }

    public CompositeTokenList replaceWithTokenList(final int start, final int end, final TokenList replaceWith) {
        return new CompositeTokenList(subList(0, start), replaceWith, subList(end, size()));
    }

    public CompositeTokenList append(final TokenList... toAppend) {
        final ArrayList<TokenList> tls = Lists.newArrayListWithCapacity(toAppend.length + 1);
        tls.add(this);
        for (int x = 0; x < toAppend.length; x++) {
            tls.add(toAppend[x]);
        }
        return new CompositeTokenList(tls);
    }

    public abstract TLPos getPosInParent(int ix);

    public abstract Object get(int ix);

    public abstract int size();

    public final boolean isEmpty() {
        return size() == 0;
    }

    private int cachedHashCode = 0;

    @Override
    public int hashCode() {
        if (cachedHashCode == 0) {
            int hashCode = 1;
            for (final Object o : this) {
                hashCode = 31 * hashCode + o.hashCode();
            }
            cachedHashCode = hashCode;
        }
        return cachedHashCode;
    }

    @Override
    public boolean equals(final Object obj) {
        if (!(obj instanceof TokenList))
            return false;
        final TokenList other = (TokenList) obj;
        if (size() != other.size())
            return false;
        for (int x = 0; x < size(); x++) {
            if (!get(x).equals(other.get(x)))
                return false;
        }
        return true;
    }

    @Override
    public Iterator<Object> iterator() {
        return new AbstractIterator<Object>() {

            int pos = 0;

            @Override
            protected Object computeNext() {
                if (pos == TokenList.this.size())
                    return endOfData();
                else
                    return TokenList.this.get(pos++);
            }
        };
    }

    public static final class SimpleTokenList extends TokenList {
        private static final long serialVersionUID = -6387012802414390386L;
        private final ArrayList<Object> tokens;

        public SimpleTokenList(final Object... tokens) {
            this(Lists.newArrayList(tokens));
        }

        public SimpleTokenList(final ArrayList<Object> tokens) {
            this.tokens = tokens;
        }

        @Override
        public Object get(final int ix) {
            return tokens.get(ix);
        }

        @Override
        public int size() {
            return tokens.size();
        }

        @Override
        public Iterator<Object> iterator() {
            return tokens.iterator();
        }

        @Override
        public TLPos getPosInParent(final int ix) {
            return new TLPos(this, ix);
        }
    }

    public static final class SubTokenList extends TokenList {
        private static final long serialVersionUID = -4306902697632956336L;
        public final TokenList parent;
        private final int start, end;

        public SubTokenList(final TokenList parent, final int start, final int end) {
            this.parent = parent;
            if (end < start)
                throw new IllegalArgumentException("End must be > Start");
            if (start < 0)
                throw new IllegalArgumentException("Start must be >= 0");
            if (end > parent.size())
                throw new IllegalArgumentException("End must be less than or equal to size of parent TokenList");
            this.start = start;
            this.end = end;
        }

        @Override
        public Object get(final int ix) {
            if (start + ix < end)
                return parent.get(ix + start);
            else
                throw new ArrayIndexOutOfBoundsException();
        }

        @Override
        public int size() {
            return end - start;
        }

        @Override
        public TLPos getPosInParent(final int ix) {
            return parent.getPosInParent(start + ix);
        }
    }

    public static final class CompositeTokenList extends TokenList {

        private static final long serialVersionUID = 96315179953921395L;
        public final ArrayList<TokenList> tokenLists;
        private final int[] sizes;

        private final Object[] getCache;

        public CompositeTokenList(final TokenList... tokenLists) {
            this(Lists.newArrayList(tokenLists));
        }

        public CompositeTokenList(final ArrayList<TokenList> tokenLists) {
            this.tokenLists = tokenLists;
            sizes = new int[tokenLists.size()];
            for (int x = 0; x < tokenLists.size(); x++) {
                sizes[x] = tokenLists.get(x).size();
            }
            int sz = 0;
            for (int x = 0; x < sizes.length; x++) {
                sz += sizes[x];
            }
            getCache = new Object[sz];
        }

        @Override
        public Object get(final int oix) {
            if (getCache[oix] == null) {
                int l = 0, ix = oix;
                while (ix >= sizes[l]) {
                    ix -= sizes[l];
                    l++;
                    if (l == sizes.length)
                        throw new ArrayIndexOutOfBoundsException();
                }
                getCache[oix] = tokenLists.get(l).get(ix);
            }
            return getCache[oix];
        }

        @Override
        public Iterator<Object> iterator() {
            return Iterables.concat(tokenLists).iterator();
        }

        @Override
        public int size() {
            return getCache.length;
        }

        @Override
        public TLPos getPosInParent(int ix) {
            int l = 0;
            while (ix >= sizes[l]) {
                ix -= sizes[l];
                l++;
                if (l == sizes.length)
                    throw new ArrayIndexOutOfBoundsException();
            }
            return tokenLists.get(l).getPosInParent(ix);
        }
    }

    public static final class TLPos {
        public final TokenList tl;
        public final int pos;

        public TLPos(final TokenList tl, final int pos) {
            this.tl = tl;
            this.pos = pos;

        }
    }
}