public static Name parse()

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);
    }