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; 024import java.util.Scanner; 025 026import org.apache.camel.CamelContext; 027import org.apache.camel.Exchange; 028 029/** 030 * Group based {@link Iterator} which groups the given {@link Iterator} a number of times 031 * and then return a combined response as a <tt>List</tt>. 032 * <p/> 033 * This implementation uses a internal array list, to combine the response. 034 * 035 * @see GroupTokenIterator 036 */ 037public final class GroupIterator implements Iterator<Object>, Closeable { 038 039 private final CamelContext camelContext; 040 private final Exchange exchange; 041 private final Iterator<?> it; 042 private final int group; 043 private final boolean skipFirst; 044 private boolean closed; 045 046 /** 047 * Creates a new group iterator 048 * 049 * @param exchange the exchange used to create this group iterator 050 * @param it the iterator to group 051 * @param group number of parts to group together 052 * @throws IllegalArgumentException is thrown if group is not a positive number 053 */ 054 public GroupIterator(Exchange exchange, Iterator<?> it, int group) { 055 this(exchange, it, group, false); 056 } 057 058 /** 059 * Creates a new group iterator 060 * 061 * @param exchange the exchange used to create this group iterator 062 * @param it the iterator to group 063 * @param group number of parts to group together 064 * @throws IllegalArgumentException is thrown if group is not a positive number 065 */ 066 public GroupIterator(Exchange exchange, Iterator<?> it, int group, boolean skipFirst) { 067 this.exchange = exchange; 068 this.camelContext = exchange.getContext(); 069 this.it = it; 070 this.group = group; 071 if (group <= 0) { 072 throw new IllegalArgumentException("Group must be a positive number, was: " + group); 073 } 074 this.skipFirst = skipFirst; 075 } 076 077 @Override 078 public void close() throws IOException { 079 try { 080 if (it instanceof Scanner) { 081 // special for Scanner which implement the Closeable since JDK7 082 Scanner scanner = (Scanner) it; 083 scanner.close(); 084 IOException ioException = scanner.ioException(); 085 if (ioException != null) { 086 throw ioException; 087 } 088 } else if (it instanceof Closeable) { 089 IOHelper.closeWithException((Closeable) it); 090 } 091 } finally { 092 // we are now closed 093 closed = true; 094 } 095 } 096 097 @Override 098 public boolean hasNext() { 099 if (closed) { 100 return false; 101 } 102 103 boolean answer = it.hasNext(); 104 if (!answer) { 105 // auto close 106 try { 107 close(); 108 } catch (IOException e) { 109 // ignore 110 } 111 } 112 return answer; 113 } 114 115 @Override 116 public Object next() { 117 try { 118 return doNext(); 119 } catch (Exception e) { 120 throw ObjectHelper.wrapRuntimeCamelException(e); 121 } 122 } 123 124 private Object doNext() throws IOException { 125 List<Object> list = new ArrayList<Object>(); 126 int count = 0; 127 while (count < group && it.hasNext()) { 128 Object data = it.next(); 129 list.add(data); 130 count++; 131 } 132 133 return list; 134 } 135 136 @Override 137 public void remove() { 138 it.remove(); 139 } 140}