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.primitive.datetime;
28  
29  import com.rapiddweller.benerator.Generator;
30  import com.rapiddweller.benerator.GeneratorContext;
31  import com.rapiddweller.benerator.distribution.Distribution;
32  import com.rapiddweller.benerator.distribution.SequenceManager;
33  import com.rapiddweller.benerator.util.ThreadSafeNonNullGenerator;
34  import com.rapiddweller.benerator.util.WrapperProvider;
35  import com.rapiddweller.benerator.wrapper.ProductWrapper;
36  import com.rapiddweller.common.BeanUtil;
37  import com.rapiddweller.common.ConfigurationError;
38  import com.rapiddweller.common.TimeUtil;
39  import com.rapiddweller.model.data.Uniqueness;
40  
41  import java.util.Calendar;
42  import java.util.Date;
43  
44  /**
45   * Generates dates with a granularity of days, months or years.<br/><br/>
46   * Created: 12.10.2010 20:57:18
47   *
48   * @author Volker Bergmann
49   * @since 0.6.4
50   */
51  public class DayGenerator extends ThreadSafeNonNullGenerator<Date> {
52  
53    /**
54     * The Min.
55     */
56    protected Date min;
57    /**
58     * The Max.
59     */
60    protected Date max;
61    /**
62     * The Distribution.
63     */
64    protected Distribution distribution;
65    /**
66     * The Unique.
67     */
68    protected boolean unique;
69  
70    /**
71     * The Year granularity.
72     */
73    protected int yearGranularity;
74    /**
75     * The Month granularity.
76     */
77    protected int monthGranularity;
78    /**
79     * The Day granularity.
80     */
81    protected int dayGranularity;
82  
83    private Calendar minCalendar;
84    private Generator<Integer> multiplierGenerator;
85    private final WrapperProvider<Integer> intWrapper = new WrapperProvider<>();
86  
87    /**
88     * Instantiates a new Day generator.
89     */
90    public DayGenerator() {
91      this(TimeUtil.date(TimeUtil.currentYear() - 5, 0, 1),
92          TimeUtil.today(),
93          SequenceManager.RANDOM_SEQUENCE,
94          false);
95    }
96  
97    /**
98     * Instantiates a new Day generator.
99     *
100    * @param min          the min
101    * @param max          the max
102    * @param distribution the distribution
103    * @param unique       the unique
104    */
105   public DayGenerator(Date min, Date max, Distribution distribution, boolean unique) {
106     this.min = min;
107     this.max = max;
108     this.distribution = distribution;
109     this.unique = unique;
110     this.yearGranularity = 0;
111     this.monthGranularity = 0;
112     this.dayGranularity = 1;
113   }
114 
115   /**
116    * Sets min.
117    *
118    * @param min the min
119    */
120   public void setMin(Date min) {
121     this.min = min;
122   }
123 
124   /**
125    * Sets max.
126    *
127    * @param max the max
128    */
129   public void setMax(Date max) {
130     this.max = max;
131   }
132 
133   /**
134    * Sets granularity.
135    *
136    * @param granularitySpec the granularity spec
137    */
138   public void setGranularity(String granularitySpec) {
139     String[] tokens = granularitySpec.split("-");
140     if (tokens.length != 3) {
141       throw new ConfigurationError("Illegal date granularity spec: " + granularitySpec);
142     }
143     this.yearGranularity = Integer.parseInt(tokens[0]);
144     this.monthGranularity = Integer.parseInt(tokens[1]);
145     this.dayGranularity = Integer.parseInt(tokens[2]);
146   }
147 
148   /**
149    * Sets distribution.
150    *
151    * @param distribution the distribution
152    */
153   public void setDistribution(Distribution distribution) {
154     this.distribution = distribution;
155   }
156 
157   /**
158    * Sets unique.
159    *
160    * @param unique the unique
161    */
162   public void setUnique(boolean unique) {
163     this.unique = unique;
164   }
165 
166   @Override
167   public Class<Date> getGeneratedType() {
168     return Date.class;
169   }
170 
171   @Override
172   public synchronized void init(GeneratorContext context) {
173     this.minCalendar = TimeUtil.calendar(min);
174     int count = 0;
175     Calendar calendar = (Calendar) minCalendar.clone();
176     do {
177       calendar.add(Calendar.YEAR, yearGranularity);
178       calendar.add(Calendar.MONTH, monthGranularity);
179       calendar.add(Calendar.DAY_OF_MONTH, dayGranularity);
180       count++;
181     } while (!max.before(calendar.getTime()));
182     multiplierGenerator = context.getGeneratorFactory().createNumberGenerator(
183         Integer.class, 0, true, count - 1, true, 1, distribution, (unique ? Uniqueness.SIMPLE : Uniqueness.NONE));
184     multiplierGenerator.init(context);
185     super.init(context);
186   }
187 
188   @Override
189   public Date generate() {
190     assertInitialized();
191     ProductWrapper<Integer> multiplierWrapper = multiplierGenerator.generate(intWrapper.get());
192     if (multiplierWrapper == null) {
193       return null;
194     }
195     int multiplier = multiplierWrapper.unwrap();
196     Calendar calendar = (Calendar) minCalendar.clone();
197     calendar.add(Calendar.YEAR, multiplier * yearGranularity);
198     calendar.add(Calendar.MONTH, multiplier * monthGranularity);
199     calendar.add(Calendar.DAY_OF_MONTH, multiplier * dayGranularity);
200     return calendar.getTime();
201   }
202 
203   @Override
204   public void reset() {
205     multiplierGenerator.reset();
206     super.reset();
207   }
208 
209   @Override
210   public void close() {
211     multiplierGenerator.close();
212     super.close();
213   }
214 
215   @Override
216   public String toString() {
217     return BeanUtil.toString(this);
218   }
219 
220 }