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