in jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/conversion/NameParser.java [53:196]
public static Name parse(String jcrName, NamespaceResolver resolver, NameFactory factory)
throws IllegalNameException, NamespaceException {
if (jcrName == null) {
complainAndThrow("name is null", "");
}
int len = jcrName.length();
if (len == 0) {
complainAndThrow("empty name", jcrName);
}
if (".".equals(jcrName) || "..".equals(jcrName)) {
complainAndThrow("illegal name", jcrName);
}
// parse the name
String prefix = "";
String uri = null;
int nameStart = 0;
int state = STATE_PREFIX_START;
boolean trailingSpaces = false;
boolean checkFormat = (resolver == null);
for (int i = 0; i < len; i++) {
char c = jcrName.charAt(i);
if (c == ':') {
if (state == STATE_PREFIX_START) {
complainAndThrow("Prefix must not be empty", jcrName, i);
} else if (state == STATE_PREFIX) {
if (trailingSpaces) {
complainAndThrow("Trailing spaces not allowed", jcrName, i);
}
prefix = jcrName.substring(0, i);
if (!XMLChar.isValidNCName(prefix)) {
complainAndThrow("Invalid name prefix: " + prefix, jcrName, i);
}
state = STATE_NAME_START;
} else if (state == STATE_URI) {
// ignore -> validation of uri later on.
} else {
complainAndThrow("'" + asDisplayableString(c) + "' not allowed in name", jcrName, i);
}
trailingSpaces = false;
} else if (c == ' ') {
if (state == STATE_PREFIX_START || state == STATE_NAME_START) {
complainAndThrow("'" + asDisplayableString(c) + "' not valid name start", jcrName, i);
}
trailingSpaces = true;
} else if (c == '[' || c == ']' || c == '*' || c == '|') {
complainAndThrow("'" + asDisplayableString(c) + "' not allowed in name", jcrName, i);
} else if (Character.isWhitespace(c) && c < 128) {
complainAndThrow("Whitespace character '" + asDisplayableString(c) + "' not allowed in name", jcrName, i);
} else if (c == '/') {
if (state == STATE_URI_START) {
state = STATE_URI;
} else if (state != STATE_URI) {
complainAndThrow("'" + asDisplayableString(c) + "' not allowed in name", jcrName, i);
}
trailingSpaces = false;
} else if (c == '{') {
if (state == STATE_PREFIX_START) {
state = STATE_URI_START;
} else if (state == STATE_URI_START || state == STATE_URI) {
// second '{' in the uri-part -> no valid expanded jcr-name.
// therefore reset the nameStart and change state.
state = STATE_NAME;
nameStart = 0;
} else if (state == STATE_NAME_START) {
state = STATE_NAME;
nameStart = i;
}
trailingSpaces = false;
} else if (c == '}') {
if (state == STATE_URI_START || state == STATE_URI) {
String tmp = jcrName.substring(1, i);
if (tmp.length() == 0 || tmp.indexOf(':') != -1) {
// The leading "{...}" part is empty or contains
// a colon, so we treat it as a valid namespace URI.
// More detailed validity checks (is it well formed,
// registered, etc.) are not needed here.
uri = tmp;
state = STATE_NAME_START;
} else if (tmp.equals("internal")) {
// As a special Jackrabbit backwards compatibility
// feature, support {internal} as a valid URI prefix
uri = tmp;
state = STATE_NAME_START;
} else if (tmp.indexOf('/') == -1) {
// The leading "{...}" contains neither a colon nor
// a slash, so we can interpret it as a a part of a
// normal local name.
state = STATE_NAME;
nameStart = 0;
} else {
complainAndThrow("The URI prefix is neither a valid URI nor a valid part of a local name", jcrName);
}
} else if (state == STATE_PREFIX_START) {
state = STATE_PREFIX; // prefix start -> validation later on will fail.
} else if (state == STATE_NAME_START) {
state = STATE_NAME;
nameStart = i;
}
trailingSpaces = false;
} else {
if (state == STATE_PREFIX_START) {
state = STATE_PREFIX; // prefix start
} else if (state == STATE_NAME_START) {
state = STATE_NAME;
nameStart = i;
} else if (state == STATE_URI_START) {
state = STATE_URI;
}
trailingSpaces = false;
}
}
// take care of qualified jcrNames starting with '{' that are not having
// a terminating '}' -> make sure there are no illegal characters present.
if (state == STATE_URI && (jcrName.indexOf(':') > -1 || jcrName.indexOf('/') > -1)) {
complainAndThrow("Local name may not contain ':' nor '/'", jcrName);
}
if (nameStart == len || state == STATE_NAME_START) {
complainAndThrow("Local name must not be empty", jcrName);
}
if (trailingSpaces) {
complainAndThrow("Trailing spaces not allowed", jcrName);
}
// if namespace is null, this is just a check for format. this can only
// happen if invoked internally
if (checkFormat) {
return null;
}
// resolve prefix to uri
if (uri == null) {
uri = resolver.getURI(prefix);
}
String localName = (nameStart == 0 ? jcrName : jcrName.substring(nameStart, len));
return factory.create(uri, localName);
}