private static Patterns processMatchExpression()

in src/main/software/amazon/event/ruler/JsonRuleCompiler.java [354:516]


    private static Patterns processMatchExpression(final JsonParser parser) throws IOException {
        final JsonToken matchTypeToken = parser.nextToken();
        if (matchTypeToken != JsonToken.FIELD_NAME) {
            barf(parser, "Match expression name not found");
        }
        final String matchTypeName = parser.getCurrentName();
        if (Constants.EXACT_MATCH.equals(matchTypeName)) {
            final JsonToken prefixToken = parser.nextToken();
            if (prefixToken != JsonToken.VALUE_STRING) {
                barf(parser, "exact match pattern must be a string");
            }
            final Patterns pattern = Patterns.exactMatch('"' + parser.getText() + '"');
            if (parser.nextToken() != JsonToken.END_OBJECT) {
                barf(parser, "Only one key allowed in match expression");
            }
            return pattern;
        } else if (Constants.PREFIX_MATCH.equals(matchTypeName)) {
            final JsonToken prefixToken = parser.nextToken();
            if (prefixToken == JsonToken.START_OBJECT) {
                return processPrefixEqualsIgnoreCaseExpression(parser);
            }

            if (prefixToken != JsonToken.VALUE_STRING) {
                barf(parser, "prefix match pattern must be a string");
            }
            final Patterns pattern = Patterns.prefixMatch('"' + parser.getText()); // note no trailing quote
            if (parser.nextToken() != JsonToken.END_OBJECT) {
                barf(parser, "Only one key allowed in match expression");
            }
            return pattern;
        } else if (Constants.SUFFIX_MATCH.equals(matchTypeName)) {
            final JsonToken suffixToken = parser.nextToken();
            if (suffixToken == JsonToken.START_OBJECT) {
                return processSuffixEqualsIgnoreCaseExpression(parser);
            }

            if (suffixToken != JsonToken.VALUE_STRING) {
                barf(parser, "suffix match pattern must be a string");
            }
            final Patterns pattern = Patterns.suffixMatch(parser.getText() + '"'); // note no beginning quote
            if (parser.nextToken() != JsonToken.END_OBJECT) {
                barf(parser, "Only one key allowed in match expression");
            }
            return pattern;
        } else if (Constants.NUMERIC.equals(matchTypeName)) {
            final JsonToken numericalExpressionToken = parser.nextToken();
            if (numericalExpressionToken != JsonToken.START_ARRAY) {
                barf(parser, "Value of " + Constants.NUMERIC + " must be an array.");
            }
            Patterns range = processNumericMatchExpression(parser);
            if (parser.nextToken() != JsonToken.END_OBJECT) {
                tooManyElements(parser);
            }
            return range;
        } else if (Constants.ANYTHING_BUT_MATCH.equals(matchTypeName)) {

            MatchType matchType = MatchType.ANYTHING_BUT;
            JsonToken anythingButExpressionToken = parser.nextToken();
            if (anythingButExpressionToken == JsonToken.START_OBJECT) {

                // there are a limited set of things we can apply Anything-But to
                final JsonToken anythingButObject = parser.nextToken();
                if (anythingButObject != JsonToken.FIELD_NAME) {
                    barf(parser, "Anything-But expression name not found");
                }
                final String anythingButObjectOp = parser.getCurrentName();
                switch (anythingButObjectOp) {
                    case Constants.EQUALS_IGNORE_CASE:
                        matchType = MatchType.ANYTHING_BUT_IGNORE_CASE;
                        break;
                    case Constants.PREFIX_MATCH:
                        matchType = MatchType.ANYTHING_BUT_PREFIX;
                        break;
                    case Constants.SUFFIX_MATCH:
                        matchType = MatchType.ANYTHING_BUT_SUFFIX;
                        break;
                    case Constants.WILDCARD:
                        matchType = MatchType.ANYTHING_BUT_WILDCARD;
                        break;
                    default:
                        barf(parser, "Unsupported anything-but pattern: " + anythingButObjectOp);
                }

                // Step into anything-but's equals-ignore-case/prefix/suffix/wildcard
                anythingButExpressionToken = parser.nextToken();
            }

            if (anythingButExpressionToken != JsonToken.START_ARRAY &&
                    anythingButExpressionToken != JsonToken.VALUE_STRING &&
                    anythingButExpressionToken != JsonToken.VALUE_NUMBER_FLOAT &&
                    anythingButExpressionToken != JsonToken.VALUE_NUMBER_INT) {
                barf(parser, "Value of " +
                        Constants.ANYTHING_BUT_MATCH + " must be an array or single string/number value.");
            }

            Patterns anythingBut;
            if (anythingButExpressionToken == JsonToken.START_ARRAY) {
                if (matchType == MatchType.ANYTHING_BUT) {
                    anythingBut = processAnythingButListMatchExpression(parser);
                } else {
                    anythingBut = processAnythingButValuesSetMatchExpression(parser, matchType);
                }
            } else {
                if (matchType == MatchType.ANYTHING_BUT) {
                    anythingBut = processAnythingButMatchExpression(parser, anythingButExpressionToken);
                } else {
                    anythingBut = processAnythingButValuesSetSingleValueMatchExpression(parser, anythingButExpressionToken, matchType);
                }
            }

            if (parser.nextToken() != JsonToken.END_OBJECT) {
                tooManyElements(parser);
            }
            // Complete the object closure when a set is present
            if (matchType != MatchType.ANYTHING_BUT && parser.nextToken() != JsonToken.END_OBJECT) {
                tooManyElements(parser);
            }

            return anythingBut;
        } else if (Constants.EXISTS_MATCH.equals(matchTypeName)) {
            return processExistsExpression(parser);
        } else if (Constants.CIDR.equals(matchTypeName)) {
            final JsonToken cidrToken = parser.nextToken();
            if (cidrToken != JsonToken.VALUE_STRING) {
                barf(parser, "prefix match pattern must be a string");
            }
            final Range cidr = CIDR.cidr(parser.getText());
            if (parser.nextToken() != JsonToken.END_OBJECT) {
                barf(parser, "Only one key allowed in match expression");
            }
            return cidr;
        } else if (Constants.EQUALS_IGNORE_CASE.equals(matchTypeName)) {
            final JsonToken equalsIgnoreCaseToken = parser.nextToken();
            if (equalsIgnoreCaseToken != JsonToken.VALUE_STRING) {
                barf(parser, "equals-ignore-case match pattern must be a string");
            }
            final Patterns pattern = Patterns.equalsIgnoreCaseMatch('"' + parser.getText() + '"');
            if (parser.nextToken() != JsonToken.END_OBJECT) {
                barf(parser, "Only one key allowed in match expression");
            }
            return pattern;
        } else if (Constants.WILDCARD.equals(matchTypeName)) {
            final JsonToken wildcardToken = parser.nextToken();
            if (wildcardToken != JsonToken.VALUE_STRING) {
                barf(parser, "wildcard match pattern must be a string");
            }
            final String parserText = parser.getText();
            String value = '"' + parserText + '"';
            try {
                getParser().parse(MatchType.WILDCARD, value);
            } catch (ParseException e) {
                barf(parser, e.getLocalizedMessage());
            }
            final Patterns pattern = Patterns.wildcardMatch(value);
            if (parser.nextToken() != JsonToken.END_OBJECT) {
                barf(parser, "Only one key allowed in match expression");
            }
            return pattern;
        } else {
            barf(parser, "Unrecognized match type " + matchTypeName);
            return null; // unreachable statement, but java can't see that?
        }
    }