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

software.amazon.smithy.linters.ReservedWordsValidator Maven / Gradle / Ivy

/*
 * Copyright 2019 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.linters;

import static java.lang.String.format;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import software.amazon.smithy.model.Model;
import software.amazon.smithy.model.node.NodeMapper;
import software.amazon.smithy.model.selector.Selector;
import software.amazon.smithy.model.shapes.MemberShape;
import software.amazon.smithy.model.shapes.Shape;
import software.amazon.smithy.model.validation.AbstractValidator;
import software.amazon.smithy.model.validation.Severity;
import software.amazon.smithy.model.validation.ValidationEvent;
import software.amazon.smithy.model.validation.ValidatorService;

/**
 * Emits validation events for a configuration of reserved words.
 *
 * 

This validator accepts the following optional configuration options: * *

    *
  • reserved: ([object]) A list of reserved word configuration * objects as follows: *
      *
    • words: ([string]) A list of words that are * case-insensitively reserved. Leading and trailing wildcards * ("*") are supported. *
    • terms: ([string]) A list of word boundary terms to test.
    • *
    • selector: (string) Specifies a selector for this * configuration. Defaults to validating all shapes, including * member names. *
    • reason: (string) A reason to display for why this set of * words is reserved. *
    *
  • *
*/ public final class ReservedWordsValidator extends AbstractValidator { /** * ReservedWords validator configuration. */ public static final class Config { private List reserved = Collections.emptyList(); public List getReserved() { return reserved; } /** * Sets the reserved words to validate. * * @param reserved Reserved words to set. */ public void setReserved(List reserved) { this.reserved = reserved; } } /** * A single reserved words configuration. */ public static final class ReservedWords { private Selector selector = Selector.IDENTITY; private String reason = ""; private final WildcardMatcher wildcardMatcher = new WildcardMatcher(); private final WordBoundaryMatcher wordMatcher = new WordBoundaryMatcher(); /** * Sets the list of reserved word definitions. * *

Each word must be a valid word. The word cannot equal "*", and if present, * "*", must appear at the start or end of the word. * * @param words Words to set. */ public void setWords(List words) { words.forEach(wildcardMatcher::addSearch); } /** * Sets the list of reserved word terms to match based on word boundaries. * * @param terms Terms to set. */ public void setTerms(List terms) { terms.forEach(wordMatcher::addSearch); } /** * Sets the selector to use for determining which shapes to validate. * * @param selector Selector to set. */ public void setSelector(Selector selector) { this.selector = selector; } /** * Sets the reason for why the words are reserved. * * @param reason Reason to set. */ public void setReason(String reason) { this.reason = reason; } private void validate(Model model, List events) { for (Shape shape : selector.select(model)) { validateShape(shape).ifPresent(events::add); } } private Optional validateShape(Shape shape) { String name = shape.asMemberShape() .map(MemberShape::getMemberName) .orElseGet(() -> shape.getId().getName()); return isReservedWord(name) ? Optional.of(emit(shape, name, reason)) : Optional.empty(); } /** * Checks a passed word against the reserved words in this configuration. * * @param word A value that may be reserved. * @return Returns true if the word is reserved by this configuration */ private boolean isReservedWord(String word) { return wildcardMatcher.test(word) || wordMatcher.test(word); } private ValidationEvent emit(Shape shape, String word, String reason) { return ValidationEvent.builder() .severity(Severity.DANGER) .id(ValidatorService.determineValidatorName(ReservedWordsValidator.class)) .shape(shape) .message(format("The word `%s` is reserved. %s", word, reason)) .build(); } } public static final class Provider extends ValidatorService.Provider { public Provider() { super(ReservedWordsValidator.class, node -> { NodeMapper mapper = new NodeMapper(); return new ReservedWordsValidator(mapper.deserialize(node, Config.class)); }); } } private final Config config; private ReservedWordsValidator(Config config) { this.config = config; } @Override public List validate(Model model) { List events = new ArrayList<>(); for (ReservedWords reserved : config.getReserved()) { reserved.validate(model, events); } return events; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy