    001    /*
    002     * Copyright (c) 2007-2014 Concurrent, 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
    021    package cascading.tuple;
    022
    023    import java.io.Closeable;
    024    import java.io.IOException;
    025    import 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     */
    032    public 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      }