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