View Javadoc
1   /*
2    * (c) Copyright 2006-2020 by rapiddweller GmbH & Volker Bergmann. All rights reserved.
3    *
4    * Redistribution and use in source and binary forms, with or without
5    * modification, is permitted under the terms of the
6    * GNU General Public License.
7    *
8    * For redistributing this software or a derivative work under a license other
9    * than the GPL-compatible Free Software License as defined by the Free
10   * Software Foundation or approved by OSI, you must first obtain a commercial
11   * license to this software product from rapiddweller GmbH & Volker Bergmann.
12   *
13   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
14   * WITHOUT A WARRANTY OF ANY KIND. ALL EXPRESS OR IMPLIED CONDITIONS,
15   * REPRESENTATIONS AND WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF
16   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE
17   * HEREBY EXCLUDED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24   * POSSIBILITY OF SUCH DAMAGE.
25   */
26  
27  package com.rapiddweller.benerator.wrapper;
28  
29  import com.rapiddweller.benerator.GeneratorContext;
30  import com.rapiddweller.benerator.IllegalGeneratorStateException;
31  import com.rapiddweller.benerator.InvalidGeneratorSetupException;
32  import com.rapiddweller.benerator.util.AbstractGenerator;
33  import com.rapiddweller.common.IOUtil;
34  import com.rapiddweller.common.TypedIterable;
35  
36  import java.io.Closeable;
37  import java.util.Iterator;
38  
39  /**
40   * Iterates over Iterators that are provided by an {@link Iterable}.<br/>
41   * <br/>
42   * Created: 16.08.2007 07:09:57
43   *
44   * @param <E> the type parameter
45   * @author Volker Bergmann
46   */
47  public class IteratingGenerator<E> extends AbstractGenerator<E> {
48  
49    private TypedIterable<E> iterable;
50    private Iterator<E> iterator;
51  
52    // constructors ----------------------------------------------------------------------------------------------------
53  
54    /**
55     * Instantiates a new Iterating generator.
56     */
57    public IteratingGenerator() {
58      this(null);
59    }
60  
61    /**
62     * Instantiates a new Iterating generator.
63     *
64     * @param iterable the iterable
65     */
66    public IteratingGenerator(TypedIterable<E> iterable) {
67      this.iterable = iterable;
68      this.iterator = null;
69    }
70  
71    // properties ------------------------------------------------------------------------------------------------------
72  
73    /**
74     * Gets iterable.
75     *
76     * @return the iterable
77     */
78    public TypedIterable<E> getIterable() {
79      return iterable;
80    }
81  
82    /**
83     * Sets iterable.
84     *
85     * @param iterable the iterable
86     */
87    public void setIterable(TypedIterable<E> iterable) {
88      if (this.iterable != null) {
89        throw new IllegalGeneratorStateException("Mutating an initialized generator");
90      }
91      this.iterable = iterable;
92    }
93  
94    // Generator interface ---------------------------------------------------------------------------------------------
95  
96    @Override
97    public boolean isParallelizable() {
98      return false;
99    }
100 
101   @Override
102   public boolean isThreadSafe() {
103     return false;
104   }
105 
106   @Override
107   public void init(GeneratorContext context) {
108     if (iterable == null) {
109       throw new InvalidGeneratorSetupException("iterable", "is null");
110     }
111     super.init(context);
112   }
113 
114   @Override
115   public Class<E> getGeneratedType() {
116     return iterable.getType();
117   }
118 
119   @Override
120   public ProductWrapper<E> generate(ProductWrapper<E> wrapper) {
121     try {
122       assertInitialized();
123       if (iterator != null && !iterator.hasNext()) {
124         return null;
125       }
126       if (iterator == null) {
127         // iterator is created lazily for avoiding script evaluation errors in init()
128         createIterator();
129       }
130       if (!iterator.hasNext()) {
131         closeIterator();
132         return null;
133       }
134       E result = iterator.next();
135       if (!iterator.hasNext()) {
136         closeIterator();
137       }
138       return wrapper.wrap(result);
139     } catch (Exception e) {
140       throw new IllegalGeneratorStateException("Generation failed: ", e);
141     }
142   }
143 
144   @Override
145   public void reset() {
146     closeIterator();
147     super.reset();
148     createIterator();
149   }
150 
151   @Override
152   public void close() {
153     closeIterator();
154     super.close();
155     if (iterable instanceof Closeable) {
156       IOUtil.close((Closeable) iterable);
157     }
158   }
159 
160   // private helpers -------------------------------------------------------------------------------------------------
161 
162   private void createIterator() {
163     iterator = iterable.iterator();
164   }
165 
166   private void closeIterator() {
167     if (iterator != null) {
168       if (iterator instanceof Closeable) {
169         IOUtil.close((Closeable) iterator);
170       }
171     }
172   }
173 
174   // java.lang.Object overrides --------------------------------------------------------------------------------------
175 
176   @Override
177   public String toString() {
178     return getClass().getSimpleName() + "[" + iterable + ']';
179   }
180 
181 }