1 7 package java.net; 8 9 import java.io.InputStream ; 10 import java.io.IOException ; 11 import java.security.AccessController ; 12 import java.security.PrivilegedAction ; 13 14 import sun.net.idn.StringPrep; 15 import sun.net.idn.Punycode; 16 import sun.text.normalizer.UCharacterIterator; 17 18 58 public final class IDN { 59 62 public static final int ALLOW_UNASSIGNED = 0x01; 63 64 67 public static final int USE_STD3_ASCII_RULES = 0x02; 68 69 70 94 public static String toASCII(String input, int flag) 95 { 96 int p = 0, q = 0; 97 StringBuffer out = new StringBuffer (); 98 99 while (p < input.length()) { 100 q = searchDots(input, p); 101 out.append(toASCIIInternal(input.substring(p, q), flag)); 102 p = q + 1; 103 if (p < input.length()) out.append('.'); 104 } 105 106 return out.toString(); 107 } 108 109 110 126 public static String toASCII(String input) { 127 return toASCII(input, 0); 128 } 129 130 131 149 public static String toUnicode(String input, int flag) { 150 int p = 0, q = 0; 151 StringBuffer out = new StringBuffer (); 152 153 while (p < input.length()) { 154 q = searchDots(input, p); 155 out.append(toUnicodeInternal(input.substring(p, q), flag)); 156 p = q + 1; 157 if (p < input.length()) out.append('.'); 158 } 159 160 return out.toString(); 161 } 162 163 164 178 public static String toUnicode(String input) { 179 return toUnicode(input, 0); 180 } 181 182 183 184 185 private static final String ACE_PREFIX = "xn--"; 187 private static final int ACE_PREFIX_LENGTH = ACE_PREFIX.length(); 188 189 private static final int MAX_LABEL_LENGTH = 63; 190 191 private static StringPrep namePrep = null; 193 194 static { 195 InputStream stream = null; 196 197 try { 198 final String IDN_PROFILE = "uidna.spp"; 199 if (System.getSecurityManager() != null) { 200 stream = AccessController.doPrivileged(new PrivilegedAction <InputStream >() { 201 public InputStream run() { 202 return StringPrep.class.getResourceAsStream(IDN_PROFILE); 203 } 204 }); 205 } else { 206 stream = StringPrep.class.getResourceAsStream(IDN_PROFILE); 207 } 208 209 namePrep = new StringPrep(stream); 210 stream.close(); 211 } catch (IOException e) { 212 assert false; 214 } 215 } 216 217 218 219 220 221 private IDN() {} 225 226 private static String toASCIIInternal(String label, int flag) 230 { 231 boolean isASCII = isAllASCII(label); 234 StringBuffer dest; 235 236 if (!isASCII) { 239 UCharacterIterator iter = UCharacterIterator.getInstance(label); 240 try { 241 dest = namePrep.prepare(iter, flag); 242 } catch (java.text.ParseException e) { 243 throw new IllegalArgumentException (e); 244 } 245 } else { 246 dest = new StringBuffer (label); 247 } 248 249 boolean useSTD3ASCIIRules = ((flag & USE_STD3_ASCII_RULES) != 0); 254 if (useSTD3ASCIIRules) { 255 for (int i = 0; i < dest.length(); i++) { 256 int c = dest.charAt(i); 257 if (!isLDHChar(c)) { 258 throw new IllegalArgumentException ("Contains non-LDH characters"); 259 } 260 } 261 262 if (dest.charAt(0) == '-' || dest.charAt(dest.length() - 1) == '-') { 263 throw new IllegalArgumentException ("Has leading or trailing hyphen"); 264 } 265 } 266 267 if (!isASCII) { 268 if (!isAllASCII(dest.toString())) { 271 if(!startsWithACEPrefix(dest)){ 274 275 try { 278 dest = Punycode.encode(dest, null); 279 } catch (java.text.ParseException e) { 280 throw new IllegalArgumentException (e); 281 } 282 283 dest = toASCIILower(dest); 284 285 dest.insert(0, ACE_PREFIX); 288 } else { 289 throw new IllegalArgumentException ("The input starts with the ACE Prefix"); 290 } 291 292 } 293 } 294 295 if(dest.length() > MAX_LABEL_LENGTH){ 298 throw new IllegalArgumentException ("The label in the input is too long"); 299 } 300 301 return dest.toString(); 302 } 303 304 private static String toUnicodeInternal(String label, int flag) { 308 boolean[] caseFlags = null; 309 StringBuffer dest; 310 311 boolean isASCII = isAllASCII(label); 314 315 if(!isASCII){ 316 try { 319 UCharacterIterator iter = UCharacterIterator.getInstance(label); 320 dest = namePrep.prepare(iter, flag); 321 } catch (Exception e) { 322 return label; 324 } 325 } else { 326 dest = new StringBuffer (label); 327 } 328 329 if(startsWithACEPrefix(dest)) { 332 333 String temp = dest.substring(ACE_PREFIX_LENGTH, dest.length()); 336 337 try { 338 StringBuffer decodeOut = Punycode.decode(new StringBuffer (temp), null); 341 342 String toASCIIOut = toASCII(decodeOut.toString(), flag); 345 346 if (toASCIIOut.equalsIgnoreCase(dest.toString())) { 349 return decodeOut.toString(); 352 } 353 } catch (Exception ignored) { 354 } 356 } 357 358 return label; 360 } 361 362 363 private static boolean isLDHChar(int ch){ 370 if(ch > 0x007A){ 372 return false; 373 } 374 if((ch == 0x002D) || 376 (0x0030 <= ch && ch <= 0x0039) || 377 (0x0041 <= ch && ch <= 0x005A) || 378 (0x0061 <= ch && ch <= 0x007A) 379 ){ 380 return true; 381 } 382 return false; 383 } 384 385 386 private static int searchDots(String s, int start) { 393 int i; 394 for (i = start; i < s.length(); i++) { 395 char c = s.charAt(i); 396 if (c == '.' || c == '\u3002' || c == '\uFF0E' || c == '\uFF61') { 397 break; 398 } 399 } 400 401 return i; 402 } 403 404 405 private static boolean isAllASCII(String input) { 409 boolean isASCII = true; 410 for (int i = 0; i < input.length(); i++) { 411 int c = input.charAt(i); 412 if (c > 0x7F) { 413 isASCII = false; 414 break; 415 } 416 } 417 return isASCII; 418 } 419 420 private static boolean startsWithACEPrefix(StringBuffer input){ 424 boolean startsWithPrefix = true; 425 426 if(input.length() < ACE_PREFIX_LENGTH){ 427 return false; 428 } 429 for(int i = 0; i < ACE_PREFIX_LENGTH; i++){ 430 if(toASCIILower(input.charAt(i)) != ACE_PREFIX.charAt(i)){ 431 startsWithPrefix = false; 432 } 433 } 434 return startsWithPrefix; 435 } 436 437 private static char toASCIILower(char ch){ 438 if('A' <= ch && ch <= 'Z'){ 439 return (char)(ch + 'a' - 'A'); 440 } 441 return ch; 442 } 443 444 private static StringBuffer toASCIILower(StringBuffer input){ 445 StringBuffer dest = new StringBuffer (); 446 for(int i = 0; i < input.length();i++){ 447 dest.append(toASCIILower(input.charAt(i))); 448 } 449 return dest; 450 } 451 } 452 | Popular Tags |