001/*
002 * Copyright (c) 2007-2017 Xplenty, Inc. All Rights Reserved.
003 *
004 * Project and contact information: http://www.cascading.org/
005 *
006 * This file is part of the Cascading project.
007 *
008 * Licensed under the Apache License, Version 2.0 (the "License");
009 * you may not use this file except in compliance with the License.
010 * You may obtain a copy of the License at
011 *
012 *     http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing, software
015 * distributed under the License is distributed on an "AS IS" BASIS,
016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017 * See the License for the specific language governing permissions and
018 * limitations under the License.
019 */
020
021package cascading.tuple;
022
023import java.io.Closeable;
024import java.io.IOException;
025import java.util.Iterator;
026
027/**
028 * TupleEntryChainIterator chains the given Iterators into a single Iterator.
029 * <p/>
030 * As one iterator is completed, it will be closed and a new one will start.
031 */
032public class TupleEntryIterableChainIterator extends TupleEntryIterator
033  {
034  Iterator<Iterator<Tuple>> iterators;
035  Iterator<Tuple> currentIterator = null;
036
037  public TupleEntryIterableChainIterator( Fields fields )
038    {
039    super( fields );
040    }
041
042  public TupleEntryIterableChainIterator( Fields fields, Iterable<Iterator<Tuple>> iterable )
043    {
044    super( fields );
045    this.iterators = iterable.iterator();
046    }
047
048  /**
049   * Method hasNext returns true if there is a next TupleEntry
050   *
051   * @return boolean
052   */
053  public boolean hasNext()
054    {
055    if( currentIterator == null && !iterators.hasNext() )
056      return false;
057
058    if( currentIterator != null && currentIterator.hasNext() )
059      return true;
060
061    closeCurrent();
062
063    currentIterator = null;
064
065    if( iterators.hasNext() )
066      currentIterator = iterators.next();
067
068    return hasNext();
069    }
070
071  public void reset( Iterable<Iterator<Tuple>> iterable )
072    {
073    this.currentIterator = null;
074    this.iterators = iterable.iterator();
075    }
076
077  /**
078   * Method next returns the next TupleEntry.
079   *
080   * @return TupleEntry
081   */
082  public TupleEntry next()
083    {
084    hasNext(); // force roll to next iterator
085
086    entry.setTuple( currentIterator.next() );
087
088    return entry;
089    }
090
091  /** Method remove removes the current TupleEntry from the underlying collection. */
092  public void remove()
093    {
094    currentIterator.remove();
095    }
096
097  /** Method close closes all underlying resources. */
098  public void close()
099    {
100    if( currentIterator != null )
101      closeCurrent();
102    }
103
104  protected void closeCurrent()
105    {
106    close( currentIterator );
107    }
108
109  private void close( Iterator iterator )
110    {
111    if( iterator instanceof Closeable )
112      {
113      try
114        {
115        ( (Closeable) iterator ).close();
116        }
117      catch( IOException exception )
118        {
119        // ignore
120        }
121      }
122    }
123  }