001: /*
002: * Copyright (c) 1998 Sun Microsystems, Inc. All Rights Reserved.
003: */
004:
005: package com.sun.xml.dtdparser;
006:
007: /**
008: * This class contains static methods used to determine whether identifiers
009: * may appear in certain roles in XML documents. Such methods are used
010: * both to parse and to create such documents.
011: *
012: * @author David Brownell
013: * @version 1.1, 00/08/05
014: */
015: public class XmlNames {
016: private XmlNames() {
017: }
018:
019: /**
020: * Returns true if the value is a legal XML name.
021: *
022: * @param value the string being tested
023: */
024: public static boolean isName(String value) {
025: if (value == null)
026: return false;
027:
028: char c = value.charAt(0);
029: if (!XmlChars.isLetter(c) && c != '_' && c != ':')
030: return false;
031: for (int i = 1; i < value.length(); i++)
032: if (!XmlChars.isNameChar(value.charAt(i)))
033: return false;
034: return true;
035: }
036:
037: /**
038: * Returns true if the value is a legal "unqualified" XML name, as
039: * defined in the XML Namespaces proposed recommendation.
040: * These are normal XML names, except that they may not contain
041: * a "colon" character.
042: *
043: * @param value the string being tested
044: */
045: public static boolean isUnqualifiedName(String value) {
046: if (value == null || value.length() == 0)
047: return false;
048:
049: char c = value.charAt(0);
050: if (!XmlChars.isLetter(c) && c != '_')
051: return false;
052: for (int i = 1; i < value.length(); i++)
053: if (!XmlChars.isNCNameChar(value.charAt(i)))
054: return false;
055: return true;
056: }
057:
058: /**
059: * Returns true if the value is a legal "qualified" XML name, as defined
060: * in the XML Namespaces proposed recommendation. Qualified names are
061: * composed of an optional prefix (an unqualified name), followed by a
062: * colon, and a required "local part" (an unqualified name). Prefixes are
063: * declared, and correspond to particular URIs which scope the "local
064: * part" of the name. (This method cannot check whether the prefix of a
065: * name has been declared.)
066: *
067: * @param value the string being tested
068: */
069: public static boolean isQualifiedName(String value) {
070: if (value == null)
071: return false;
072:
073: // [6] QName ::= (Prefix ':')? LocalPart
074: // [7] Prefix ::= NCName
075: // [8] LocalPart ::= NCName
076:
077: int first = value.indexOf(':');
078:
079: // no Prefix, only check LocalPart
080: if (first <= 0)
081: return isUnqualifiedName(value);
082:
083: // Prefix exists, check everything
084:
085: int last = value.lastIndexOf(':');
086: if (last != first)
087: return false;
088:
089: return isUnqualifiedName(value.substring(0, first))
090: && isUnqualifiedName(value.substring(first + 1));
091: }
092:
093: /**
094: * This method returns true if the identifier is a "name token"
095: * as defined in the XML specification. Like names, these
096: * may only contain "name characters"; however, they do not need
097: * to have letters as their initial characters. Attribute values
098: * defined to be of type NMTOKEN(S) must satisfy this predicate.
099: *
100: * @param token the string being tested
101: */
102: public static boolean isNmtoken(String token) {
103: int length = token.length();
104:
105: for (int i = 0; i < length; i++)
106: if (!XmlChars.isNameChar(token.charAt(i)))
107: return false;
108: return true;
109: }
110:
111: /**
112: * This method returns true if the identifier is a "name token" as
113: * defined by the XML Namespaces proposed recommendation.
114: * These are like XML "name tokens" but they may not contain the
115: * "colon" character.
116: *
117: * @param token the string being tested
118: * @see #isNmtoken
119: */
120: public static boolean isNCNmtoken(String token) {
121: return isNmtoken(token) && token.indexOf(':') < 0;
122: }
123: }
|