1 /* GENERATED SOURCE. DO NOT MODIFY. */ 2 // 2016 and later: Unicode, Inc. and others. 3 // License & terms of use: http://www.unicode.org/copyright.html#License 4 /* 5 ******************************************************************************* 6 * Copyright (C) 2003-2010, International Business Machines Corporation and * 7 * others. All Rights Reserved. * 8 ******************************************************************************* 9 */ 10 package android.icu.dev.test.stringprep; 11 12 13 import java.lang.reflect.InvocationTargetException; 14 import java.lang.reflect.Method; 15 16 import android.icu.impl.ICUResourceBundle; 17 import android.icu.lang.UCharacter; 18 import android.icu.lang.UCharacterDirection; 19 import android.icu.text.StringPrepParseException; 20 import android.icu.text.UCharacterIterator; 21 import android.icu.text.UnicodeSet; 22 import android.icu.testsharding.MainTestShard; 23 24 /** 25 * @author ram 26 * 27 * To change the template for this generated type comment go to 28 * Window>Preferences>Java>Code Generation>Code and Comments 29 */ 30 @MainTestShard 31 public class NamePrepTransform { 32 33 private static final NamePrepTransform transform = new NamePrepTransform(); 34 35 private UnicodeSet labelSeparatorSet; 36 private UnicodeSet prohibitedSet; 37 private UnicodeSet unassignedSet; 38 private MapTransform mapTransform; 39 public static final int NONE = 0; 40 public static final int ALLOW_UNASSIGNED = 1; 41 42 private NamePrepTransform(){ 43 // load the resource bundle 44 ICUResourceBundle bundle = (ICUResourceBundle)ICUResourceBundle.getBundleInstance("android/icu/dev/data/testdata","idna_rules", NamePrepTransform.class.getClassLoader(), true); 45 String mapRules = bundle.getString("MapNoNormalization"); 46 mapRules += bundle.getString("MapNFKC"); 47 // disable 48 mapTransform = new MapTransform("CaseMap", mapRules, 0 /*Transliterator.FORWARD*/); 49 labelSeparatorSet = new UnicodeSet(bundle.getString("LabelSeparatorSet")); 50 prohibitedSet = new UnicodeSet(bundle.getString("ProhibitedSet")); 51 unassignedSet = new UnicodeSet(bundle.getString("UnassignedSet")); 52 } 53 54 public static final NamePrepTransform getInstance(){ 55 return transform; 56 } 57 public static boolean isLabelSeparator(int ch){ 58 return transform.labelSeparatorSet.contains(ch); 59 } 60 61 /* 62 1) Map -- For each character in the input, check if it has a mapping 63 and, if so, replace it with its mapping. 64 65 2) Normalize -- Possibly normalize the result of step 1 using Unicode 66 normalization. 67 68 3) Prohibit -- Check for any characters that are not allowed in the 69 output. If any are found, return an error. 70 71 4) Check bidi -- Possibly check for right-to-left characters, and if 72 any are found, make sure that the whole string satisfies the 73 requirements for bidirectional strings. If the string does not 74 satisfy the requirements for bidirectional strings, return an 75 error. 76 [Unicode3.2] defines several bidirectional categories; each character 77 has one bidirectional category assigned to it. For the purposes of 78 the requirements below, an "RandALCat character" is a character that 79 has Unicode bidirectional categories "R" or "AL"; an "LCat character" 80 is a character that has Unicode bidirectional category "L". Note 81 82 83 that there are many characters which fall in neither of the above 84 definitions; Latin digits (<U+0030> through <U+0039>) are examples of 85 this because they have bidirectional category "EN". 86 87 In any profile that specifies bidirectional character handling, all 88 three of the following requirements MUST be met: 89 90 1) The characters in section 5.8 MUST be prohibited. 91 92 2) If a string contains any RandALCat character, the string MUST NOT 93 contain any LCat character. 94 95 3) If a string contains any RandALCat character, a RandALCat 96 character MUST be the first character of the string, and a 97 RandALCat character MUST be the last character of the string. 98 */ 99 100 public boolean isReady() { 101 return mapTransform.isReady(); 102 } 103 104 public StringBuffer prepare(UCharacterIterator src, 105 int options) 106 throws StringPrepParseException{ 107 return prepare(src.getText(),options); 108 } 109 110 private String map ( String src, int options) 111 throws StringPrepParseException{ 112 // map 113 boolean allowUnassigned = ((options & ALLOW_UNASSIGNED)>0); 114 // disable test 115 String caseMapOut = mapTransform.transliterate(src); 116 UCharacterIterator iter = UCharacterIterator.getInstance(caseMapOut); 117 int ch; 118 while((ch=iter.nextCodePoint())!=UCharacterIterator.DONE){ 119 if(transform.unassignedSet.contains(ch)==true && allowUnassigned ==false){ 120 throw new StringPrepParseException("An unassigned code point was found in the input", 121 StringPrepParseException.UNASSIGNED_ERROR); 122 } 123 } 124 return caseMapOut; 125 } 126 public StringBuffer prepare(String src,int options) 127 throws StringPrepParseException{ 128 129 int ch; 130 String mapOut = map(src,options); 131 UCharacterIterator iter = UCharacterIterator.getInstance(mapOut); 132 133 int direction=UCharacterDirection.CHAR_DIRECTION_COUNT, 134 firstCharDir=UCharacterDirection.CHAR_DIRECTION_COUNT; 135 int rtlPos=-1, ltrPos=-1; 136 boolean rightToLeft=false, leftToRight=false; 137 138 while((ch=iter.nextCodePoint())!= UCharacterIterator.DONE){ 139 140 141 if(transform.prohibitedSet.contains(ch)==true && ch!=0x0020){ 142 throw new StringPrepParseException("A prohibited code point was found in the input", 143 StringPrepParseException.PROHIBITED_ERROR, 144 iter.getText(),iter.getIndex()); 145 } 146 147 direction = UCharacter.getDirection(ch); 148 if(firstCharDir == UCharacterDirection.CHAR_DIRECTION_COUNT){ 149 firstCharDir = direction; 150 } 151 if(direction == UCharacterDirection.LEFT_TO_RIGHT){ 152 leftToRight = true; 153 ltrPos = iter.getIndex()-1; 154 } 155 if(direction == UCharacterDirection.RIGHT_TO_LEFT || direction == UCharacterDirection.RIGHT_TO_LEFT_ARABIC){ 156 rightToLeft = true; 157 rtlPos = iter.getIndex()-1; 158 } 159 } 160 161 // satisfy 2 162 if( leftToRight == true && rightToLeft == true){ 163 throw new StringPrepParseException("The input does not conform to the rules for BiDi code points.", 164 StringPrepParseException.CHECK_BIDI_ERROR,iter.getText(),(rtlPos>ltrPos) ? rtlPos : ltrPos); 165 } 166 167 //satisfy 3 168 if( rightToLeft == true && 169 !((firstCharDir == UCharacterDirection.RIGHT_TO_LEFT || firstCharDir == UCharacterDirection.RIGHT_TO_LEFT_ARABIC) && 170 (direction == UCharacterDirection.RIGHT_TO_LEFT || direction == UCharacterDirection.RIGHT_TO_LEFT_ARABIC)) 171 ){ 172 throw new StringPrepParseException("The input does not conform to the rules for BiDi code points.", 173 StringPrepParseException.CHECK_BIDI_ERROR,iter.getText(),(rtlPos>ltrPos) ? rtlPos : ltrPos); 174 } 175 176 return new StringBuffer(mapOut); 177 178 } 179 180 private static class MapTransform { 181 private Object translitInstance; 182 private Method translitMethod; 183 private boolean isReady; 184 185 MapTransform(String id, String rule, int direction) { 186 isReady = initialize(id, rule, direction); 187 } 188 189 boolean initialize(String id, String rule, int direction) { 190 try { 191 Class cls = Class.forName("android.icu.text.Transliterator"); 192 Method createMethod = cls.getMethod("createFromRules", String.class, String.class, Integer.TYPE); 193 translitInstance = createMethod.invoke(null, id, rule, Integer.valueOf(direction)); 194 translitMethod = cls.getMethod("transliterate", String.class); 195 } catch (Throwable e) { 196 return false; 197 } 198 return true; 199 } 200 201 boolean isReady() { 202 return isReady; 203 } 204 205 String transliterate(String text) { 206 if (!isReady) { 207 throw new IllegalStateException("Transliterator is not ready"); 208 } 209 String result = null; 210 try { 211 result = (String)translitMethod.invoke(translitInstance, text); 212 } catch (InvocationTargetException ite) { 213 throw new RuntimeException(ite); 214 } catch (IllegalAccessException iae) { 215 throw new RuntimeException(iae); 216 } 217 return result; 218 } 219 } 220 } 221