public static void parseXPointer()

in src/main/java/org/apache/maven/xinclude/stax/XPointerParser.java [44:156]


    public static void parseXPointer(String xpointerString, XPointer xpointer) throws InvalidXPointerException {

        final Tokens tokens = new Tokens(); // tokens

        // scan the XPointer expression
        int length = xpointerString.length();
        boolean success = Scanner.scanExpr(tokens, xpointerString, 0, length);

        if (!success) {
            throw new InvalidXPointerException("Invalid XPointer expression", xpointerString);
        }

        while (tokens.hasMore()) {
            int token = tokens.nextToken();

            switch (token) {
                case Tokens.XPTRTOKEN_SHORTHAND: {

                    // The shorthand name
                    token = tokens.nextToken();
                    String shortHandPointerName = tokens.getTokenString(token);

                    if (shortHandPointerName == null) {
                        throw new InvalidXPointerException("Invalid Shorthand XPointer", xpointerString);
                    }
                    if (!NCName.isValid(shortHandPointerName)) {
                        throw new InvalidXPointerException(
                                "Shorthand XPointer is not a valid NCName: " + shortHandPointerName, xpointerString);
                    }

                    xpointer.setShorthandPointer(shortHandPointerName);
                    break;
                }
                case Tokens.XPTRTOKEN_SCHEMENAME: {

                    // Retrieve the local name and prefix to form the scheme name
                    token = tokens.nextToken();
                    String prefix = tokens.getTokenString(token);
                    token = tokens.nextToken();
                    String localName = tokens.getTokenString(token);

                    String schemeName = prefix + localName;

                    // The next character should be an open parenthesis
                    int openParenCount = 0;
                    int closeParenCount = 0;

                    token = tokens.nextToken();
                    String openParen = tokens.getTokenString(token);
                    if (!Objects.equals(openParen, "XPTRTOKEN_OPEN_PAREN")) {

                        // can not have more than one ShortHand Pointer
                        if (token == Tokens.XPTRTOKEN_SHORTHAND) {
                            throw new InvalidXPointerException("Multiple Shorthand pointers", xpointerString);
                        } else {
                            throw new InvalidXPointerException("Invalid XPointer expression", xpointerString);
                        }
                    }
                    openParenCount++;

                    // followed by zero or more ( and  the schemeData
                    String schemeData = null;
                    while (tokens.hasMore()) {
                        token = tokens.nextToken();
                        schemeData = tokens.getTokenString(token);
                        if (!Objects.equals(schemeData, "XPTRTOKEN_OPEN_PAREN")) {
                            break;
                        }
                        openParenCount++;
                    }
                    token = tokens.nextToken();
                    schemeData = tokens.getTokenString(token);

                    // followed by the same number of )
                    if (tokens.hasMore()) {
                        token = tokens.nextToken();
                        String closeParen = tokens.getTokenString(token);
                        if (!Objects.equals(closeParen, "XPTRTOKEN_CLOSE_PAREN")) {
                            throw new InvalidXPointerException(
                                    "SchemeData not followed by close parenthesis", xpointerString);
                        }
                    } else {
                        throw new InvalidXPointerException(
                                "SchemeData not followed by close parenthesis", xpointerString);
                    }

                    closeParenCount++;

                    while (tokens.hasMore()) {
                        if (!Objects.equals(tokens.getTokenString(tokens.peekToken()), "XPTRTOKEN_OPEN_PAREN")) {
                            break;
                        }
                        closeParenCount++;
                    }

                    // check if the number of open parenthesis are equal to the number of close parenthesis
                    if (openParenCount != closeParenCount) {
                        throw new InvalidXPointerException(
                                "Unbalanced parenthesis in XPointer expression", xpointerString);
                    }

                    // Perform scheme specific parsing of the pointer part, make this more generic for any pointer part?
                    if (schemeName.equals(ELEMENT_SCHEME_NAME)) {
                        PointerPart elementSchemePointer = ElementPointerPart.parseFromString(schemeData);
                        xpointer.addPointerPart(elementSchemePointer);
                    } // Else an unknown scheme.
                    break;
                }
                default:
                    throw new InvalidXPointerException("Invalid XPointer expression", xpointerString);
            }
        }
    }