1 19 20 package org.openide.util; 21 22 import java.io.IOException ; 23 import java.io.InputStream ; 24 import java.lang.ref.Reference ; 25 import java.lang.ref.WeakReference ; 26 import java.net.URL ; 27 import java.util.ArrayList ; 28 import java.util.Collections ; 29 import java.util.Enumeration ; 30 import java.util.HashMap ; 31 import java.util.Iterator ; 32 import java.util.LinkedList ; 33 import java.util.List ; 34 import java.util.Locale ; 35 import java.util.Map ; 36 import java.util.MissingResourceException ; 37 import java.util.NoSuchElementException ; 38 import java.util.Properties ; 39 import java.util.ResourceBundle ; 40 import java.util.WeakHashMap ; 41 import java.util.jar.Attributes ; 42 import java.util.logging.Level ; 43 import java.util.logging.Logger ; 44 45 58 public class NbBundle extends Object { 59 60 private static final boolean USE_DEBUG_LOADER = Boolean.getBoolean("org.openide.util.NbBundle.DEBUG"); private static String brandingToken = null; 62 63 68 static final Map <ClassLoader ,Map <String ,URL >> localizedFileCache = new WeakHashMap <ClassLoader ,Map <String ,URL >>(); 69 70 73 static final Map <ClassLoader ,Map <String ,Reference <ResourceBundle >>> bundleCache = new WeakHashMap <ClassLoader ,Map <String ,Reference <ResourceBundle >>>(); 74 75 80 @Deprecated 81 public NbBundle() { 82 } 83 84 87 public static String getBranding() { 88 return brandingToken; 89 } 90 91 102 public static void setBranding(String bt) throws IllegalArgumentException { 103 if (bt != null && !bt.matches("[a-z][a-z0-9]*(_[a-z][a-z0-9]*)*")) { throw new IllegalArgumentException ("Malformed branding token: " + bt); } 106 brandingToken = bt; 107 } 108 109 123 @Deprecated 124 public static synchronized URL getLocalizedFile(String baseName, String ext) 125 throws MissingResourceException { 126 return getLocalizedFile(baseName, ext, Locale.getDefault(), getLoader()); 127 } 128 129 140 @Deprecated 141 public static synchronized URL getLocalizedFile(String baseName, String ext, Locale locale) 142 throws MissingResourceException { 143 return getLocalizedFile(baseName, ext, locale, getLoader()); 144 } 145 146 158 @Deprecated 159 public static synchronized URL getLocalizedFile(String baseName, String ext, Locale locale, ClassLoader loader) 160 throws MissingResourceException { 161 URL lookup = null; 164 Iterator <String > it = new LocaleIterator(locale); 165 List <String > cacheCandidates = new ArrayList <String >(10); 166 String baseNameSlashes = baseName.replace('.', '/'); 167 Map <String ,URL > perLoaderCache = localizedFileCache.get(loader); 168 169 if (perLoaderCache == null) { 170 localizedFileCache.put(loader, perLoaderCache = new HashMap <String ,URL >()); 171 } 172 173 URL baseVariant; 176 String path; 177 178 if (ext != null) { 179 path = baseNameSlashes + '.' + ext; 180 } else { 181 path = baseNameSlashes; 182 } 183 184 lookup = perLoaderCache.get(path); 185 186 if (lookup == null) { 187 baseVariant = loader.getResource(path); 188 } else { 189 baseVariant = null; 191 } 192 193 while (it.hasNext()) { 194 String suffix = it.next(); 195 196 if (ext != null) { 197 path = baseNameSlashes + suffix + '.' + ext; 198 } else { 199 path = baseNameSlashes + suffix; 200 } 201 202 lookup = perLoaderCache.get(path); 203 204 if (lookup != null) { 205 break; 206 } 207 208 cacheCandidates.add(path); 209 210 if (suffix.length() == 0) { 211 lookup = baseVariant; 212 } else { 213 lookup = loader.getResource(path); 214 } 215 216 if (lookup != null) { 217 break; 218 } 219 } 220 221 if (lookup == null) { 222 path = baseName.replace('.', '/'); 223 224 if (ext != null) { 225 path += ('.' + ext); 226 } 227 228 throw new MissingResourceException ( 229 "Cannot find localized resource " + path + " in " + loader, loader.toString(), path 230 ); } else { 232 it = cacheCandidates.iterator(); 239 240 while (it.hasNext()) { 241 perLoaderCache.put(it.next(), lookup); 242 } 243 244 return lookup; 245 } 246 } 247 248 267 public static <T> T getLocalizedValue(Map <String ,T> table, String key, Locale locale) { 268 for (String suffix : NbCollections.iterable(new LocaleIterator(locale))) { 269 String physicalKey = key + suffix; 270 T v = table.get(physicalKey); 271 272 if (v != null) { 273 if (USE_DEBUG_LOADER && (v instanceof String )) { 275 @SuppressWarnings ("unchecked") 277 T _v = (T) (((String ) v) + " (?:" + physicalKey + ")"); return _v; 279 } else { 280 return v; 281 } 282 } 283 } 284 285 return null; 286 } 287 288 296 public static <T> T getLocalizedValue(Map <String ,T> table, String key) { 297 return getLocalizedValue(table, key, Locale.getDefault()); 298 } 299 300 307 public static String getLocalizedValue(Attributes attr, Attributes.Name key, Locale locale) { 308 return getLocalizedValue(attr2Map(attr), key.toString().toLowerCase(Locale.US), locale); 309 } 310 311 317 public static String getLocalizedValue(Attributes attr, Attributes.Name key) { 318 return getLocalizedValue(attr2Map(attr), key.toString().toLowerCase(Locale.US)); 321 } 322 323 328 private static Map <String ,String > attr2Map(Attributes attr) { 329 return new AttributesMap(attr); 330 } 331 332 334 347 public static final ResourceBundle getBundle(String baseName) 348 throws MissingResourceException { 349 return getBundle(baseName, Locale.getDefault(), getLoader()); 350 } 351 352 360 public static ResourceBundle getBundle(Class clazz) 361 throws MissingResourceException { 362 String name = findName(clazz); 363 364 return getBundle(name, Locale.getDefault(), clazz.getClassLoader()); 365 } 366 367 368 private static String findName(Class clazz) { 369 String pref = clazz.getName(); 370 int last = pref.lastIndexOf('.'); 371 372 if (last >= 0) { 373 pref = pref.substring(0, last + 1); 374 375 return pref + "Bundle"; } else { 377 return "Bundle"; } 380 } 381 382 389 public static final ResourceBundle getBundle(String baseName, Locale locale) 390 throws MissingResourceException { 391 return getBundle(baseName, locale, getLoader()); 392 } 393 394 401 public static final ResourceBundle getBundle(String baseName, Locale locale, ClassLoader loader) 402 throws MissingResourceException { 403 if (USE_DEBUG_LOADER) { 404 loader = DebugLoader.get(loader); 405 } 406 407 ResourceBundle b = getBundleFast(baseName, locale, loader); 412 413 if (b != null) { 414 return b; 415 } else { 416 MissingResourceException e = new MissingResourceException ("No such bundle " + baseName, baseName, null); 418 if (Lookup.getDefault().lookup(ClassLoader .class) == null) { 419 Exceptions.attachMessage(e, 420 "Class loader not yet initialized in lookup"); } else { 422 Exceptions.attachMessage(e, "Offending classloader: " + loader); } 424 425 throw e; 426 } 427 } 428 429 439 private static ResourceBundle getBundleFast(String name, Locale locale, ClassLoader loader) { 440 Map <String ,Reference <ResourceBundle >> m; 441 442 synchronized (bundleCache) { 443 m = bundleCache.get(loader); 444 445 if (m == null) { 446 bundleCache.put(loader, m = new HashMap <String ,Reference <ResourceBundle >>()); 447 } 448 } 449 450 String localeStr = locale.toString(); 454 char[] k = new char[name.length() + ((brandingToken != null) ? brandingToken.length() : 1) + 2 + 455 localeStr.length()]; 456 name.getChars(0, name.length(), k, 0); 457 k[name.length()] = '/'; 459 int pos = name.length() + 1; 460 461 if (brandingToken == null) { 462 k[pos] = '-'; pos++; 464 } else { 465 brandingToken.getChars(0, brandingToken.length(), k, pos); 466 pos += brandingToken.length(); 467 } 468 469 k[pos] = '/'; pos++; 471 localeStr.getChars(0, localeStr.length(), k, pos); 472 473 String key = new String (k); 474 475 478 synchronized (m) { 479 Reference <ResourceBundle > o = m.get(key); 480 ResourceBundle b = o != null ? o.get() : null; 481 482 if (b != null) { 483 return b; 484 } else { 485 b = loadBundle(name, locale, loader); 486 487 if (b != null) { 488 m.put(key, new TimedSoftReference<ResourceBundle >(b, m, key)); 489 } else { 490 } 493 494 return b; 495 } 496 } 497 } 498 499 506 private static ResourceBundle loadBundle(String name, Locale locale, ClassLoader loader) { 507 String sname = name.replace('.', '/'); 508 Iterator <String > it = new LocaleIterator(locale); 509 LinkedList <String > l = new LinkedList <String >(); 510 511 while (it.hasNext()) { 512 l.addFirst(it.next()); 513 } 514 515 Properties p = new Properties (); 516 517 for (String suffix : l) { 518 String res = sname + suffix + ".properties"; 519 520 URL u = loader != null ? loader.getResource(res) : ClassLoader.getSystemResource(res); 522 523 if (u != null) { 524 try { 526 InputStream is = USE_DEBUG_LOADER ? 528 (loader != null ? loader.getResourceAsStream(res) : ClassLoader.getSystemResourceAsStream(res)) : 529 u.openStream(); 530 531 try { 532 p.load(is); 533 } finally { 534 is.close(); 535 } 536 } catch (IOException e) { 537 Exceptions.attachMessage(e, "While loading: " + res); Logger.getLogger(NbBundle.class.getName()).log(Level.WARNING, null, e); 539 540 return null; 541 } 542 } else if (suffix.length() == 0) { 543 return loadBundleClass(name, sname, locale, l, loader); 546 } 547 } 548 549 return new PBundle(NbCollections.checkedMapByFilter(p, String .class, String .class, true), locale); 550 } 551 552 561 private static ResourceBundle loadBundleClass( 562 String name, String sname, Locale locale, List <String > suffixes, ClassLoader l 563 ) { 564 if (l != null && l.getResource(sname + ".class") == null) { 566 return null; 568 } 569 570 ResourceBundle master = null; 571 572 for (String suffix : suffixes) { 573 try { 574 Class <? extends ResourceBundle > c = Class.forName(name + suffix, true, l).asSubclass(ResourceBundle .class); 575 ResourceBundle b = c.newInstance(); 576 577 if (master == null) { 578 master = b; 579 } else { 580 master = new MergedBundle(locale, b, master); 581 } 582 } catch (ClassNotFoundException cnfe) { 583 } catch (Exception e) { 585 Logger.getLogger(NbBundle.class.getName()).log(Level.WARNING, null, e); 586 } catch (LinkageError e) { 587 Logger.getLogger(NbBundle.class.getName()).log(Level.WARNING, null, e); 588 } 589 } 590 591 return master; 592 } 593 594 598 605 public static String getMessage(Class clazz, String resName) 606 throws MissingResourceException { 607 return getBundle(clazz).getString(resName); 608 } 609 610 621 public static String getMessage(Class clazz, String resName, Object param1) 622 throws MissingResourceException { 623 return getMessage(clazz, resName, new Object [] { param1 }); 624 } 625 626 638 public static String getMessage(Class clazz, String resName, Object param1, Object param2) 639 throws MissingResourceException { 640 return getMessage(clazz, resName, new Object [] { param1, param2 }); 641 } 642 643 656 public static String getMessage(Class clazz, String resName, Object param1, Object param2, Object param3) 657 throws MissingResourceException { 658 return getMessage(clazz, resName, new Object [] { param1, param2, param3 }); 659 } 660 661 672 public static String getMessage(Class clazz, String resName, Object [] arr) 673 throws MissingResourceException { 674 return java.text.MessageFormat.format(getMessage(clazz, resName), arr); 675 } 676 677 681 private static ClassLoader getLoader() { 682 ClassLoader c = Lookup.getDefault().lookup(ClassLoader .class); 683 684 return (c != null) ? c : ClassLoader.getSystemClassLoader(); 685 } 686 687 702 public static Iterator <String > getLocalizingSuffixes() { 703 return new LocaleIterator(Locale.getDefault()); 704 } 705 706 711 @Deprecated 712 public static void setClassLoaderFinder(ClassLoaderFinder loaderFinder) { 713 throw new Error (); 714 } 715 716 720 @Deprecated 721 public static interface ClassLoaderFinder { 722 727 @Deprecated 728 public ClassLoader find(); 729 } 730 731 private static class AttributesMap extends HashMap <String ,String > { 732 private Attributes attrs; 733 734 public AttributesMap(Attributes attrs) { 735 super(7); 736 this.attrs = attrs; 737 } 738 739 public String get(Object _k) { 740 if (!(_k instanceof String )) { 741 return null; 742 } 743 String k = (String ) _k; 744 745 Attributes.Name an; 746 747 try { 748 an = new Attributes.Name (k); 749 } catch (IllegalArgumentException iae) { 750 Exceptions.attachLocalizedMessage(iae, 752 getMessage(NbBundle.class, "EXC_bad_attributes_name", k, Locale.getDefault().toString()) 753 ); 754 Exceptions.printStackTrace(iae); 755 756 return null; 757 } 758 759 return attrs.getValue(an); 760 } 761 } 762 763 766 private static final class PBundle extends ResourceBundle { 767 private final Map <String ,String > m; 768 private final Locale locale; 769 770 775 public PBundle(Map <String ,String > m, Locale locale) { 776 this.m = m; 777 this.locale = locale; 778 } 779 780 public Enumeration <String > getKeys() { 781 return Collections.enumeration(m.keySet()); 782 } 783 784 protected Object handleGetObject(String key) { 785 return m.get(key); 786 } 787 788 public Locale getLocale() { 789 return locale; 790 } 791 } 792 793 796 private static class MergedBundle extends ResourceBundle { 797 private Locale loc; 798 private ResourceBundle sub1; 799 private ResourceBundle sub2; 800 801 807 public MergedBundle(Locale loc, ResourceBundle sub1, ResourceBundle sub2) { 808 this.loc = loc; 809 this.sub1 = sub1; 810 this.sub2 = sub2; 811 } 812 813 public Locale getLocale() { 814 return loc; 815 } 816 817 public Enumeration <String > getKeys() { 818 return Enumerations.removeDuplicates(Enumerations.concat(sub1.getKeys(), sub2.getKeys())); 819 } 820 821 protected Object handleGetObject(String key) throws MissingResourceException { 822 try { 823 return sub1.getObject(key); 824 } catch (MissingResourceException mre) { 825 return sub2.getObject(key); 827 } 828 } 829 } 830 831 851 private static class LocaleIterator extends Object implements Iterator <String > { 852 853 private boolean defaultInProgress = false; 854 855 856 private boolean empty = false; 857 858 859 private Locale locale; 860 861 862 private Locale initLocale; 863 864 865 private String current; 866 867 868 private String branding; 869 870 873 public LocaleIterator(Locale locale) { 874 this.locale = this.initLocale = locale; 875 876 if (locale.equals(Locale.getDefault())) { 877 defaultInProgress = true; 878 } 879 880 current = '_' + locale.toString(); 881 882 if (brandingToken == null) { 883 branding = null; 884 } else { 885 branding = "_" + brandingToken; } 887 888 } 890 891 894 public String next() throws NoSuchElementException { 895 if (current == null) { 896 throw new NoSuchElementException (); 897 } 898 899 final String ret; 900 901 if (branding == null) { 902 ret = current; 903 } else { 904 ret = branding + current; 905 } 906 907 int lastUnderbar = current.lastIndexOf('_'); 908 909 if (lastUnderbar == 0) { 910 if (empty) { 911 reset(); 912 } else { 913 current = ""; empty = true; 915 } 916 } else { 917 if (lastUnderbar == -1) { 918 if (defaultInProgress) { 919 reset(); 920 } else { 921 locale = Locale.getDefault(); 924 current = '_' + locale.toString(); 925 defaultInProgress = true; 926 } 927 } else { 928 current = current.substring(0, lastUnderbar); 929 } 930 } 931 932 return ret; 934 } 935 936 940 private void reset() { 941 if (branding != null) { 942 current = '_' + initLocale.toString(); 943 944 int idx = branding.lastIndexOf('_'); 945 946 if (idx == 0) { 947 branding = null; 948 } else { 949 branding = branding.substring(0, idx); 950 } 951 952 empty = false; 953 } else { 954 current = null; 955 } 956 } 957 958 959 public boolean hasNext() { 960 return (current != null); 961 } 962 963 public void remove() throws UnsupportedOperationException { 964 throw new UnsupportedOperationException (); 965 } 966 } 967 969 972 static final class DebugLoader extends ClassLoader { 973 974 private static int count = 0; 975 976 979 private static final Map <String ,Integer > knownIDs = new HashMap <String ,Integer >(); 980 981 982 private static final Map <ClassLoader ,Reference <ClassLoader >> existing = new WeakHashMap <ClassLoader ,Reference <ClassLoader >>(); 983 984 private DebugLoader(ClassLoader cl) { 985 super(cl); 986 987 } 989 990 private static int getID(String name) { 991 synchronized (knownIDs) { 992 Integer i = knownIDs.get(name); 993 994 if (i == null) { 995 i = ++count; 996 knownIDs.put(name, i); 997 System.err.println("NbBundle trace: #" + i + " = " + name); } 999 1000 return i; 1001 } 1002 } 1003 1004 public static ClassLoader get(ClassLoader normal) { 1005 synchronized (existing) { 1007 Reference <ClassLoader > r = existing.get(normal); 1008 1009 if (r != null) { 1010 ClassLoader dl = r.get(); 1011 1012 if (dl != null) { 1013 return dl; 1015 } else { 1016 } 1018 } else { 1019 } 1021 1022 ClassLoader dl = new DebugLoader(normal); 1023 existing.put(normal, new WeakReference <ClassLoader >(dl)); 1024 1025 return dl; 1026 } 1027 } 1028 1029 public InputStream getResourceAsStream(String name) { 1030 InputStream base = super.getResourceAsStream(name); 1031 1032 if (base == null) { 1033 return null; 1034 } 1035 1036 if (name.endsWith(".properties")) { 1038 int id = getID(name); 1039 1040 boolean loc = name.indexOf("Bundle") != -1; 1043 return new DebugInputStream(base, id, loc); 1044 } else { 1045 return base; 1046 } 1047 } 1048 1049 1051 1061 static final class DebugInputStream extends InputStream { 1062 1063 private static final int WAITING_FOR_KEY = 0; 1064 1065 1066 private static final int IN_COMMENT = 1; 1067 1068 1069 private static final int IN_KEY = 2; 1070 1071 1072 private static final int IN_KEY_BACKSLASH = 3; 1073 1074 1075 private static final int AFTER_KEY = 4; 1076 1077 1078 private static final int WAITING_FOR_VALUE = 5; 1079 1080 1081 private static final int IN_VALUE = 6; 1082 1083 1084 private static final int IN_VALUE_BACKSLASH = 7; 1085 private final InputStream base; 1086 private final int id; 1087 private final boolean localizable; 1088 1089 1090 private int line = 0; 1091 1092 1093 private int keyLine = 0; 1094 1095 1096 private int state = WAITING_FOR_KEY; 1097 1098 1099 private boolean twixtCrAndNl = false; 1100 1101 1102 private String toInsert = null; 1103 1104 1105 private boolean reverseLocalizable = false; 1106 1107 1108 private StringBuffer lastComment = null; 1109 1110 1120 public DebugInputStream(InputStream base, int id, boolean localizable) { 1121 this.base = base; 1122 this.id = id; 1123 this.localizable = localizable; 1124 } 1125 1126 public int read() throws IOException { 1127 if (toInsert != null) { 1128 char result = toInsert.charAt(0); 1129 1130 if (toInsert.length() > 1) { 1131 toInsert = toInsert.substring(1); 1132 } else { 1133 toInsert = null; 1134 } 1135 1136 return result; 1137 } 1138 1139 int next = base.read(); 1140 1141 if (next == '\n') { 1142 twixtCrAndNl = false; 1143 line++; 1144 } else if (next == '\r') { 1145 if (twixtCrAndNl) { 1146 line++; 1147 } else { 1148 twixtCrAndNl = true; 1149 } 1150 } else { 1151 twixtCrAndNl = false; 1152 } 1153 1154 switch (state) { 1155 case WAITING_FOR_KEY: 1156 1157 switch (next) { 1158 case '#': 1159 case '!': 1160 state = IN_COMMENT; 1161 lastComment = new StringBuffer (); 1162 lastComment.append((char) next); 1163 1164 return next; 1165 1166 case ' ': 1167 case '\t': 1168 case '\n': 1169 case '\r': 1170 case -1: 1171 return next; 1172 1173 case '\\': 1174 state = IN_KEY_BACKSLASH; 1175 1176 return next; 1177 1178 default: 1179 state = IN_KEY; 1180 keyLine = line + 1; 1181 1182 return next; 1183 } 1184 1185 case IN_COMMENT: 1186 1187 switch (next) { 1188 case '\n': 1189 case '\r': 1190 1191 String comment = lastComment.toString(); 1192 lastComment = null; 1193 1194 if (localizable && comment.equals("#NOI18N")) { reverseLocalizable = true; 1196 } else if (localizable && comment.equals("#PARTNOI18N")) { System.err.println( 1198 "NbBundle WARNING (" + id + ":" + line + 1199 "): #PARTNOI18N encountered, will not annotate I18N parts" 1200 ); reverseLocalizable = true; 1202 } else if (!localizable && comment.equals("#I18N")) { reverseLocalizable = true; 1204 } else if (!localizable && comment.equals("#PARTI18N")) { System.err.println( 1206 "NbBundle WARNING (" + id + ":" + line + 1207 "): #PARTI18N encountered, will not annotate I18N parts" 1208 ); reverseLocalizable = false; 1210 } else if ( 1211 (localizable && (comment.equals("#I18N") || comment.equals("#PARTI18N"))) || (!localizable && (comment.equals("#NOI18N") || comment.equals("#PARTNOI18N"))) 1213 ) { System.err.println( 1215 "NbBundle WARNING (" + id + ":" + line + "): incongruous comment " + comment + 1216 " found for bundle" 1217 ); reverseLocalizable = false; 1219 } 1220 1221 state = WAITING_FOR_KEY; 1222 1223 return next; 1224 1225 default: 1226 lastComment.append((char) next); 1227 1228 return next; 1229 } 1230 1231 case IN_KEY: 1232 1233 switch (next) { 1234 case '\\': 1235 state = IN_KEY_BACKSLASH; 1236 1237 return next; 1238 1239 case ' ': 1240 case '\t': 1241 state = AFTER_KEY; 1242 1243 return next; 1244 1245 case '=': 1246 case ':': 1247 state = WAITING_FOR_VALUE; 1248 1249 return next; 1250 1251 case '\r': 1252 case '\n': 1253 state = WAITING_FOR_KEY; 1254 1255 return next; 1256 1257 default: 1258 return next; 1259 } 1260 1261 case IN_KEY_BACKSLASH: 1262 state = IN_KEY; 1263 1264 return next; 1265 1266 case AFTER_KEY: 1267 1268 switch (next) { 1269 case '=': 1270 case ':': 1271 state = WAITING_FOR_VALUE; 1272 1273 return next; 1274 1275 case '\r': 1276 case '\n': 1277 state = WAITING_FOR_KEY; 1278 1279 return next; 1280 1281 default: 1282 return next; 1283 } 1284 1285 case WAITING_FOR_VALUE: 1286 1287 switch (next) { 1288 case '\r': 1289 case '\n': 1290 state = WAITING_FOR_KEY; 1291 1292 return next; 1293 1294 case ' ': 1295 case '\t': 1296 return next; 1297 1298 case '\\': 1299 state = IN_VALUE_BACKSLASH; 1300 1301 return next; 1302 1303 default: 1304 state = IN_VALUE; 1305 1306 return next; 1307 } 1308 1309 case IN_VALUE: 1310 1311 switch (next) { 1312 case '\\': 1313 1314 state = IN_VALUE_BACKSLASH; 1318 1319 return next; 1320 1321 case '\n': 1322 case '\r': 1323 case -1: 1324 1325 boolean revLoc = reverseLocalizable; 1327 reverseLocalizable = false; 1328 state = WAITING_FOR_KEY; 1329 1330 if (localizable ^ revLoc) { 1331 assert keyLine > 0; 1333 toInsert = "(" + id + ":" + keyLine + ")"; if (next != -1) { 1335 toInsert += new Character ((char) next); 1336 } 1337 keyLine = 0; 1338 1339 return ' '; 1341 } else { 1342 return next; 1344 } 1345 1346 default: 1347 return next; 1348 } 1349 1350 case IN_VALUE_BACKSLASH: 1351 state = IN_VALUE; 1352 1353 return next; 1354 1355 default: 1356 throw new IOException ("should never happen"); } 1358 } 1359 1360 } 1361 } 1362} 1363 | Popular Tags |