View Javadoc

1   /* Version 1.0 based on Apache Software License 1.1
2    *
3    * Copyright (c) 2003 Piotr Maj and DBMonster developers. All rights
4    * reserved.
5    *
6    * Redistribution and use in source and binary forms, with or without
7    * modification, are permitted provided that the following conditions are
8    * met:
9    *
10   * 1. Redistributions of source code must retain the above copyright
11   *    notice, this list of conditions and the following disclaimer.
12   *
13   * 2. Redistributions in binary form must reproduce the above copyright
14   *    notice, this list of conditions and the following disclaimer in the
15   *    documentation and/or other materials provided with the distribution.
16   *
17   * 3. The end-user documentation included with the redistribution, if any,
18   *    must include the following acknowledgment:
19   *
20   *    "This product includes software developed by DBMonster developers
21   *    (http://dbmonster.kernelpanic.pl/)."
22   *
23   *  Alternately, this acknowledgment may appear in the software itself,
24   *  if and wherever such third-party acknowledgments normally appear.
25   *
26   * 4. The name "DBMonster" must not be used to endorse or promote products
27   *    derived from this software without prior written permission. For
28   *    written permission, please contact piotr.maj@kernelpanic.pl.
29   *
30   * 5. Products derived from this software may not be called "DBMonster",
31   *    nor may "DBMonster" appear in their name, without prior written
32   *    permission of Piotr Maj.
33   *
34   * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
35   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
36   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
37   * IN NO EVENT SHALL THE DBMONSTER DEVELOPERS BE LIABLE FOR ANY DIRECT,
38   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
39   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
40   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
42   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
43   * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
44   * POSSIBILITY OF SUCH DAMAGE.
45   */
46  
47  package pl.kernelpanic.dbmonster.generator;
48  
49  import java.net.URL;
50  import java.util.HashMap;
51  import java.util.Iterator;
52  import java.util.Map;
53  import java.util.Random;
54  
55  import pl.kernelpanic.dbmonster.DBMonster;
56  import pl.kernelpanic.dbmonster.DBMonsterContext;
57  import pl.kernelpanic.dbmonster.Dictionary;
58  import pl.kernelpanic.dbmonster.DictionaryManager;
59  
60  /***
61   * String generator. Recognizes the following properties:
62   *
63   * <table border="1">
64   *   <tr>
65   *     <td>minLength</td>
66   *     <td>minimal length of generated string (default: 0)</td>
67   *   </tr>
68   *   <tr>
69   *     <td>maxLength</td>
70   *     <td>maximum length of generated string (default: 255)</td>
71   *   </tr>
72   *   <tr>
73   *     <td>allowSpaces</td>
74   *     <td>should this column contain spaces? (default: <code>true</code>)</td>
75   *   </tr>
76   *   <tr>
77   *     <td>excludeChars</td>
78   *     <td>characters that should not appear in generated string
79   *         (no default value)</td>
80   *   </tr>
81   *   <tr>
82   *     <td>nulls</td>
83   *     <td>How many nulls on average should this generator produce
84   *         per every 100 rows (default: <code>0</code>)</td>
85   *   </tr>
86   * </table>
87   *
88   * @author Piotr Maj &lt;piotr.maj@kernelpanic.pl&gt;
89   *
90   * @version $Id: StringGenerator.html,v 1.1 2007/06/21 08:38:13 sbahloul Exp $
91   */
92  public class StringGenerator extends BasicDataGenerator implements Initializable {
93  
94      /***
95       * Dictionary file.
96       */
97      private String dict = "/pl/kernelpanic/dbmonster/resources/dictionary.gz"; //$NON-NLS-1$
98  
99      /***
100      * Minimal length.
101      */
102     private int minLength = 0;
103 
104     /***
105      * Maximal length.
106      */
107     private int maxLength = 255;
108 
109     /***
110      * Should the spaces be allowed?
111      */
112     private boolean allowSpaces = true;
113 
114     /***
115      * Don't include these characters in generated string.
116      */
117     private Map excludeChars = new HashMap();
118 
119     /***
120      * Words dictionary.
121      */
122     private Dictionary dictionary = null;
123 
124     /***
125      * Random number generator.
126      */
127     private Random random = null;
128 
129     /***
130      * DBMonster context.
131      */
132     private DBMonsterContext context = null;
133 
134     /***
135      * Initializes the generator.
136      *
137      * @param ctx context
138      *
139      * @throws Exception of errors
140      */
141     public final void initialize(final DBMonsterContext ctx) throws Exception {
142         if (minLength > maxLength) {
143             throw new Exception("minLength > maxLength is string generator!"); //$NON-NLS-1$
144         }
145         context = ctx;
146         random = (Random) context.getProperty(DBMonster.RANDOM_KEY);
147         DictionaryManager dm =
148             (DictionaryManager) context.getProperty(
149                 DBMonster.DICTIONARY_MANAGER_KEY);
150         URL url = getClass().getResource(dict);
151         dictionary = dm.getDictionary(url);
152     }
153 
154     /***
155      * Generates random string.
156      *
157      * @return <code>null</code>.
158      */
159     public final Object generate() {
160 
161         if (nulls != 0 && random.nextInt(101) <= nulls) {
162             return null;
163         }
164 
165         StringBuffer buff = new StringBuffer();
166         int k = 0;
167         int length = random.nextInt(maxLength - minLength + 1);
168         length += minLength;
169 
170         String s = null;
171         while (k < length) {
172             s = (String) dictionary.getNextRandomItem();
173             s = filter(s);
174             buff.append(s);
175             k += s.length();
176 
177             if (allowSpaces) {
178                 buff.append(" "); //$NON-NLS-1$
179                 ++k;
180             }
181         }
182 
183         buff.setLength(length);
184 
185         return buff.toString();
186     }
187 
188     /***
189      * Returns the minimal length of the string.
190      *
191      * @return the minimal length of generated string
192      */
193     public final int getMinLength() {
194         return minLength;
195     }
196 
197     /***
198      * Sets the minimal length of the string.
199      *
200      * @param length minimal length
201      */
202     public final void setMinLength(final int length) {
203         minLength = length;
204     }
205 
206      /***
207      * Returns the maximal length of the string.
208      *
209      * @return the maximal value of generated string
210      */
211     public final int getMaxLength() {
212         return maxLength;
213     }
214 
215     /***
216      * Sets the maximal length of the string.
217      *
218      * @param length maximal length
219      */
220     public final void setMaxLength(final int length) {
221         maxLength = length;
222     }
223 
224     /***
225      * Return allowSpaces parameter.
226      *
227      * @return <code>true</code> if generated string
228      *         can contain spaces.
229      */
230     public final boolean getAllowSpaces() {
231         return allowSpaces;
232     }
233 
234     /***
235      * Sets the allowSpaces parameter.
236      *
237      * @param spaces <code>true</code> or <code>false</code>
238      */
239     public final void setAllowSpaces(final boolean spaces) {
240         allowSpaces = spaces;
241     }
242 
243     /***
244      * Returns an exclude chars.
245      *
246      * @return characters that should not be included in generated string.
247      */
248     public final String getExcludeChars() {
249         Iterator it = excludeChars.keySet().iterator();
250         StringBuffer buff = new StringBuffer();
251         while (it.hasNext()) {
252             buff.append(it.next());
253         }
254         return buff.toString();
255     }
256 
257     /***
258      * Sets the excluded characters.
259      *
260      * @param chars the characters to exclude
261      */
262     public final void setExcludeChars(final String chars) {
263         excludeChars.clear();
264         if (chars == null) {
265             return;
266         }
267         for (int i = 0; i < chars.length(); i++) {
268             char c = chars.charAt(i);
269             excludeChars.put(new Character(c), null);
270         }
271     }
272 
273     /***
274      * Resets the generator.
275      */
276     public final void reset() {
277     }
278 
279     /***
280      * Removes unwanted chars and trims the string.
281      *
282      * @param str String to filter
283      *
284      * @return filtered string
285      */
286     private String filter(final String str) {
287         if (str == null) {
288             return null;
289         }
290         StringBuffer buff = new StringBuffer();
291         for (int i = 0; i < str.length(); i++) {
292             char c = str.charAt(i);
293             if (Character.isWhitespace(c)) {
294                 if (allowSpaces) {
295                     buff.append(c);
296                 }
297             } else if (!excludeChars.containsKey(new Character(c))) {
298                 buff.append(c);
299             }
300         }
301         return buff.toString();
302     }
303 }