001 /* 002 * Copyright (c) 2007-2015 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 TupleEntryChainIterator extends TupleEntryIterator 033 { 034 /** Field iterator */ 035 Iterator<Tuple>[] iterators; 036 int currentIterator = 0; 037 038 public TupleEntryChainIterator( Fields fields, Iterator<Tuple>... iterators ) 039 { 040 super( fields ); 041 this.iterators = iterators; 042 } 043 044 /** 045 * Method hasNext returns true if there is a next TupleEntry 046 * 047 * @return boolean 048 */ 049 public boolean hasNext() 050 { 051 if( iterators.length < currentIterator + 1 ) // past the end 052 return false; 053 054 if( iterators[ currentIterator ].hasNext() ) 055 return true; 056 057 closeCurrent(); 058 059 currentIterator++; 060 061 return iterators.length != currentIterator && hasNext(); 062 } 063 064 public void reset( Iterator<Tuple>... iterators ) 065 { 066 this.currentIterator = 0; 067 this.iterators = iterators; 068 } 069 070 /** 071 * Method next returns the next TupleEntry. 072 * 073 * @return TupleEntry 074 */ 075 public TupleEntry next() 076 { 077 hasNext(); // force roll to next iterator 078 079 entry.setTuple( iterators[ currentIterator ].next() ); 080 081 return entry; 082 } 083 084 /** Method remove removes the current TupleEntry from the underlying collection. */ 085 public void remove() 086 { 087 iterators[ currentIterator ].remove(); 088 } 089 090 /** Method close closes all underlying resources. */ 091 public void close() 092 { 093 if( iterators.length != currentIterator ) 094 closeCurrent(); 095 } 096 097 protected void closeCurrent() 098 { 099 close( iterators[ currentIterator ] ); 100 } 101 102 private void close( Iterator iterator ) 103 { 104 if( iterator instanceof Closeable ) 105 { 106 try 107 { 108 ( (Closeable) iterator ).close(); 109 } 110 catch( IOException exception ) 111 { 112 // ignore 113 } 114 } 115 } 116 }