59
60 @Override
61 public InputSource resolveEntity(String publicID, String systemID) throws IOException, SAXException {
62 // avoid HTTP traffic to unicode.org
63 if (systemID.startsWith(CLDRConverter.LDML_DTD_SYSTEM_ID)) {
64 return new InputSource((new File(CLDRConverter.LOCAL_LDML_DTD)).toURI().toString());
65 }
66 return null;
67 }
68
69 @Override
70 public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
71 switch (qName) {
72 //
73 // Generic information
74 //
75 case "identity":
76 // ignore this element - it has language and territory elements that aren't locale data
77 pushIgnoredContainer(qName);
78 break;
79 case "type":
80 if ("calendar".equals(attributes.getValue("key"))) {
81 pushStringEntry(qName, attributes, CLDRConverter.CALENDAR_NAME_PREFIX + attributes.getValue("type"));
82 } else {
83 pushIgnoredContainer(qName);
84 }
85 break;
86
87 case "language":
88 case "script":
89 case "territory":
90 case "variant":
91 // for LocaleNames
92 // copy string
93 pushStringEntry(qName, attributes,
94 CLDRConverter.LOCALE_NAME_PREFIX +
95 (qName.equals("variant") ? "%%" : "") +
96 attributes.getValue("type"));
97 break;
98
99 //
100 // Currency information
101 //
102 case "currency":
103 // for CurrencyNames
104 // stash away "type" value for nested <symbol>
105 pushKeyContainer(qName, attributes, attributes.getValue("type"));
106 break;
107 case "symbol":
108 // for CurrencyNames
109 // need to get the key from the containing <currency> element
110 pushStringEntry(qName, attributes, CLDRConverter.CURRENCY_SYMBOL_PREFIX
111 + getContainerKey());
112 break;
113
114 // Calendar or currency
115 case "displayName":
116 {
117 if (currentContainer.getqName().equals("field")) {
118 pushStringEntry(qName, attributes,
498 break;
499 case "defaultNumberingSystem":
500 // default numbering system if multiple numbering systems are used.
501 pushStringEntry(qName, attributes, "DefaultNumberingSystem");
502 break;
503 case "symbols":
504 // for FormatData
505 // look up numberingSystems
506 symbols: {
507 String script = attributes.getValue("numberSystem");
508 if (script == null) {
509 // Has no script. Just ignore.
510 pushIgnoredContainer(qName);
511 break;
512 }
513
514 // Use keys as <script>."NumberElements/<symbol>"
515 currentNumberingSystem = script + ".";
516 String digits = CLDRConverter.handlerNumbering.get(script);
517 if (digits == null) {
518 throw new InternalError("null digits for " + script);
519 }
520 if (Character.isSurrogate(digits.charAt(0))) {
521 // DecimalFormatSymbols doesn't support supplementary characters as digit zero.
522 pushIgnoredContainer(qName);
523 break;
524 }
525 // in case digits are in the reversed order, reverse back the order.
526 if (digits.charAt(0) > digits.charAt(digits.length() - 1)) {
527 StringBuilder sb = new StringBuilder(digits);
528 digits = sb.reverse().toString();
529 }
530 // Check if the order is sequential.
531 char c0 = digits.charAt(0);
532 for (int i = 1; i < digits.length(); i++) {
533 if (digits.charAt(i) != c0 + i) {
534 pushIgnoredContainer(qName);
535 break symbols;
536 }
537 }
538 @SuppressWarnings("unchecked")
539 List<String> numberingScripts = (List<String>) get("numberingScripts");
540 if (numberingScripts == null) {
541 numberingScripts = new ArrayList<>();
542 put("numberingScripts", numberingScripts);
543 }
544 numberingScripts.add(script);
545 put(currentNumberingSystem + "NumberElements/zero", digits.substring(0, 1));
546 pushContainer(qName, attributes);
547 }
548 break;
549 case "decimal":
550 // for FormatData
551 // copy string for later assembly into NumberElements
552 if (currentContainer.getqName().equals("symbols")) {
553 pushStringEntry(qName, attributes, currentNumberingSystem + "NumberElements/decimal");
554 } else {
555 pushIgnoredContainer(qName);
556 }
557 break;
920 target = target.substring(0, target.indexOf('.'))+"."+tmp[0];
921 }
922 CLDRConverter.aliases.put(src.replaceFirst("^gregorian.", ""),
923 target.replaceFirst("^gregorian.", ""));
924 }
925 }
926 } else if (currentContainer instanceof Entry) {
927 Entry<?> entry = (Entry<?>) currentContainer;
928 Object value = entry.getValue();
929 if (value != null) {
930 String key = entry.getKey();
931 // Tweak for MonthNames for the root locale, Needed for
932 // SimpleDateFormat.format()/parse() roundtrip.
933 if (id.equals("root") && key.startsWith("MonthNames")) {
934 value = new DateFormatSymbols(Locale.US).getShortMonths();
935 }
936 put(entry.getKey(), value);
937 }
938 }
939 }
940 }
|
59
60 @Override
61 public InputSource resolveEntity(String publicID, String systemID) throws IOException, SAXException {
62 // avoid HTTP traffic to unicode.org
63 if (systemID.startsWith(CLDRConverter.LDML_DTD_SYSTEM_ID)) {
64 return new InputSource((new File(CLDRConverter.LOCAL_LDML_DTD)).toURI().toString());
65 }
66 return null;
67 }
68
69 @Override
70 public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
71 switch (qName) {
72 //
73 // Generic information
74 //
75 case "identity":
76 // ignore this element - it has language and territory elements that aren't locale data
77 pushIgnoredContainer(qName);
78 break;
79
80 // for LocaleNames
81 // copy string
82 case "localeSeparator":
83 pushStringEntry(qName, attributes,
84 CLDRConverter.LOCALE_SEPARATOR);
85 break;
86 case "localeKeyTypePattern":
87 pushStringEntry(qName, attributes,
88 CLDRConverter.LOCALE_KEYTYPE);
89 break;
90
91 case "language":
92 case "script":
93 case "territory":
94 case "variant":
95 // for LocaleNames
96 // copy string
97 pushStringEntry(qName, attributes,
98 CLDRConverter.LOCALE_NAME_PREFIX +
99 (qName.equals("variant") ? "%%" : "") +
100 attributes.getValue("type"));
101 break;
102
103 case "key":
104 // for LocaleNames
105 // copy string
106 pushStringEntry(qName, attributes,
107 CLDRConverter.LOCALE_KEY_PREFIX +
108 convertOldKeyName(attributes.getValue("type")));
109 break;
110
111 case "type":
112 // for LocaleNames/CalendarNames
113 // copy string
114 pushStringEntry(qName, attributes,
115 CLDRConverter.LOCALE_TYPE_PREFIX +
116 convertOldKeyName(attributes.getValue("key")) + "." +
117 attributes.getValue("type"));
118
119 break;
120
121 //
122 // Currency information
123 //
124 case "currency":
125 // for CurrencyNames
126 // stash away "type" value for nested <symbol>
127 pushKeyContainer(qName, attributes, attributes.getValue("type"));
128 break;
129 case "symbol":
130 // for CurrencyNames
131 // need to get the key from the containing <currency> element
132 pushStringEntry(qName, attributes, CLDRConverter.CURRENCY_SYMBOL_PREFIX
133 + getContainerKey());
134 break;
135
136 // Calendar or currency
137 case "displayName":
138 {
139 if (currentContainer.getqName().equals("field")) {
140 pushStringEntry(qName, attributes,
520 break;
521 case "defaultNumberingSystem":
522 // default numbering system if multiple numbering systems are used.
523 pushStringEntry(qName, attributes, "DefaultNumberingSystem");
524 break;
525 case "symbols":
526 // for FormatData
527 // look up numberingSystems
528 symbols: {
529 String script = attributes.getValue("numberSystem");
530 if (script == null) {
531 // Has no script. Just ignore.
532 pushIgnoredContainer(qName);
533 break;
534 }
535
536 // Use keys as <script>."NumberElements/<symbol>"
537 currentNumberingSystem = script + ".";
538 String digits = CLDRConverter.handlerNumbering.get(script);
539 if (digits == null) {
540 pushIgnoredContainer(qName);
541 break;
542 }
543
544 @SuppressWarnings("unchecked")
545 List<String> numberingScripts = (List<String>) get("numberingScripts");
546 if (numberingScripts == null) {
547 numberingScripts = new ArrayList<>();
548 put("numberingScripts", numberingScripts);
549 }
550 numberingScripts.add(script);
551 put(currentNumberingSystem + "NumberElements/zero", digits.substring(0, 1));
552 pushContainer(qName, attributes);
553 }
554 break;
555 case "decimal":
556 // for FormatData
557 // copy string for later assembly into NumberElements
558 if (currentContainer.getqName().equals("symbols")) {
559 pushStringEntry(qName, attributes, currentNumberingSystem + "NumberElements/decimal");
560 } else {
561 pushIgnoredContainer(qName);
562 }
563 break;
926 target = target.substring(0, target.indexOf('.'))+"."+tmp[0];
927 }
928 CLDRConverter.aliases.put(src.replaceFirst("^gregorian.", ""),
929 target.replaceFirst("^gregorian.", ""));
930 }
931 }
932 } else if (currentContainer instanceof Entry) {
933 Entry<?> entry = (Entry<?>) currentContainer;
934 Object value = entry.getValue();
935 if (value != null) {
936 String key = entry.getKey();
937 // Tweak for MonthNames for the root locale, Needed for
938 // SimpleDateFormat.format()/parse() roundtrip.
939 if (id.equals("root") && key.startsWith("MonthNames")) {
940 value = new DateFormatSymbols(Locale.US).getShortMonths();
941 }
942 put(entry.getKey(), value);
943 }
944 }
945 }
946
947 public String convertOldKeyName(String key) {
948 // TODO: This should not be hard coded. Instead, obtained from "alias"
949 // attribute in each "key" element.
950 switch (key) {
951 case "calendar":
952 return "ca";
953 case "currency":
954 return "cu";
955 case "collation":
956 return "co";
957 case "numbers":
958 return "nu";
959 case "timezone":
960 return "tz";
961 default:
962 return key;
963 }
964 }
965 }
|