    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  }