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