/*
GASH 2
XMLNameValidator
Created: 10 December 2009
Module By: Jonathan Abbey, jonabbey@arlut.utexas.edu
-----------------------------------------------------------------------
Ganymede Directory Management System
Copyright (C) 1996-2010
The University of Texas at Austin
Contact information
Web site: http://www.arlut.utexas.edu/gash2
Author Email: ganymede_author@arlut.utexas.edu
Email mailing list: ganymede@arlut.utexas.edu
US Mail:
Computer Science Division
Applied Research Laboratories
The University of Texas at Austin
PO Box 8029, Austin TX 78713-8029
Telephone: (512) 835-3200
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package arlut.csd.Util;
/*------------------------------------------------------------------------------
class
XMLNameValidator
------------------------------------------------------------------------------*/
/**
* This is a dirt-simple XML Name validator for Ganymede, used to
* verify that proposed field names are acceptable for Ganymede's use.
*
* From the XML 1.1 (and XML 1.0 Version 5) standards:
*
* NameStartChar ::= ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] |
* [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] |
* [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] |
* [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] |
* [#x10000-#xEFFFF]
*
* NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
*
*/
public class XMLNameValidator {
/**
* Returns true if codePoint is a valid character to start a name
* (element name or attribute name) in XML 1.1 or XML 1.0 (revision
* 5).
*/
public static boolean isValidNameStartChar(int codePoint)
{
return (codePoint == ':' || codePoint == '_' ||
(codePoint >= 'A' && codePoint <= 'Z') ||
(codePoint >= 'a' && codePoint <= 'z') ||
(codePoint >= 0xC0 && codePoint <= 0xD6) ||
(codePoint >= 0xD8 && codePoint <= 0xF6) ||
(codePoint >= 0xF8 && codePoint <= 0x2FF) ||
(codePoint >= 0x370 && codePoint <= 0x37D) ||
(codePoint >= 0x37F && codePoint <= 0x1FFF) ||
(codePoint >= 0x200C && codePoint <= 0x200D) ||
(codePoint >= 0x2070 && codePoint <= 0x218F) ||
(codePoint >= 0x2C00 && codePoint <= 0x2FEF) ||
(codePoint >= 0x3001 && codePoint <= 0xD7FF) ||
(codePoint >= 0xF900 && codePoint <= 0xFDCF) ||
(codePoint >= 0xFDF0 && codePoint <= 0xFFFD) ||
(codePoint >= 0x10000 && codePoint <= 0xEFFFF));
}
/**
* Returns true if codePoint is a valid character for a character
* after the first in a name (element name or attribute name) in XML
* 1.1 or XML 1.0 (revision 5).
*/
public static boolean isValidNameChar(int codePoint)
{
return (isValidNameStartChar(codePoint) ||
codePoint == '-' || codePoint == '.' ||
(codePoint >= '0' && codePoint <= '9') ||
codePoint == 0xB7 ||
(codePoint >= 0x300 && codePoint <= 0x36F) ||
(codePoint >= 0x203F && codePoint <= 0x2040));
}
/**
* Returns true if text is a valid name for element name or
* attribute name in XML 1.1 or XML 1.0 (revision 5)
*/
public static boolean isValidXMLName(String text)
{
if (text == null || text.length() == 0)
{
return false;
}
for (int offset = 0; offset < text.length();)
{
int codePoint = text.codePointAt(offset);
if (offset == 0)
{
if (!XMLNameValidator.isValidNameStartChar(codePoint))
{
return false;
}
}
else
{
if (!XMLNameValidator.isValidNameChar(codePoint))
{
return false;
}
}
offset += Character.charCount(codePoint);
}
return true;
}
/**
* Returns true if text can be used as a Ganymede object type or
* field name.
*
* Ganymede names differ from XML names in that underscores are not
* allowed (because they are used as the representation of spaces),
* and spaces are, after the first character in the name.
*
* We're also not going to permit colons to avoid confusion about
* XML namespaces.
*/
public static boolean isValidGanymedeName(String text)
{
if (text == null || text.length() == 0)
{
return false;
}
for (int offset = 0; offset < text.length();)
{
int codePoint = text.codePointAt(offset);
if (offset == 0)
{
if (codePoint == ' ' || codePoint == '_' || codePoint == ':')
{
return false;
}
if (!XMLNameValidator.isValidNameStartChar(codePoint))
{
return false;
}
}
else
{
if (codePoint == '_' || codePoint == ':')
{
return false;
}
if (codePoint != ' ' && !XMLNameValidator.isValidNameChar(codePoint))
{
return false;
}
}
offset += Character.charCount(codePoint);
}
// XML names that begin with xml are reserved, so we don't want to
// allow Ganymede names to start that way.
if (text.startsWith("xml"))
{
return false;
}
return true;
}
}