org.eclipse.xtext.nodemodel.util.NodeTreeIterator.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.xtext.nodemodel.util.NodeTreeIterator.java

Source

/*******************************************************************************
 * Copyright (c) 2010 itemis AG (http://www.itemis.eu) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *******************************************************************************/
package org.eclipse.xtext.nodemodel.util;

import java.util.NoSuchElementException;

import org.eclipse.xtext.nodemodel.BidiTreeIterator;
import org.eclipse.xtext.nodemodel.ICompositeNode;
import org.eclipse.xtext.nodemodel.INode;

import com.google.common.collect.UnmodifiableIterator;

/**
 * @author Sebastian Zarnekow - Initial contribution and API
 */
public class NodeTreeIterator extends UnmodifiableIterator<INode> implements BidiTreeIterator<INode> {

    private final INode root;
    private INode lastNextReturned;
    private INode lastPreviousReturned;
    private INode next;
    private boolean nextComputed = false;
    private boolean pruned = false;
    private INode previous;
    private boolean previousComputed = false;

    public NodeTreeIterator(INode root) {
        this.root = root;
    }

    @Override
    public boolean hasNext() {
        if (nextComputed)
            return next != null;

        if (lastNextReturned == null) {
            next = lastPreviousReturned != null ? lastPreviousReturned : root;
        } else if (!pruned && lastNextReturned instanceof ICompositeNode
                && ((ICompositeNode) lastNextReturned).hasChildren()) {
            next = ((ICompositeNode) lastNextReturned).getFirstChild();
        } else if (root.equals(lastNextReturned)) {
            next = null;
        } else if ((next = lastNextReturned.getNextSibling()) != null) {
            // next found
        } else {
            for (INode parent = lastNextReturned.getParent(); next == null
                    && !root.equals(parent); parent = parent.getParent()) {
                next = parent.getNextSibling();
            }
        }
        nextComputed = true;
        return next != null;
    }

    @Override
    public INode next() {
        if (next == null && !hasNext())
            throw new NoSuchElementException();
        lastNextReturned = next;
        lastPreviousReturned = null;
        afterAdvance();
        return lastNextReturned;
    }

    protected void afterAdvance() {
        next = null;
        previous = null;
        nextComputed = false;
        previousComputed = false;
        pruned = false;
    }

    @Override
    public boolean hasPrevious() {
        if (previousComputed)
            return previous != null;

        if (lastPreviousReturned == null) {
            previous = lastNextReturned != null ? lastNextReturned : root;
        } else if (!pruned && lastPreviousReturned instanceof ICompositeNode
                && ((ICompositeNode) lastPreviousReturned).hasChildren()) {
            previous = ((ICompositeNode) lastPreviousReturned).getLastChild();
        } else if (root.equals(lastPreviousReturned)) {
            previous = null;
        } else if ((previous = lastPreviousReturned.getPreviousSibling()) != null) {
            // previous found
        } else {
            for (INode parent = lastPreviousReturned.getParent(); previous == null
                    && !root.equals(parent); parent = parent.getParent()) {
                previous = parent.getPreviousSibling();
            }
        }
        previousComputed = true;
        return previous != null;
    }

    @Override
    public INode previous() {
        if (previous == null && !hasPrevious())
            throw new NoSuchElementException();
        lastPreviousReturned = previous;
        lastNextReturned = null;
        afterAdvance();
        return lastPreviousReturned;
    }

    @Override
    public void prune() {
        if (lastPreviousReturned == null && lastNextReturned == null)
            throw new IllegalStateException("Cannot prune before #next or #previous");
        pruned = true;
    }

}