001 // Copyright 2007 The Apache Software Foundation 002 // 003 // Licensed under the Apache License, Version 2.0 (the "License"); 004 // you may not use this file except in compliance with the License. 005 // You may obtain a copy of the License at 006 // 007 // http://www.apache.org/licenses/LICENSE-2.0 008 // 009 // Unless required by applicable law or agreed to in writing, software 010 // distributed under the License is distributed on an "AS IS" BASIS, 011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012 // See the License for the specific language governing permissions and 013 // limitations under the License. 014 015 package org.apache.tapestry5.test; 016 017 import java.io.*; 018 import static java.lang.String.format; 019 import java.util.ArrayList; 020 import java.util.List; 021 import java.util.Random; 022 023 /** 024 * Provides access to random data that can be used when populating a test database with "reasonable" data. The majority 025 * of this is access to random words from an american english dictionary, which can be strung together to form names, 026 * sentences and paragraphs. 027 */ 028 public final class RandomDataSource 029 { 030 private final Random random = new Random(System.currentTimeMillis()); 031 032 private final List<String> words = new ArrayList<String>(); 033 034 public RandomDataSource() 035 { 036 for (int i = 0; i < 4; i++) 037 readWords("english." + i); 038 039 for (int i = 0; i < 3; i++) 040 readWords("american." + i); 041 042 System.out.printf("Dictionary contains %d words\n", words.size()); 043 } 044 045 private void readWords(String name) 046 { 047 System.out.println("Reading " + name + " ..."); 048 049 int count = 0; 050 051 InputStream is = getClass().getResourceAsStream(name); 052 053 if (is == null) throw new RuntimeException(format("File '%s' not found.", name)); 054 055 try 056 { 057 BufferedInputStream bis = new BufferedInputStream(is); 058 InputStreamReader isr = new InputStreamReader(bis); 059 LineNumberReader r = new LineNumberReader(isr); 060 061 while (true) 062 { 063 String word = r.readLine(); 064 065 if (word == null) break; 066 067 count++; 068 words.add(word); 069 } 070 071 r.close(); 072 } 073 catch (IOException ex) 074 { 075 throw new RuntimeException(format("Error reading '%s': %s", name + ex.getMessage()), ex); 076 } 077 078 System.out.printf("... %d words\n", count); 079 } 080 081 public boolean maybe(int percent) 082 { 083 assert percent > 0 && percent <= 100; 084 085 return random.nextInt(100) < percent; 086 } 087 088 public int random(int min, int max) 089 { 090 assert min <= max; 091 092 return random.nextInt(max - min + 1) + min; 093 } 094 095 /** 096 * Returns a random word frm the dictionary. These words are usually all lowercase. 097 */ 098 public String word() 099 { 100 int index = random.nextInt(words.size()); 101 102 return words.get(index); 103 } 104 105 /** 106 * Returns a random word, capitalized. Useful when create random names. 107 */ 108 public String capitalizedWord() 109 { 110 String word = word(); 111 112 char[] chars = word.toCharArray(); 113 114 chars[0] = Character.toUpperCase(chars[0]); 115 116 return new String(chars); 117 } 118 119 /** 120 * Returns a word that is "safe" for use in an email address. 121 */ 122 public String safeWord() 123 { 124 String word = word(); 125 126 int x = word.indexOf('\''); 127 128 return x < 0 ? word : word.substring(0, x); 129 } 130 131 /** 132 * Returns a random value from the list of values supplied. 133 */ 134 public <T> T oneOf(T... values) 135 { 136 assert values.length > 0; 137 138 int index = random.nextInt(values.length); 139 140 return values[index]; 141 } 142 143 /** 144 * Returns a random enum value, given the enum type. 145 */ 146 public <T extends Enum> T oneOf(Class<T> enumClass) 147 { 148 return oneOf(enumClass.getEnumConstants()); 149 } 150 151 /** 152 * Creates a space-separated list of random words. If in sentence form, then the first word is capitalized, and a 153 * period is appended. 154 * 155 * @param minWords minimun number of words in the list 156 * @param maxWords maximum number of words in the list 157 * @param asSentence if true, the output is "dressed up" as a non-sensical sentence 158 * @return the word list / sentence 159 */ 160 public String wordList(int minWords, int maxWords, boolean asSentence) 161 { 162 assert minWords <= maxWords; 163 assert minWords > 0; 164 165 StringBuilder builder = new StringBuilder(); 166 167 int count = random(minWords, maxWords); 168 169 for (int i = 0; i < count; i++) 170 { 171 172 if (i > 0) builder.append(' '); 173 174 if (i == 0 && asSentence) 175 builder.append(capitalizedWord()); 176 else 177 builder.append(word()); 178 } 179 180 if (asSentence) builder.append('.'); 181 182 return builder.toString(); 183 } 184 185 /** 186 * Strings together a random number of word lists (in sentence form) to create something that looks like a 187 * paragraph. 188 * 189 * @param minSentences per paragraph 190 * @param maxSentences per paragraph 191 * @param minWords per sentence 192 * @param maxWords per sentence 193 * @return the random paragraph 194 */ 195 public String paragraph(int minSentences, int maxSentences, int minWords, int maxWords) 196 { 197 assert minSentences < maxSentences; 198 assert minSentences > 0; 199 200 int count = random(minSentences, maxSentences); 201 202 StringBuilder builder = new StringBuilder(); 203 204 for (int i = 0; i < count; i++) 205 { 206 if (i > 0) builder.append(' '); 207 208 builder.append(wordList(minWords, maxWords, true)); 209 } 210 211 return builder.toString(); 212 } 213 }