ohair@286: /* ohair@286: * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. ohair@286: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ohair@286: * ohair@286: * This code is free software; you can redistribute it and/or modify it ohair@286: * under the terms of the GNU General Public License version 2 only, as ohair@286: * published by the Free Software Foundation. Oracle designates this ohair@286: * particular file as subject to the "Classpath" exception as provided ohair@286: * by Oracle in the LICENSE file that accompanied this code. ohair@286: * ohair@286: * This code is distributed in the hope that it will be useful, but WITHOUT ohair@286: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ohair@286: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ohair@286: * version 2 for more details (a copy is included in the LICENSE file that ohair@286: * accompanied this code). ohair@286: * ohair@286: * You should have received a copy of the GNU General Public License version ohair@286: * 2 along with this work; if not, write to the Free Software Foundation, ohair@286: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ohair@286: * ohair@286: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ohair@286: * or visit www.oracle.com if you need additional information or have any ohair@286: * questions. ohair@286: */ ohair@286: ohair@286: package com.sun.xml.internal.dtdparser; ohair@286: ohair@286: ohair@286: /** ohair@286: * This class contains static methods used to determine whether identifiers ohair@286: * may appear in certain roles in XML documents. Such methods are used ohair@286: * both to parse and to create such documents. ohair@286: * ohair@286: * @author David Brownell ohair@286: * @version 1.1, 00/08/05 ohair@286: */ ohair@286: public class XmlNames { ohair@286: private XmlNames() { ohair@286: } ohair@286: ohair@286: ohair@286: /** ohair@286: * Returns true if the value is a legal XML name. ohair@286: * ohair@286: * @param value the string being tested ohair@286: */ ohair@286: public static boolean isName(String value) { ohair@286: if (value == null) ohair@286: return false; ohair@286: ohair@286: char c = value.charAt(0); ohair@286: if (!XmlChars.isLetter(c) && c != '_' && c != ':') ohair@286: return false; ohair@286: for (int i = 1; i < value.length(); i++) ohair@286: if (!XmlChars.isNameChar(value.charAt(i))) ohair@286: return false; ohair@286: return true; ohair@286: } ohair@286: ohair@286: /** ohair@286: * Returns true if the value is a legal "unqualified" XML name, as ohair@286: * defined in the XML Namespaces proposed recommendation. ohair@286: * These are normal XML names, except that they may not contain ohair@286: * a "colon" character. ohair@286: * ohair@286: * @param value the string being tested ohair@286: */ ohair@286: public static boolean isUnqualifiedName(String value) { ohair@286: if (value == null || value.length() == 0) ohair@286: return false; ohair@286: ohair@286: char c = value.charAt(0); ohair@286: if (!XmlChars.isLetter(c) && c != '_') ohair@286: return false; ohair@286: for (int i = 1; i < value.length(); i++) ohair@286: if (!XmlChars.isNCNameChar(value.charAt(i))) ohair@286: return false; ohair@286: return true; ohair@286: } ohair@286: ohair@286: /** ohair@286: * Returns true if the value is a legal "qualified" XML name, as defined ohair@286: * in the XML Namespaces proposed recommendation. Qualified names are ohair@286: * composed of an optional prefix (an unqualified name), followed by a ohair@286: * colon, and a required "local part" (an unqualified name). Prefixes are ohair@286: * declared, and correspond to particular URIs which scope the "local ohair@286: * part" of the name. (This method cannot check whether the prefix of a ohair@286: * name has been declared.) ohair@286: * ohair@286: * @param value the string being tested ohair@286: */ ohair@286: public static boolean isQualifiedName(String value) { ohair@286: if (value == null) ohair@286: return false; ohair@286: ohair@286: // [6] QName ::= (Prefix ':')? LocalPart ohair@286: // [7] Prefix ::= NCName ohair@286: // [8] LocalPart ::= NCName ohair@286: ohair@286: int first = value.indexOf(':'); ohair@286: ohair@286: // no Prefix, only check LocalPart ohair@286: if (first <= 0) ohair@286: return isUnqualifiedName(value); ohair@286: ohair@286: // Prefix exists, check everything ohair@286: ohair@286: int last = value.lastIndexOf(':'); ohair@286: if (last != first) ohair@286: return false; ohair@286: ohair@286: return isUnqualifiedName(value.substring(0, first)) ohair@286: && isUnqualifiedName(value.substring(first + 1)); ohair@286: } ohair@286: ohair@286: /** ohair@286: * This method returns true if the identifier is a "name token" ohair@286: * as defined in the XML specification. Like names, these ohair@286: * may only contain "name characters"; however, they do not need ohair@286: * to have letters as their initial characters. Attribute values ohair@286: * defined to be of type NMTOKEN(S) must satisfy this predicate. ohair@286: * ohair@286: * @param token the string being tested ohair@286: */ ohair@286: public static boolean isNmtoken(String token) { ohair@286: int length = token.length(); ohair@286: ohair@286: for (int i = 0; i < length; i++) ohair@286: if (!XmlChars.isNameChar(token.charAt(i))) ohair@286: return false; ohair@286: return true; ohair@286: } ohair@286: ohair@286: ohair@286: /** ohair@286: * This method returns true if the identifier is a "name token" as ohair@286: * defined by the XML Namespaces proposed recommendation. ohair@286: * These are like XML "name tokens" but they may not contain the ohair@286: * "colon" character. ohair@286: * ohair@286: * @param token the string being tested ohair@286: * @see #isNmtoken ohair@286: */ ohair@286: public static boolean isNCNmtoken(String token) { ohair@286: return isNmtoken(token) && token.indexOf(':') < 0; ohair@286: } ohair@286: }