All Downloads are FREE. Search and download functionalities are using the official Maven repository.

software.amazon.smithy.model.selector.ScopedAttributeSelector Maven / Gradle / Ivy

/*
 * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 *
 *  http://aws.amazon.com/apache2.0
 *
 * or in the "license" file accompanying this file. This file is distributed
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

package software.amazon.smithy.model.selector;

import java.util.List;
import java.util.Map;
import java.util.Set;
import software.amazon.smithy.model.shapes.Shape;

/**
 * Matches a scoped attribute or projection against a set of assertions that
 * can path into the scoped attribute.
 */
final class ScopedAttributeSelector implements InternalSelector {

    static final class Assertion {
        private final ScopedFactory lhs;
        private final AttributeComparator comparator;
        private final List rhs;
        private final boolean caseInsensitive;

        Assertion(
                ScopedFactory lhs,
                AttributeComparator comparator,
                List rhs,
                boolean caseInsensitive
        ) {
            this.lhs = lhs;
            this.comparator = comparator;
            this.rhs = rhs;
            this.caseInsensitive = caseInsensitive;
        }
    }

    /**
     * Creates an AttributeValue from the given scope value.
     *
     * 

This is useful for pathing into scopes. */ @FunctionalInterface interface ScopedFactory { AttributeValue create(AttributeValue value); } private final List path; private final List assertions; ScopedAttributeSelector(List path, List assertions) { this.path = path; this.assertions = assertions; } @Override public Response push(Context context, Shape shape, Receiver next) { if (matchesAssertions(shape, context.getVars())) { return next.apply(context, shape); } else { return Response.CONTINUE; } } private boolean matchesAssertions(Shape shape, Map> vars) { // First resolve the scope of the assertions. AttributeValue scope = AttributeValue.shape(shape, vars).getPath(path); // If it's not present, then nothing could ever match. if (!scope.isPresent()) { return false; } // When dealing with a projection, each flattened projection value is // used as a scope and then passed to the assertions one at a time. for (AttributeValue value : scope.getFlattenedValues()) { if (compareWithScope(value)) { return true; } } return false; } private boolean compareWithScope(AttributeValue scope) { // Ensure that each assertion matches, and provide them the scope. for (Assertion assertion : assertions) { AttributeValue lhs = assertion.lhs.create(scope); boolean matchedOneRhs = false; for (ScopedFactory factory : assertion.rhs) { AttributeValue rhs = factory.create(scope); if (assertion.comparator.compare(lhs, rhs, assertion.caseInsensitive)) { matchedOneRhs = true; break; } } if (!matchedOneRhs) { return false; } } return true; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy