001    package echopoint.util;
002    /* 
003     * This file is part of the Echo Point Project.  This project is a collection
004     * of Components that have extended the Echo Web Application Framework.
005     *
006     * Version: MPL 1.1/GPL 2.0/LGPL 2.1
007     *
008     * The contents of this file are subject to the Mozilla Public License Version
009     * 1.1 (the "License"); you may not use this file except in compliance with
010     * the License. You may obtain a copy of the License at
011     * http://www.mozilla.org/MPL/
012     *
013     * Software distributed under the License is distributed on an "AS IS" basis,
014     * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
015     * for the specific language governing rights and limitations under the
016     * License.
017     *
018     * Alternatively, the contents of this file may be used under the terms of
019     * either the GNU General Public License Version 2 or later (the "GPL"), or
020     * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
021     * in which case the provisions of the GPL or the LGPL are applicable instead
022     * of those above. If you wish to allow use of your version of this file only
023     * under the terms of either the GPL or the LGPL, and not to allow others to
024     * use your version of this file under the terms of the MPL, indicate your
025     * decision by deleting the provisions above and replace them with the notice
026     * and other provisions required by the GPL or the LGPL. If you do not delete
027     * the provisions above, a recipient may use your version of this file under
028     * the terms of any one of the MPL, the GPL or the LGPL.
029     */
030    
031    /**
032     * A utility class to help with Random number generation.
033     *
034     * @author Brad Baker 
035     */
036    
037    import java.util.Calendar;
038    import java.util.Random;
039    
040    public class RandKit {
041    
042            /** not instantiable */
043            private RandKit() {
044            }
045    
046            private static Random rn = new Random();
047    
048            /**
049             * get random numbers in a range, lo <= number <= hi
050             */
051            public static double rand(double lo, double hi) {
052    
053                    if (lo > hi) {
054                            double save = lo;
055                            lo = hi;
056                            hi = save;
057                    }
058                    double range = hi - lo + 1;
059    
060                    // compute a fraction of the range, 0 <= frac < range
061                    double frac = (range * rn.nextDouble());
062    
063                    // add the fraction to the lo value and return the sum
064                    return (frac + lo);
065            }
066            /**
067             * get random numbers in a range, lo <= number <= hi
068             */
069            public static int rand(int lo, int hi) {
070                    return (int) rand((long) lo, (long) hi);
071            }
072            /**
073             * get random numbers in a range, lo <= number <= hi
074             */
075            public static long rand(long lo, long hi) {
076    
077                    if (lo > hi) {
078                            long save = lo;
079                            lo = hi;
080                            hi = save;
081                    }
082                    long range = hi - lo + 1;
083    
084                    // compute a fraction of the range, 0 <= frac < range
085                    long frac = (long) (range * rn.nextDouble());
086    
087                    // add the fraction to the lo value and return the sum
088                    return (frac + lo);
089            }
090            /**
091             * Returns a new Calendar object which is between start and end
092             */
093            public static Calendar rand(Calendar start, Calendar end) {
094                    if (start.after(end)) {
095                            Calendar temp = start;
096                            start = end;
097                            end = temp;
098                    }
099                    long diff = end.getTime().getTime() - start.getTime().getTime();
100                    long daysDiff = diff / (1000 * 60 * 60 * 24);
101    
102                    int delta = rand(0, (int) daysDiff);
103    
104                    Calendar newCal = Calendar.getInstance();
105                    newCal.setTime(start.getTime());
106                    newCal.setTimeZone(start.getTimeZone());
107    
108                    newCal.add(Calendar.DAY_OF_MONTH, delta);
109                    newCal.add(Calendar.HOUR, rand(0, 23));
110                    newCal.add(Calendar.MINUTE, rand(0, 59));
111                    newCal.add(Calendar.SECOND, rand(0, 59));
112    
113                    // check range cause we might random picked value
114                    // greater than the range.
115                    if (newCal.after(end)) {
116                            newCal.setTime(end.getTime());
117                            newCal.setTimeZone(end.getTimeZone());
118                    }
119                    if (newCal.before(start)) {
120                            newCal.setTime(start.getTime());
121                            newCal.setTimeZone(start.getTimeZone());
122                    }
123    
124                    return newCal;
125            }
126            /**
127             * Returns a random char from the array of chars
128             */
129            public static char roll(char[] chars) {
130                    int index = rand(0, chars.length - 1);
131                    return chars[index];
132            }
133            /**
134             * Returns a random double from the array of doubles
135             */
136            public static double roll(double[] doubles) {
137                    int index = rand(0, doubles.length - 1);
138                    return doubles[index];
139            }
140            /**
141             * Returns a random float from the array of floats
142             */
143            public static float roll(float[] floats) {
144                    int index = rand(0, floats.length - 1);
145                    return floats[index];
146            }
147            /**
148             * Returns a random int from the array of ints
149             */
150            public static int roll(int[] ints) {
151                    int index = rand(0, ints.length - 1);
152                    return ints[index];
153            }
154            /**
155             * Returns a random long from the array of longs
156             */
157            public static long roll(long[] longs) {
158                    int index = rand(0, longs.length - 1);
159                    return longs[index];
160            }
161            /**
162             * Returns a random object from the array of objects
163             */
164            public static Object roll(Object[] arr) {
165                    int index = rand(0, arr.length - 1);
166                    return arr[index];
167            }
168            /**
169             * Returns a random String from the array of Strings
170             */
171            public static String roll(String[] arrStrings) {
172                    int index = rand(0, arrStrings.length - 1);
173                    return arrStrings[index];
174            }
175            /**
176             * Returns a random boolean from the array of booleans
177             */
178            public static boolean roll(boolean[] booleans) {
179                    int index = rand(0, booleans.length - 1);
180                    return booleans[index];
181            }
182            /**
183             * Returns true "chance" percent of the time.  Of course chance should
184             * be an integer between 0 and 100.
185             */
186            public static boolean roll(int percentageChance) {
187                    int val = rand(0, 100);
188                    if (percentageChance > 100)
189                            percentageChance = 100;
190                    if (percentageChance < 0)
191                            percentageChance = 0;
192    
193                    return val >= percentageChance;
194            }
195            /**
196             * Returns a random Object from the List of Objects
197             */
198            public static Object roll(java.util.List list) {
199                    int index = rand(0, list.size()-1);
200                    return list.get(index);
201            }
202            /**
203             * Returns true of false 50 percent of the time
204             */
205            public static boolean roll5050() {
206                    return (rand(0, 100001) > (100001 / 2));
207            }
208    
209            /**
210             * This method will return a random sample of the
211             * possibles array into the destination array, without
212             * repeating any options.
213             * 
214             * By providing a destination array, then the eact type of the
215             * returned array can be controlled.
216             * 
217             * @param possibles - an array of possible choices
218             * @param destination - the destination array for random choices
219             * @return - the destination array itself
220             */
221            public static Object[] rand(Object[] possibles, Object[] destination) {
222                    if (possibles == null || destination == null) {
223                            return destination;
224                    }
225                    int maxTimes = Math.min(possibles.length,destination.length);
226                    int index = 0;
227                    int count = 0;
228                    while (true) {
229                            count++;
230                            if (index >= maxTimes) {
231                                    break;
232                            }
233                            Object choice = roll(possibles);
234                            boolean found = false;
235                            for (int j = 0; j < destination.length; j++) {
236                                    if (choice == destination[j]) {
237                                            found = true;
238                                            break;
239                                    }
240                            }
241                            if (! found) {
242                                    destination[index] = choice;
243                                    index++;
244                            }
245                            if (count > maxTimes * 100) {
246                                    break;
247                            }
248                    }
249                    return destination;
250            }
251    }