make/src/classes/build/tools/cldrconverter/LDMLParseHandler.java

Print this page

        

*** 1,7 **** /* ! * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this --- 1,7 ---- /* ! * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this
*** 27,39 **** --- 27,41 ---- import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; + import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; + import java.util.Set; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.SAXException; /**
*** 45,54 **** --- 47,58 ---- private String currentNumberingSystem = ""; private CalendarType currentCalendarType; private String zoneNameStyle; // "long" or "short" for time zone names private String zonePrefix; private final String id; + private String currentContext = ""; // "format"/"stand-alone" + private String currentWidth = ""; // "wide"/"narrow"/"abbreviated" LDMLParseHandler(String id) { this.id = id; }
*** 110,122 **** break; // Calendar or currency case "displayName": { ! if (currentCalendarType != null) { pushStringEntry(qName, attributes, ! currentCalendarType.keyElementName() + "field." + getContainerKey()); } else { // for CurrencyNames // need to get the key from the containing <currency> element // ignore if is has "count" attribute String containerKey = getContainerKey(); --- 114,127 ---- break; // Calendar or currency case "displayName": { ! if (currentContainer.getqName().equals("field")) { pushStringEntry(qName, attributes, ! (currentCalendarType != null ? currentCalendarType.keyElementName() : "") ! + "field." + getContainerKey()); } else { // for CurrencyNames // need to get the key from the containing <currency> element // ignore if is has "count" attribute String containerKey = getContainerKey();
*** 147,160 **** pushIgnoredContainer(qName); } } break; case "fields": ! if (currentCalendarType != null) { pushContainer(qName, attributes); - } else { - pushIgnoredContainer(qName); } break; case "field": { String type = attributes.getValue("type"); --- 152,163 ---- pushIgnoredContainer(qName); } } break; case "fields": ! { pushContainer(qName, attributes); } break; case "field": { String type = attributes.getValue("type");
*** 181,190 **** --- 184,194 ---- { // for FormatData // need to keep stand-alone and format, to allow for inheritance in CLDR String type = attributes.getValue("type"); if ("stand-alone".equals(type) || "format".equals(type)) { + currentContext = type; pushKeyContainer(qName, attributes, type); } else { pushIgnoredContainer(qName); } }
*** 192,203 **** case "monthWidth": { // for FormatData // create string array for the two types that the JRE knows // keep info about the context type so we can sort out inheritance later String prefix = (currentCalendarType == null) ? "" : currentCalendarType.keyElementName(); ! switch (attributes.getValue("type")) { case "wide": pushStringArrayEntry(qName, attributes, prefix + "MonthNames/" + getContainerKey(), 13); break; case "abbreviated": pushStringArrayEntry(qName, attributes, prefix + "MonthAbbreviations/" + getContainerKey(), 13); --- 196,212 ---- case "monthWidth": { // for FormatData // create string array for the two types that the JRE knows // keep info about the context type so we can sort out inheritance later + if (currentCalendarType == null) { + pushIgnoredContainer(qName); + break; + } String prefix = (currentCalendarType == null) ? "" : currentCalendarType.keyElementName(); ! currentWidth = attributes.getValue("type"); ! switch (currentWidth) { case "wide": pushStringArrayEntry(qName, attributes, prefix + "MonthNames/" + getContainerKey(), 13); break; case "abbreviated": pushStringArrayEntry(qName, attributes, prefix + "MonthAbbreviations/" + getContainerKey(), 13);
*** 220,229 **** --- 229,239 ---- { // for FormatData // need to keep stand-alone and format, to allow for multiple inheritance in CLDR String type = attributes.getValue("type"); if ("stand-alone".equals(type) || "format".equals(type)) { + currentContext = type; pushKeyContainer(qName, attributes, type); } else { pushIgnoredContainer(qName); } }
*** 232,242 **** { // for FormatData // create string array for the two types that the JRE knows // keep info about the context type so we can sort out inheritance later String prefix = (currentCalendarType == null) ? "" : currentCalendarType.keyElementName(); ! switch (attributes.getValue("type")) { case "wide": pushStringArrayEntry(qName, attributes, prefix + "DayNames/" + getContainerKey(), 7); break; case "abbreviated": pushStringArrayEntry(qName, attributes, prefix + "DayAbbreviations/" + getContainerKey(), 7); --- 242,253 ---- { // for FormatData // create string array for the two types that the JRE knows // keep info about the context type so we can sort out inheritance later String prefix = (currentCalendarType == null) ? "" : currentCalendarType.keyElementName(); ! currentWidth = attributes.getValue("type"); ! switch (currentWidth) { case "wide": pushStringArrayEntry(qName, attributes, prefix + "DayNames/" + getContainerKey(), 7); break; case "abbreviated": pushStringArrayEntry(qName, attributes, prefix + "DayAbbreviations/" + getContainerKey(), 7);
*** 261,280 **** // for FormatData // need to keep stand-alone and format, to allow for multiple inheritance in CLDR { String type = attributes.getValue("type"); if ("stand-alone".equals(type) || "format".equals(type)) { pushKeyContainer(qName, attributes, type); } else { pushIgnoredContainer(qName); } } break; case "dayPeriodWidth": // for FormatData // create string array entry for am/pm. only keeping wide ! switch (attributes.getValue("type")) { case "wide": pushStringArrayEntry(qName, attributes, "AmPmMarkers/" + getContainerKey(), 2); break; case "narrow": pushStringArrayEntry(qName, attributes, "narrow.AmPmMarkers/" + getContainerKey(), 2); --- 272,293 ---- // for FormatData // need to keep stand-alone and format, to allow for multiple inheritance in CLDR { String type = attributes.getValue("type"); if ("stand-alone".equals(type) || "format".equals(type)) { + currentContext = type; pushKeyContainer(qName, attributes, type); } else { pushIgnoredContainer(qName); } } break; case "dayPeriodWidth": // for FormatData // create string array entry for am/pm. only keeping wide ! currentWidth = attributes.getValue("type"); ! switch (currentWidth) { case "wide": pushStringArrayEntry(qName, attributes, "AmPmMarkers/" + getContainerKey(), 2); break; case "narrow": pushStringArrayEntry(qName, attributes, "narrow.AmPmMarkers/" + getContainerKey(), 2);
*** 360,369 **** --- 373,383 ---- { // for FormatData // need to keep stand-alone and format, to allow for inheritance in CLDR String type = attributes.getValue("type"); if ("stand-alone".equals(type) || "format".equals(type)) { + currentContext = type; pushKeyContainer(qName, attributes, type); } else { pushIgnoredContainer(qName); } }
*** 371,381 **** case "quarterWidth": { // for FormatData // keep info about the context type so we can sort out inheritance later String prefix = (currentCalendarType == null) ? "" : currentCalendarType.keyElementName(); ! switch (attributes.getValue("type")) { case "wide": pushStringArrayEntry(qName, attributes, prefix + "QuarterNames/" + getContainerKey(), 4); break; case "abbreviated": pushStringArrayEntry(qName, attributes, prefix + "QuarterAbbreviations/" + getContainerKey(), 4); --- 385,396 ---- case "quarterWidth": { // for FormatData // keep info about the context type so we can sort out inheritance later String prefix = (currentCalendarType == null) ? "" : currentCalendarType.keyElementName(); ! currentWidth = attributes.getValue("type"); ! switch (currentWidth) { case "wide": pushStringArrayEntry(qName, attributes, prefix + "QuarterNames/" + getContainerKey(), 4); break; case "abbreviated": pushStringArrayEntry(qName, attributes, prefix + "QuarterAbbreviations/" + getContainerKey(), 4);
*** 448,463 **** --- 463,486 ---- } break; case "currencyFormat": // for FormatData // copy string for later assembly into NumberPatterns + if (attributes.getValue("type").equals("standard")) { pushStringEntry(qName, attributes, "NumberPatterns/currency"); + } else { + pushIgnoredContainer(qName); + } break; case "percentFormat": // for FormatData // copy string for later assembly into NumberPatterns + if (attributes.getValue("type").equals("standard")) { pushStringEntry(qName, attributes, "NumberPatterns/percent"); + } else { + pushIgnoredContainer(qName); + } break; case "defaultNumberingSystem": // default numbering system if multiple numbering systems are used. pushStringEntry(qName, attributes, "DefaultNumberingSystem"); break;
*** 580,595 **** // copy string for later assembly into DateTimePatterns String prefix = (currentCalendarType == null) ? "" : currentCalendarType.keyElementName(); pushStringEntry(qName, attributes, prefix + "DateTimePatterns/" + attributes.getValue("type") + "-date"); } break; ! case "dateTimeFormat": { // for FormatData // copy string for later assembly into DateTimePatterns String prefix = (currentCalendarType == null) ? "" : currentCalendarType.keyElementName(); ! pushStringEntry(qName, attributes, prefix + "DateTimePatterns/date-time"); } break; case "localizedPatternChars": { // for FormatData --- 603,618 ---- // copy string for later assembly into DateTimePatterns String prefix = (currentCalendarType == null) ? "" : currentCalendarType.keyElementName(); pushStringEntry(qName, attributes, prefix + "DateTimePatterns/" + attributes.getValue("type") + "-date"); } break; ! case "dateTimeFormatLength": { // for FormatData // copy string for later assembly into DateTimePatterns String prefix = (currentCalendarType == null) ? "" : currentCalendarType.keyElementName(); ! pushStringEntry(qName, attributes, prefix + "DateTimePatterns/" + attributes.getValue("type") + "-dateTime"); } break; case "localizedPatternChars": { // for FormatData
*** 597,613 **** --- 620,828 ---- String prefix = (currentCalendarType == null) ? "" : currentCalendarType.keyElementName(); pushStringEntry(qName, attributes, prefix + "DateTimePatternChars"); } break; + // "alias" for root + case "alias": + { + if (id.equals("root") && + !isIgnored(attributes) && + currentCalendarType != null && + !currentCalendarType.lname().startsWith("islamic-")) { // ignore Islamic variants + pushAliasEntry(qName, attributes, attributes.getValue("path")); + } else { + pushIgnoredContainer(qName); + } + } + break; + default: // treat anything else as a container pushContainer(qName, attributes); break; } } + private static final String[] CONTEXTS = {"stand-alone", "format"}; + private static final String[] WIDTHS = {"wide", "narrow", "abbreviated"}; + private static final String[] LENGTHS = {"full", "long", "medium", "short"}; + + private void populateWidthAlias(String type, Set<String> keys) { + for (String context : CONTEXTS) { + for (String width : WIDTHS) { + String keyName = toJDKKey(type+"Width", context, width); + if (keyName.length() > 0) { + keys.add(keyName + "," + context + "," + width); + } + } + } + } + + private void populateFormatLengthAlias(String type, Set<String> keys) { + for (String length: LENGTHS) { + String keyName = toJDKKey(type+"FormatLength", currentContext, length); + if (keyName.length() > 0) { + keys.add(keyName + "," + currentContext + "," + length); + } + } + } + + private Set<String> populateAliasKeys(String qName, String context, String width) { + HashSet<String> ret = new HashSet<>(); + String keyName = qName; + + switch (qName) { + case "monthWidth": + case "dayWidth": + case "quarterWidth": + case "dayPeriodWidth": + case "dateFormatLength": + case "timeFormatLength": + case "dateTimeFormatLength": + case "eraNames": + case "eraAbbr": + case "eraNarrow": + ret.add(toJDKKey(qName, context, width) + "," + context + "," + width); + break; + case "days": + populateWidthAlias("day", ret); + break; + case "months": + populateWidthAlias("month", ret); + break; + case "quarters": + populateWidthAlias("quarter", ret); + break; + case "dayPeriods": + populateWidthAlias("dayPeriod", ret); + break; + case "eras": + ret.add(toJDKKey("eraNames", context, width) + "," + context + "," + width); + ret.add(toJDKKey("eraAbbr", context, width) + "," + context + "," + width); + ret.add(toJDKKey("eraNarrow", context, width) + "," + context + "," + width); + break; + case "dateFormats": + populateFormatLengthAlias("date", ret); + break; + case "timeFormats": + populateFormatLengthAlias("time", ret); + break; + default: + break; + } + return ret; + } + + private String translateWidthAlias(String qName, String context, String width) { + String keyName = qName; + String type = Character.toUpperCase(qName.charAt(0)) + qName.substring(1, qName.indexOf("Width")); + + switch (width) { + case "wide": + keyName = type + "Names/" + context; + break; + case "abbreviated": + keyName = type + "Abbreviations/" + context; + break; + case "narrow": + keyName = type + "Narrows/" + context; + break; + default: + assert false; + } + + return keyName; + } + + private String toJDKKey(String containerqName, String context, String type) { + String keyName = containerqName; + + switch (containerqName) { + case "monthWidth": + case "dayWidth": + case "quarterWidth": + keyName = translateWidthAlias(keyName, context, type); + break; + case "dayPeriodWidth": + switch (type) { + case "wide": + keyName = "AmPmMarkers/" + context; + break; + case "narrow": + keyName = "narrow.AmPmMarkers/" + context; + break; + case "abbreviated": + keyName = ""; + break; + } + break; + case "dateFormatLength": + case "timeFormatLength": + case "dateTimeFormatLength": + keyName = "DateTimePatterns/" + + type + "-" + + keyName.substring(0, keyName.indexOf("FormatLength")); + break; + case "eraNames": + keyName = "long.Eras"; + break; + case "eraAbbr": + keyName = "Eras"; + break; + case "eraNarrow": + keyName = "narrow.Eras"; + break; + case "dateFormats": + case "timeFormats": + case "days": + case "months": + case "quarters": + case "dayPeriods": + case "eras": + break; + default: + keyName = ""; + break; + } + + return keyName; + } + + private String getTarget(String qName, String path, String calType, String context, String width) { + // qName + int lastSlash = path.lastIndexOf('/'); + qName = path.substring(lastSlash+1); + int bracket = qName.indexOf('['); + if (bracket != -1) { + qName = qName.substring(0, bracket); + } + + // calType + String typeKey = "/calendar[@type='"; + int start = path.indexOf(typeKey); + if (start != -1) { + calType = path.substring(start+typeKey.length(), path.indexOf("']", start)); + } + + // context + typeKey = "Context[@type='"; + start = path.indexOf(typeKey); + if (start != -1) { + context = (path.substring(start+typeKey.length(), path.indexOf("']", start))); + } + + // width + typeKey = "Width[@type='"; + start = path.indexOf(typeKey); + if (start != -1) { + width = path.substring(start+typeKey.length(), path.indexOf("']", start)); + } + + return calType + "." + toJDKKey(qName, context, width); + } + @Override public void endElement(String uri, String localName, String qName) throws SAXException { assert qName.equals(currentContainer.getqName()) : "current=" + currentContainer.getqName() + ", param=" + qName; switch (qName) { case "calendar":
*** 626,652 **** break; case "timeZoneNames": zonePrefix = null; break; case "generic": case "standard": case "daylight": if (zonePrefix != null && (currentContainer instanceof Entry)) { @SuppressWarnings("unchecked") Map<String, String> valmap = (Map<String, String>) get(zonePrefix + getContainerKey()); Entry<?> entry = (Entry<?>) currentContainer; valmap.put(entry.getKey(), (String) entry.getValue()); } break; default: ! if (currentContainer instanceof Entry) { Entry<?> entry = (Entry<?>) currentContainer; Object value = entry.getValue(); if (value != null) { put(entry.getKey(), value); } } } - currentContainer = currentContainer.getParent(); - } } --- 841,911 ---- break; case "timeZoneNames": zonePrefix = null; break; + case "generic": case "standard": case "daylight": if (zonePrefix != null && (currentContainer instanceof Entry)) { @SuppressWarnings("unchecked") Map<String, String> valmap = (Map<String, String>) get(zonePrefix + getContainerKey()); Entry<?> entry = (Entry<?>) currentContainer; valmap.put(entry.getKey(), (String) entry.getValue()); } break; + + case "monthWidth": + case "dayWidth": + case "dayPeriodWidth": + case "quarterWidth": + currentWidth = ""; + putIfEntry(); + break; + + case "monthContext": + case "dayContext": + case "dayPeriodContext": + case "quarterContext": + currentContext = ""; + putIfEntry(); + break; + default: ! putIfEntry(); ! } ! currentContainer = currentContainer.getParent(); ! } ! ! private void putIfEntry() { ! if (currentContainer instanceof AliasEntry) { ! Entry<?> entry = (Entry<?>) currentContainer; ! String containerqName = entry.getParent().getqName(); ! Set<String> keyNames = populateAliasKeys(containerqName, currentContext, currentWidth); ! if (!keyNames.isEmpty()) { ! for (String keyName : keyNames) { ! String[] tmp = keyName.split(",", 3); ! String calType = currentCalendarType.lname(); ! String src = calType+"."+tmp[0]; ! String target = getTarget(containerqName, ! entry.getKey(), ! calType, ! tmp[1].length()>0 ? tmp[1] : currentContext, ! tmp[2].length()>0 ? tmp[2] : currentWidth); ! if (target.substring(target.lastIndexOf('.')+1).equals(containerqName)) { ! // may not always be correct ! target = target.substring(0, target.indexOf('.'))+"."+tmp[0]; ! } ! CLDRConverter.aliases.put(src.replaceFirst("^gregorian.", ""), ! target.replaceFirst("^gregorian.", "")); ! } ! } ! } else if (currentContainer instanceof Entry) { Entry<?> entry = (Entry<?>) currentContainer; Object value = entry.getValue(); if (value != null) { put(entry.getKey(), value); } } } }