1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.commons.geometry.core.internal;
18
19 import java.util.Collection;
20 import java.util.Deque;
21 import java.util.Iterator;
22 import java.util.LinkedList;
23 import java.util.NoSuchElementException;
24
25 /** Class that wraps another iterator, converting each input iterator value into
26 * one or more output iterator values.
27 * @param <I> Input iterator type
28 * @param <T> Output iterator type
29 */
30 public abstract class IteratorTransform<I, T> implements Iterator<T> {
31
32 /** Input iterator instance that supplies the input values for this instance. */
33 private final Iterator<I> inputIterator;
34
35 /** Output value queue. */
36 private final Deque<T> outputQueue = new LinkedList<>();
37
38 /** Create a new instance that uses the given iterator as the input source.
39 * @param inputIterator iterator supplying input values
40 */
41 protected IteratorTransform(final Iterator<I> inputIterator) {
42 this.inputIterator = inputIterator;
43 }
44
45 /** {@inheritDoc} */
46 @Override
47 public boolean hasNext() {
48 return loadNextOutput();
49 }
50
51 /** {@inheritDoc} */
52 @Override
53 public T next() {
54 if (outputQueue.isEmpty()) {
55 throw new NoSuchElementException();
56 }
57
58 return outputQueue.removeFirst();
59 }
60
61 /** Load the next output values into the output queue. Returns true if the output queue
62 * contains more entries.
63 * @return true if more output values are available
64 */
65 private boolean loadNextOutput() {
66 while (outputQueue.isEmpty() && inputIterator.hasNext()) {
67 acceptInput(inputIterator.next());
68 }
69
70 return !outputQueue.isEmpty();
71 }
72
73 /** Add a value to the output queue.
74 * @param value value to add to the output queue
75 */
76 protected void addOutput(final T value) {
77 outputQueue.add(value);
78 }
79
80 /** Add multiple values to the output queue.
81 * @param values values to add to the output queue
82 */
83 protected void addAllOutput(final Collection<T> values) {
84 outputQueue.addAll(values);
85 }
86
87 /** Accept a value from the input iterator. This method should take
88 * the input value and add one or more values to the output queue.
89 * @param input value from the input iterator
90 */
91 protected abstract void acceptInput(I input);
92 }