1 /* 2 * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package build.tools.cldrconverter; 27 28 import java.io.File; 29 import java.io.IOException; 30 import java.util.HashMap; 31 import java.util.Map; 32 import org.xml.sax.Attributes; 33 import org.xml.sax.InputSource; 34 import org.xml.sax.SAXException; 35 36 /** 37 * Handles parsing of files in Locale Data Markup Language for SupplementData.xml 38 * and produces a map that uses the keys and values of JRE locale data. 39 */ 40 41 class SupplementDataParseHandler extends AbstractLDMLHandler<Object> { 42 //UNM49 region and composition code used in supplementalData.xml 43 private static final String WORLD = "001"; 44 45 private static final String JAVA_FIRSTDAY = "firstDayOfWeek"; 46 private static final String JAVA_MINDAY = "minimalDaysInFirstWeek"; 47 48 // The weekData is now in supplementalData.xml, 49 // which is not a locale specific file. 50 // Map for JRE is created locale specific way. 51 // When parsing the locale neutral file (supplementalData.xml), 52 // we need to rely on the country code because 53 // the weekData is listed using country code. 54 // 55 // weekData are generated per each country 56 private final Map<String, Object> firstDayMap; 57 private final Map<String, Object> minDaysMap; 58 59 // Parent locales. These information will only be 60 // generated towards the base meta info, with the format of 61 // 62 // parentLocale.<parent_locale_id>=<child_locale_id>(" "<child_locale_id>)+ 63 private final Map<String, String> parentLocalesMap; 64 SupplementDataParseHandler()65 SupplementDataParseHandler() { 66 firstDayMap = new HashMap<>(); 67 minDaysMap = new HashMap<>(); 68 parentLocalesMap = new HashMap<>(); 69 } 70 71 /** 72 * It returns Map that contains the firstDay and minDays information for 73 * the country. The Map is created in JRE format after obtaining the data 74 * from two Maps, firstDayMap and minDaysMap. 75 * 76 * It returns null when there is no firstDay and minDays for the country 77 * although this should not happen because supplementalData.xml includes 78 * default value for the world ("001") for firstDay and minDays. 79 */ getData(String id)80 Map<String, Object> getData(String id) { 81 Map<String, Object> values = new HashMap<>(); 82 if ("root".equals(id)) { 83 parentLocalesMap.keySet().forEach(key -> { 84 values.put(CLDRConverter.PARENT_LOCALE_PREFIX+key, 85 parentLocalesMap.get(key)); 86 }); 87 firstDayMap.keySet().forEach(key -> { 88 values.put(CLDRConverter.CALENDAR_FIRSTDAY_PREFIX+firstDayMap.get(key), 89 key); 90 }); 91 minDaysMap.keySet().forEach(key -> { 92 values.put(CLDRConverter.CALENDAR_MINDAYS_PREFIX+minDaysMap.get(key), 93 key); 94 }); 95 } 96 return values.isEmpty() ? null : values; 97 } 98 99 @Override resolveEntity(String publicID, String systemID)100 public InputSource resolveEntity(String publicID, String systemID) throws IOException, SAXException { 101 // avoid HTTP traffic to unicode.org 102 if (systemID.startsWith(CLDRConverter.SPPL_LDML_DTD_SYSTEM_ID)) { 103 return new InputSource((new File(CLDRConverter.LOCAL_SPPL_LDML_DTD)).toURI().toString()); 104 } 105 return null; 106 } 107 108 /** 109 * JRE requires all the data to be organized by the locale while CLDR 1.4 list 110 * Calendar related data (weekData)in SupplementalData.xml. 111 * startElement stores JRE required data into two Maps, 112 * firstDayMap and minDaysMap. 113 */ 114 @Override startElement(String uri, String localName, String qName, Attributes attributes)115 public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { 116 // elements we need to actively ignore 117 switch (qName) { 118 case "firstDay": 119 if (!isIgnored(attributes)) { 120 String fd; 121 122 switch (attributes.getValue("day")) { 123 case "sun": 124 fd = "1"; 125 break; 126 default: 127 case "mon": 128 fd = "2"; 129 break; 130 case "tue": 131 fd = "3"; 132 break; 133 case "wed": 134 fd = "4"; 135 break; 136 case "thu": 137 fd = "5"; 138 break; 139 case "fri": 140 fd = "6"; 141 break; 142 case "sat": 143 fd = "7"; 144 break; 145 } 146 firstDayMap.put(attributes.getValue("territories"), fd); 147 } 148 break; 149 case "minDays": 150 if (!isIgnored(attributes)) { 151 minDaysMap.put(attributes.getValue("territories"), attributes.getValue("count")); 152 } 153 break; 154 case "parentLocale": 155 if (!isIgnored(attributes)) { 156 parentLocalesMap.put( 157 attributes.getValue("parent").replaceAll("_", "-"), 158 attributes.getValue("locales").replaceAll("_", "-")); 159 } 160 break; 161 default: 162 // treat anything else as a container 163 pushContainer(qName, attributes); 164 break; 165 } 166 } 167 168 } 169