com.phoenixst.plexus.util.FilteredTraverser.java Source code

Java tutorial

Introduction

Here is the source code for com.phoenixst.plexus.util.FilteredTraverser.java

Source

/*
 *  $Id: FilteredTraverser.java,v 1.19 2005/10/03 15:20:46 rconner Exp $
 *
 *  Copyright (C) 1994-2005 by Phoenix Software Technologists,
 *  Inc. and others.  All rights reserved.
 *
 *  THIS PROGRAM AND DOCUMENTATION IS PROVIDED UNDER THE TERMS OF THE
 *  COMMON PUBLIC LICENSE ("AGREEMENT") WHICH ACCOMPANIES IT.  ANY
 *  USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES
 *  RECIPIENT'S ACCEPTANCE OF THE AGREEMENT.
 *
 *  The license text can also be found at
 *    http://opensource.org/licenses/cpl.php
 */

package com.phoenixst.plexus.util;

import java.util.NoSuchElementException;

import org.apache.commons.collections.Predicate;

import com.phoenixst.collections.OrderedPair;
import com.phoenixst.plexus.*;

/**
 *  A simple filtered <code>Traverser</code>.  Because this class must
 *  advance the underlying <code>Traverser</code> to function
 *  properly, {@link #remove} and {@link #removeEdge} may delegate to
 *  {@link Graph#removeNode Graph.removeNode( node )} and {@link
 *  Graph#removeEdge Graph.removeEdge( edge )} in some situations.
 *
 *  @version    $Revision: 1.19 $
 *  @author     Ray A. Conner
 *
 *  @since      1.0
 */
public class FilteredTraverser implements Traverser {

    private final Graph graph;
    private final Traverser delegate;
    private final Predicate traverserPredicate;

    private Object currentNode = null;
    private Object nextNode = null;
    private Graph.Edge currentEdge = null;
    private Graph.Edge nextEdge = null;

    private boolean isCurrentValid = false;
    private boolean isNextValid = false;

    ////////////////////////////////////////
    // Constructors
    ////////////////////////////////////////

    /**
     *  Creates a new <code>FilteredTraverser</code> which will throw
     *  an <code>IllegalStateException</code> if <code>remove()</code>
     *  or <code>removeEdge()</code> is called after
     *  <code>hasNext()</code> without an intervening call to
     *  <code>next()</code>.
     */
    public FilteredTraverser(Traverser delegate, Predicate traverserPredicate) {
        this(null, delegate, traverserPredicate);
    }

    /**
     *  Creates a new <code>FilteredTraverser</code> which will have
     *  {@link #remove()} and {@link #removeEdge()} delegate to {@link
     *  Graph#removeNode Graph.removeNode( node )} and {@link
     *  Graph#removeEdge Graph.removeEdge( edge )} if necessary.
     *  Depending upon the <code>Graph</code> implementation, this may
     *  invalidate this <code>Traverser</code>.
     */
    public FilteredTraverser(Graph graph, Traverser delegate, Predicate traverserPredicate) {
        super();
        this.graph = graph;
        this.delegate = delegate;
        this.traverserPredicate = traverserPredicate;
    }

    ////////////////////////////////////////
    // Traverser
    ////////////////////////////////////////

    public boolean hasNext() {
        if (!isNextValid) {
            OrderedPair pair = new OrderedPair();
            while (delegate.hasNext()) {
                Object node = delegate.next();
                Graph.Edge edge = delegate.getEdge();
                pair.setFirst(edge.getOtherEndpoint(node));
                pair.setSecond(edge);
                if (traverserPredicate.evaluate(pair)) {
                    nextNode = node;
                    nextEdge = edge;
                    isNextValid = true;
                    break;
                }
            }
        }
        return isNextValid;
    }

    public Object next() {
        if (!hasNext()) {
            throw new NoSuchElementException();
        }
        currentNode = nextNode;
        currentEdge = nextEdge;
        isCurrentValid = true;
        isNextValid = false;
        return currentNode;
    }

    public void remove() {
        if (!isCurrentValid) {
            throw new IllegalStateException();
        }
        if (!isNextValid) {
            delegate.remove();
        } else {
            if (graph == null) {
                throw new IllegalStateException("The remove() method cannot be called after hasNext()"
                        + " without an intervening call to next().");
            }
            graph.removeNode(currentNode);
        }
        isCurrentValid = false;
    }

    public Graph.Edge getEdge() {
        if (!isCurrentValid) {
            throw new IllegalStateException();
        }
        return currentEdge;
    }

    public void removeEdge() {
        if (!isCurrentValid) {
            throw new IllegalStateException();
        }
        if (!isNextValid) {
            delegate.removeEdge();
        } else {
            if (graph == null) {
                throw new IllegalStateException("The removeEdge() method cannot be called after hasNext()"
                        + " without an intervening call to next().");
            }
            graph.removeEdge(currentEdge);
        }
        isCurrentValid = false;
    }

}