public static boolean parse()

in oak-core-spi/src/main/java/org/apache/jackrabbit/oak/namepath/JcrNameParser.java [79:192]


    public static boolean parse(String jcrName, Listener listener, int index) {
        // trivial check
        int len = jcrName == null ? 0 : jcrName.length();
        if (len == 0) {
            listener.error("Empty name.");
            return false;
        }
        if (".".equals(jcrName) || "..".equals(jcrName)) {
            listener.error("Illegal name:" + jcrName);
            return false;
        }

        // parse the name
        String prefix;
        int nameStart = 0;
        int state = STATE_PREFIX_START;

        for (int i = 0; i < len; i++) {
            char c = jcrName.charAt(i);
            if (c == ':') {
                if (state == STATE_PREFIX_START) {
                    listener.error("Prefix must not be empty.");
                    return false;
                } else if (state == STATE_PREFIX) {
                    prefix = jcrName.substring(0, i);
                    if (!XMLChar.isValidNCName(prefix)) {
                        listener.error("Invalid name prefix: "+ prefix);
                        return false;
                    }
                    state = STATE_NAME_START;
                } else if (state == STATE_URI) {
                    // ignore -> validation of uri later on.
                } else {
                    listener.error("'" + c + "' not allowed in name.");
                    return false;
                }
            } else if (c == '[' || c == ']' || c == '*' || c == '|') {
                listener.error("'" + c + "' not allowed in name.");
                return false;
            } else if (c == '/') {
                if (state == STATE_URI_START) {
                    state = STATE_URI;
                } else if (state != STATE_URI) {
                    listener.error("'" + c + "' not allowed in name.");
                    return 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;
                }
            } else if (c == '}') {
                if (state == STATE_URI_START || state == STATE_URI) {
                    String tmp = jcrName.substring(1, i);
                    if (tmp.isEmpty() || 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.
                        state = STATE_NAME_START;
                    } else if (tmp.equals("internal")) {
                        // As a special Jackrabbit backwards compatibility
                        // feature, support {internal} as a valid URI prefix
                        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 {
                        listener.error("The URI prefix of the name " + jcrName + " is " +
                                "neither a valid URI nor a valid part of a local name.");
                        return false;
                    }
                } 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;
                }
            } 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;
                }
            }
        }

        // 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)) {
            listener.error("Local name may not contain ':' nor '/'.");
            return false;
        }

        if (nameStart == len || state == STATE_NAME_START) {
            listener.error("Local name must not be empty.");
            return false;
        }

        return listener.name(jcrName, index);
    }