1 /*
2  **********************************************************************
3  * Copyright (c) 2002-2004, International Business Machines
4  * Corporation and others.  All Rights Reserved.
5  **********************************************************************
6  * Author: Mark Davis
7  **********************************************************************
8  */
9 package org.unicode.cldr.util.props;
10 
11 import java.util.ArrayList;
12 import java.util.List;
13 import java.util.Random;
14 
15 import com.ibm.icu.dev.util.UnicodeMap;
16 import com.ibm.icu.text.UTF16;
17 import com.ibm.icu.text.UnicodeSet;
18 
19 public class RandomStringGenerator {
20 
21     private static final UnicodeSet SUPPLEMENTARIES = new UnicodeSet(0x10000, 0x10FFFF);
22 
23     /**
24      * If not null, masks off the character properties so the UnicodeSets are easier to use when debugging.
25      */
26     public static UnicodeSet DEBUG_REDUCE_SET_SIZE = null; // new
27     // UnicodeSet("[\\u0000-\\u00FF\\u0300-\\u03FF\\u2000-\\u20FF]");
28     // // new UnicodeSet("[\\u0000-\\u00FF\\u2000-\\u20FF]"); //
29     // or null
30 
31 
32     private Random random = new Random(0);
33     private UnicodeSet[] sets;
34     private UnicodeMap map;
35     private UnicodeMap shortMap;
36     private UnicodeMap extendedMap;
37 
init(UnicodeProperty.Factory factory)38     void init(UnicodeProperty.Factory factory) {
39         extendedMap = new UnicodeMap();
40         UnicodeMap tempMap = factory.getProperty("GraphemeClusterBreak").getUnicodeMap();
41         extendedMap.putAll(tempMap.keySet("CR"), "CR");
42         extendedMap.putAll(tempMap.keySet("LF"), "LF");
43         extendedMap.putAll(tempMap.keySet("Extend"), "GCExtend");
44         extendedMap.putAll(tempMap.keySet("Control"), "GCControl");
45     }
46 
RandomStringGenerator(UnicodeProperty.Factory factory, String propertyName)47     public RandomStringGenerator(UnicodeProperty.Factory factory, String propertyName) {
48         this(factory, propertyName, false, false);
49     }
50 
RandomStringGenerator(UnicodeProperty.Factory factory, String propertyName, boolean useShortName, boolean addGCStuff)51     public RandomStringGenerator(UnicodeProperty.Factory factory, String propertyName, boolean useShortName,
52         boolean addGCStuff) {
53         this(factory, factory.getProperty(propertyName).getUnicodeMap(),
54             useShortName ? ICUPropertyFactory.make().getProperty(propertyName).getUnicodeMap(true) : null,
55                 addGCStuff);
56     }
57 
RandomStringGenerator(UnicodeProperty.Factory factory, UnicodeMap longNameMap, UnicodeMap shortNameMap, boolean addGCStuff)58     RandomStringGenerator(UnicodeProperty.Factory factory, UnicodeMap longNameMap, UnicodeMap shortNameMap,
59         boolean addGCStuff) {
60         init(factory);
61         map = !addGCStuff ? longNameMap
62             : longNameMap.composeWith(extendedMap, MyComposer);
63         shortMap = (shortNameMap == null ? longNameMap
64             : !addGCStuff ? shortNameMap
65                 : shortNameMap.composeWith(extendedMap, MyComposer));
66         List<String> values = new ArrayList<String>(map.getAvailableValues());
67         sets = new UnicodeSet[values.size()];
68         for (int i = 0; i < sets.length; ++i) {
69             sets[i] = map.keySet(values.get(i));
70             sets[i].removeAll(SUPPLEMENTARIES);
71             if (DEBUG_REDUCE_SET_SIZE != null) {
72                 int first = sets[i].charAt(0);
73                 sets[i].retainAll(DEBUG_REDUCE_SET_SIZE);
74                 if (sets[i].size() == 0) sets[i].add(first);
75             }
76         }
77     }
78 
79     static UnicodeMap.Composer MyComposer = new UnicodeMap.Composer() {
80         @Override
81         public Object compose(int codePoint, String string, Object a, Object b) {
82             if (a == null) return b;
83             if (b == null) return a;
84             return a + "_" + b;
85         }
86     };
87 
getValue(int cp)88     public String getValue(int cp) {
89         return (String) shortMap.getValue(cp);
90     }
91 
next(int len)92     public String next(int len) {
93         StringBuffer result = new StringBuffer();
94         for (int i = 0; i < len; ++i) {
95             UnicodeSet us = sets[random.nextInt(sets.length)];
96             int cp = us.charAt(random.nextInt(us.size()));
97             UTF16.append(result, cp);
98         }
99         return result.toString();
100     }
101 }