001/** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.camel.util; 018 019import java.io.Closeable; 020import java.io.IOException; 021import java.util.ArrayList; 022import java.util.Iterator; 023import java.util.List; 024 025import org.apache.camel.CamelContext; 026import org.apache.camel.Exchange; 027 028/** 029 * Group based {@link Iterator} which groups the given {@link Iterator} a number of times 030 * and then return a combined response as a <tt>List</tt>. 031 * <p/> 032 * This implementation uses a internal array list, to combine the response. 033 * 034 * @see GroupTokenIterator 035 */ 036public final class GroupIterator implements Iterator<Object>, Closeable { 037 038 private final CamelContext camelContext; 039 private final Exchange exchange; 040 private final Iterator<?> it; 041 private final int group; 042 private final boolean skipFirst; 043 private boolean closed; 044 045 /** 046 * Creates a new group iterator 047 * 048 * @param exchange the exchange used to create this group iterator 049 * @param it the iterator to group 050 * @param group number of parts to group together 051 * @throws IllegalArgumentException is thrown if group is not a positive number 052 */ 053 public GroupIterator(Exchange exchange, Iterator<?> it, int group) { 054 this(exchange, it, group, false); 055 } 056 057 /** 058 * Creates a new group iterator 059 * 060 * @param exchange the exchange used to create this group iterator 061 * @param it the iterator to group 062 * @param group number of parts to group together 063 * @throws IllegalArgumentException is thrown if group is not a positive number 064 */ 065 public GroupIterator(Exchange exchange, Iterator<?> it, int group, boolean skipFirst) { 066 this.exchange = exchange; 067 this.camelContext = exchange.getContext(); 068 this.it = it; 069 this.group = group; 070 if (group <= 0) { 071 throw new IllegalArgumentException("Group must be a positive number, was: " + group); 072 } 073 this.skipFirst = skipFirst; 074 } 075 076 @Override 077 public void close() throws IOException { 078 try { 079 IOHelper.closeIterator(it); 080 } finally { 081 // we are now closed 082 closed = true; 083 } 084 } 085 086 @Override 087 public boolean hasNext() { 088 if (closed) { 089 return false; 090 } 091 092 boolean answer = it.hasNext(); 093 if (!answer) { 094 // auto close 095 try { 096 close(); 097 } catch (IOException e) { 098 // ignore 099 } 100 } 101 return answer; 102 } 103 104 @Override 105 public Object next() { 106 try { 107 return doNext(); 108 } catch (Exception e) { 109 throw ObjectHelper.wrapRuntimeCamelException(e); 110 } 111 } 112 113 private Object doNext() throws IOException { 114 List<Object> list = new ArrayList<>(); 115 int count = 0; 116 while (count < group && it.hasNext()) { 117 Object data = it.next(); 118 list.add(data); 119 count++; 120 } 121 122 return list; 123 } 124 125 @Override 126 public void remove() { 127 it.remove(); 128 } 129}