--- /dev/null Fri Jul 20 11:47:51 2012 +++ new/make/tools/src/build/tools/cldrconverter/AbstractLDMLHandler.java Fri Jul 20 11:47:48 2012 @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2012, 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 + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package build.tools.cldrconverter; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; +import org.xml.sax.helpers.DefaultHandler; + +/** + * This is an abstract class for general LDML parsing purpose. + * LDMLParseHandler, SupplementLDMLParseHandler, and NumberingLDMLParseHandler + * are the subclasses of this class. + */ + +abstract class AbstractLDMLHandler extends DefaultHandler { + static final Map DAY_OF_WEEK_MAP = new HashMap<>(); + static { + DAY_OF_WEEK_MAP.put("sun", "1"); + DAY_OF_WEEK_MAP.put("mon", "2"); + DAY_OF_WEEK_MAP.put("tue", "3"); + DAY_OF_WEEK_MAP.put("wed", "4"); + DAY_OF_WEEK_MAP.put("thu", "5"); + DAY_OF_WEEK_MAP.put("fri", "6"); + DAY_OF_WEEK_MAP.put("sat", "7"); + } + // Collected data in JRE locale data format. + private Map data = new HashMap<>(); + + // The root Container + Container currentContainer = new Container("$ROOT", null); + + AbstractLDMLHandler() { + } + + Map getData() { + return data; + } + + V put(String key, V value) { + return data.put(key, value); + } + + V get(String key) { + return data.get(key); + } + + Set keySet() { + return data.keySet(); + } + + /* + * It returns true if the data should be ignored based on the user + * defined acceptance level, which is listed with draft attribute in + * the cldr locale xml files. + * When the alt attribute is present, the data is always ignored since + * we always use the primary data + */ + boolean isIgnored(Attributes attributes) { + if (attributes.getValue("alt") != null) { + return true; + } + String draftValue = attributes.getValue("draft"); + if (draftValue != null) { + return CLDRConverter.draftType > CLDRConverter.DRAFT_MAP.get(draftValue); + } + return false; + } + + void pushContainer(String qName, Attributes attributes) { + if (isIgnored(attributes) || currentContainer instanceof IgnoredContainer) { + currentContainer = new IgnoredContainer(qName, currentContainer); + } else { + currentContainer = new Container(qName, currentContainer); + } + } + + void pushIgnoredContainer(String qName) { + currentContainer = new IgnoredContainer(qName, currentContainer); + } + + void pushKeyContainer(String qName, Attributes attributes, String key) { + if (!pushIfIgnored(qName, attributes)) { + currentContainer = new KeyContainer(qName, currentContainer, key); + } + } + + /** + * start an element that defines a string entry, with the value provided by the element's text. + */ + void pushStringEntry(String qName, Attributes attributes, String key) { + if (!pushIfIgnored(qName, attributes)) { + currentContainer = new StringEntry(qName, currentContainer, key); + } + } + + /** + * start an element that defines a string entry, with the value provided by an attribute value. + */ + void pushStringEntry(String qName, Attributes attributes, String key, String value) { + if (!pushIfIgnored(qName, attributes)) { + currentContainer = new StringEntry(qName, currentContainer, key, value); + } + } + + void pushStringArrayEntry(String qName, Attributes attributes, String key, int length) { + if (!pushIfIgnored(qName, attributes)) { + currentContainer = new StringArrayEntry(qName, currentContainer, key, length); + } + } + + void pushStringArrayElement(String qName, Attributes attributes, int index) { + if (!pushIfIgnored(qName, attributes)) { + currentContainer = new StringArrayElement(qName, currentContainer, index); + } + } + + private boolean pushIfIgnored(String qName, Attributes attributes) { + if (isIgnored(attributes) || currentContainer instanceof IgnoredContainer) { + pushIgnoredContainer(qName); + return true; + } + return false; + } + + /** + * Obtains the key from the innermost containing container that provides one. + */ + String getContainerKey() { + Container current = currentContainer; + while (current != null) { + if (current instanceof KeyContainer) { + return ((KeyContainer) current).getKey(); + } + current = current.getParent(); + } + return null; + } + + @Override + public void characters(char[] ch, int start, int length) throws SAXException { + currentContainer.addCharacters(ch, start, length); + } + + @SuppressWarnings(value = "CallToThreadDumpStack") + @Override + public void warning(SAXParseException e) throws SAXException { + e.printStackTrace(); + } + + @SuppressWarnings(value = "CallToThreadDumpStack") + @Override + public void error(SAXParseException e) throws SAXException { + e.printStackTrace(); + } + + @SuppressWarnings(value = "CallToThreadDumpStack") + @Override + public void fatalError(SAXParseException e) throws SAXException { + e.printStackTrace(); + super.fatalError(e); + } +}