1 /* 2 * Copyright (c) 2012, 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.util.HashMap; 29 import java.util.Map; 30 import java.util.Set; 31 import org.xml.sax.Attributes; 32 import org.xml.sax.SAXException; 33 import org.xml.sax.SAXParseException; 34 import org.xml.sax.helpers.DefaultHandler; 35 36 /** 37 * This is an abstract class for general LDML parsing purpose. 38 * LDMLParseHandler, SupplementLDMLParseHandler, and NumberingLDMLParseHandler 39 * are the subclasses of this class. 40 */ 41 42 abstract class AbstractLDMLHandler<V> extends DefaultHandler { 43 static final Map<String, String> DAY_OF_WEEK_MAP = new HashMap<>(); 44 static { 45 DAY_OF_WEEK_MAP.put("sun", "1"); 46 DAY_OF_WEEK_MAP.put("mon", "2"); 47 DAY_OF_WEEK_MAP.put("tue", "3"); 48 DAY_OF_WEEK_MAP.put("wed", "4"); 49 DAY_OF_WEEK_MAP.put("thu", "5"); 50 DAY_OF_WEEK_MAP.put("fri", "6"); 51 DAY_OF_WEEK_MAP.put("sat", "7"); 52 } 53 // Collected data in JRE locale data format. 54 private Map<String, V> data = new HashMap<>(); 55 56 // The root Container 57 Container currentContainer = new Container("$ROOT", null); 58 59 AbstractLDMLHandler() { 60 } 61 62 Map<String, V> getData() { 63 return data; 64 } 65 66 V put(String key, V value) { 67 return data.put(key, value); 68 } 69 70 V get(String key) { 71 return data.get(key); 72 } 73 74 Set<String> keySet() { 75 return data.keySet(); 76 } 77 78 /* 79 * It returns true if the data should be ignored based on the user 80 * defined acceptance level, which is listed with draft attribute in 81 * the cldr locale xml files. 82 * When the alt attribute is present, the data is always ignored since 83 * we always use the primary data 84 */ 85 boolean isIgnored(Attributes attributes) { 86 if (attributes.getValue("alt") != null) { 87 return true; 88 } 89 String draftValue = attributes.getValue("draft"); 90 if (draftValue != null) { 91 return CLDRConverter.draftType > CLDRConverter.DRAFT_MAP.get(draftValue); 92 } 93 return false; 94 } 95 96 void pushContainer(String qName, Attributes attributes) { 97 if (isIgnored(attributes) || currentContainer instanceof IgnoredContainer) { 98 currentContainer = new IgnoredContainer(qName, currentContainer); 99 } else { 100 currentContainer = new Container(qName, currentContainer); 101 } 102 } 103 104 void pushIgnoredContainer(String qName) { 105 currentContainer = new IgnoredContainer(qName, currentContainer); 106 } 107 108 void pushKeyContainer(String qName, Attributes attributes, String key) { 109 if (!pushIfIgnored(qName, attributes)) { 110 currentContainer = new KeyContainer(qName, currentContainer, key); 111 } 112 } 113 114 /** 115 * start an element that defines a string entry, with the value provided by the element's text. 116 */ 117 void pushStringEntry(String qName, Attributes attributes, String key) { 118 if (!pushIfIgnored(qName, attributes)) { 119 currentContainer = new StringEntry(qName, currentContainer, key); 120 } 121 } 122 123 /** 124 * start an element that defines a string entry, with the value provided by an attribute value. 125 */ 126 void pushStringEntry(String qName, Attributes attributes, String key, String value) { 127 if (!pushIfIgnored(qName, attributes)) { 128 currentContainer = new StringEntry(qName, currentContainer, key, value); 129 } 130 } 131 132 void pushStringArrayEntry(String qName, Attributes attributes, String key, int length) { 133 if (!pushIfIgnored(qName, attributes)) { 134 currentContainer = new StringArrayEntry(qName, currentContainer, key, length); 135 } 136 } 137 138 void pushStringArrayElement(String qName, Attributes attributes, int index) { 139 if (!pushIfIgnored(qName, attributes)) { 140 currentContainer = new StringArrayElement(qName, currentContainer, index); 141 } 142 } 143 144 private boolean pushIfIgnored(String qName, Attributes attributes) { 145 if (isIgnored(attributes) || currentContainer instanceof IgnoredContainer) { 146 pushIgnoredContainer(qName); 147 return true; 148 } 149 return false; 150 } 151 152 /** 153 * Obtains the key from the innermost containing container that provides one. 154 */ 155 String getContainerKey() { 156 Container current = currentContainer; 157 while (current != null) { 158 if (current instanceof KeyContainer) { 159 return ((KeyContainer) current).getKey(); 160 } 161 current = current.getParent(); 162 } 163 return null; 164 } 165 166 @Override 167 public void characters(char[] ch, int start, int length) throws SAXException { 168 currentContainer.addCharacters(ch, start, length); 169 } 170 171 @SuppressWarnings(value = "CallToThreadDumpStack") 172 @Override 173 public void warning(SAXParseException e) throws SAXException { 174 e.printStackTrace(); 175 } 176 177 @SuppressWarnings(value = "CallToThreadDumpStack") 178 @Override 179 public void error(SAXParseException e) throws SAXException { 180 e.printStackTrace(); 181 } 182 183 @SuppressWarnings(value = "CallToThreadDumpStack") 184 @Override 185 public void fatalError(SAXParseException e) throws SAXException { 186 e.printStackTrace(); 187 super.fatalError(e); 188 } 189 }