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

guru.nidi.ramltester.core.RamlValidatorChecker Maven / Gradle / Ivy

/*
 * Copyright (C) 2014 Stefan Niederhauser ([email protected])
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License 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 guru.nidi.ramltester.core;

import guru.nidi.ramltester.util.MediaType;
import guru.nidi.ramltester.util.Message;
import org.raml.model.*;
import org.raml.model.parameter.AbstractParam;

import java.util.*;
import java.util.regex.Pattern;

import static guru.nidi.ramltester.core.CheckerHelper.*;

/**
 *
 */
class RamlValidatorChecker {

    private static final String PARAM_CONDITION_ILLEGAL = "parameter.condition.illegal";

    enum ParamName {
        BASE_URI("baseUriParameter"),
        URI("uriParameter"),
        QUERY("queryParameter"),
        HEADER("header"),
        FORM("formParameter");
        private final String value;

        ParamName(String value) {
            this.value = value;
        }

        @Override
        public String toString() {
            return value;
        }
    }

    private final Raml raml;
    private final Locator locator;
    private final Pattern resourcePattern;
    private final Pattern parameterPattern;
    private final Pattern headerPattern;
    private final List schemaValidators;
    private final EnumSet validations;
    private final RamlReport report;
    private final RamlViolations violations;

    public RamlValidatorChecker(Raml raml, List schemaValidators) {
        this(raml, new Locator(), schemaValidators, EnumSet.allOf(Validation.class), null, null, null);
    }

    public RamlValidatorChecker(Raml raml, Locator locator, List schemaValidators, EnumSet validations, Pattern resourcePattern, Pattern parameterPattern, Pattern headerPattern) {
        this.raml = raml;
        this.locator = locator;
        this.resourcePattern = resourcePattern;
        this.parameterPattern = parameterPattern;
        this.headerPattern = headerPattern;
        this.schemaValidators = schemaValidators;
        this.validations = validations;
        this.report = new RamlReport(raml);
        this.violations = report.getValidationViolations();
    }

    public RamlValidatorChecker withChecks(Validation... validations) {
        final EnumSet validationSet = validations.length == 0 ? EnumSet.noneOf(Validation.class) : EnumSet.copyOf(Arrays.asList(validations));
        return new RamlValidatorChecker(raml, locator, schemaValidators, validationSet, headerPattern, parameterPattern, resourcePattern);
    }

    public RamlValidatorChecker withResourcePattern(String regex) {
        return new RamlValidatorChecker(raml, locator, schemaValidators, validations, regex == null ? null : Pattern.compile(regex), parameterPattern, headerPattern);
    }

    public RamlValidatorChecker withParameterPattern(String regex) {
        return new RamlValidatorChecker(raml, locator, schemaValidators, validations, resourcePattern, regex == null ? null : Pattern.compile(regex), headerPattern);
    }

    public RamlValidatorChecker withHeaderPattern(String regex) {
        return new RamlValidatorChecker(raml, locator, schemaValidators, validations, resourcePattern, parameterPattern, regex == null ? null : Pattern.compile(regex));
    }

    public Locator getLocator() {
        return locator;
    }

    public RamlReport getReport() {
        return report;
    }

    private boolean has(Validation validation) {
        return validations.contains(validation);
    }

    private void violation(String key, Object... params) {
        violations.add(new Message(key, params));
    }

    public void description(Map params, ParamName paramName) {
        if (has(Validation.DESCRIPTION)) {
            for (final Map.Entry param : paramEntries(params)) {
                description(param.getKey(), param.getValue(), paramName);
            }
        }
    }

    private void description(String name, AbstractParam param, ParamName paramName) {
        if (isNullOrEmpty(param.getDescription())) {
            violation("parameter.description.missing", locator, name, paramName);
        }
    }

    public void description(String desc) {
        if (has(Validation.DESCRIPTION)) {
            if (isNullOrEmpty(desc)) {
                violation("description.missing", locator);
            }
        }
    }

    public void description(List docs) {
        if (has(Validation.DESCRIPTION)) {
            if (isNullOrEmpty(docs)) {
                violation("documentation.missing", locator);
            } else {
                for (final DocumentationItem doc : docs) {
                    if (isNullOrEmpty(doc.getTitle())) {
                        violation("documentation.missing.title", locator);
                    } else if (isNullOrEmpty(doc.getContent())) {
                        violation("documentation.missing.content", locator);
                    }
                }
            }
        }
    }

    public void empty(Resource resource) {
        if (has(Validation.EMPTY)) {
            if (resource.getActions().isEmpty() && resource.getResources().isEmpty()) {
                violation("empty", locator);
            }
        }
    }

    public void empty(Action action) {
        if (has(Validation.EMPTY)) {
            if (action.getResponses().isEmpty()) {
                violation("empty", locator);
            }
        }
    }

    private void baseUriParameters(Collection names) {
        if (has(Validation.URI_PARAMETER)) {
            if (raml.getBaseUri() == null && !names.isEmpty()) {
                violation("baseUriParameters.illegal", locator);
            } else {
                for (final String name : names) {
                    if ("version".equals(name)) {
                        violation("baseUriParameter.illegal", locator, name);
                    } else if (!raml.getBaseUri().contains("{" + name + "}")) {
                        violation("baseUriParameter.invalid", locator, name);
                    }
                }
            }
        }
    }

    public void uriParameters(Collection names, Resource resource) {
        if (has(Validation.URI_PARAMETER)) {
            for (final String name : names) {
                if ("version".equals(name)) {
                    violation("uriParameter.illegal", locator, name);
                } else if (!resource.getUri().contains("{" + name + "}")) {
                    violation("uriParameter.invalid", locator, name);
                }
            }
        }
    }

    public void resourcePattern(Resource resource) {
        if (resourcePattern != null) {
            final String uri = resource.getRelativeUri().replaceAll("\\{[^}/]+\\}", "");
            for (final String part : uri.split("/")) {
                if (part != null && part.length() > 0 && !resourcePattern.matcher(part).matches()) {
                    violation("resource.name.invalid", locator, resourcePattern.pattern());
                }
            }
        }
    }

    public void parameters(Map params, ParamName paramName) {
        if (paramName == ParamName.BASE_URI) {
            baseUriParameters(params.keySet());
        }
        if (parameterPattern != null) {
            for (final String name : params.keySet()) {
                if (!parameterPattern.matcher(name).matches()) {
                    violation("parameter.name.invalid", locator, name, paramName, parameterPattern.pattern());
                }
            }
        }
        if (has(Validation.PARAMETER)) {
            parameterDef(params, paramName);
        }
        if (has(Validation.EXAMPLE)) {
            final ParameterChecker checker = new ParameterChecker(violations);
            for (final Map.Entry param : paramEntries(params)) {
                parameterValues(param.getValue(), checker, new Message("parameter.condition", locator, param.getKey(), paramName));
            }
        }
    }

    public void formParameters(MimeType mimeType) {
        if (has(Validation.PARAMETER)) {
            if (!MediaType.valueOf(mimeType.getType()).isCompatibleWith(MediaType.FORM_URL_ENCODED) &&
                    !MediaType.valueOf(mimeType.getType()).isCompatibleWith(MediaType.MULTIPART)) {
                violation("formParameter.illegal", locator);
            }
        }
    }

    private void parameterDef(Map params, ParamName paramName) {
        for (final Map.Entry entry : paramEntries(params)) {
            final String name = entry.getKey();
            final AbstractParam param = entry.getValue();
            final ParamType type = param.getType() == null ? ParamType.STRING : param.getType();
            if (type == ParamType.STRING) {
                minMaxNotAllowed(param, name, paramName);
            } else {
                stringConstraintsNotAllowed(param, name, paramName);
                if (type != ParamType.INTEGER && type != ParamType.NUMBER) {
                    minMaxNotAllowed(param, name, paramName);
                }
                if (type == ParamType.FILE) {
                    violations.addIf(paramName != ParamName.FORM, new Message("parameter.file.illegal", locator, name, paramName));
                }
            }
        }
    }

    private void stringConstraintsNotAllowed(AbstractParam param, String name, ParamName paramName) {
        violations.addIf(param.getEnumeration() != null, new Message(PARAM_CONDITION_ILLEGAL, locator, name, paramName, "enum"));
        violations.addIf(param.getPattern() != null, new Message(PARAM_CONDITION_ILLEGAL, locator, name, paramName, "pattern"));
        violations.addIf(param.getMinLength() != null, new Message(PARAM_CONDITION_ILLEGAL, locator, name, paramName, "minLength"));
        violations.addIf(param.getMaxLength() != null, new Message(PARAM_CONDITION_ILLEGAL, locator, name, paramName, "maxLength"));
    }

    private void minMaxNotAllowed(AbstractParam param, String name, ParamName paramName) {
        violations.addIf(param.getMinimum() != null, new Message(PARAM_CONDITION_ILLEGAL, locator, name, paramName, "minimum"));
        violations.addIf(param.getMaximum() != null, new Message(PARAM_CONDITION_ILLEGAL, locator, name, paramName, "maximum"));
    }

    private void parameterValues(AbstractParam param, ParameterChecker checker, Message message) {
        if (param.getExample() != null) {
            checker.checkParameter(param, param.getExample(), message.withParam("example"));
        }
        if (param.getDefaultValue() != null) {
            checker.checkParameter(param, param.getDefaultValue(), message.withParam("default value"));
        }
    }

    public void headerPattern(Collection names) {
        if (headerPattern != null) {
            for (final String name : names) {
                if (!headerPattern.matcher(name).matches()) {
                    violation("header.name.invalid", locator, name, headerPattern.pattern());
                }
            }
        }
    }

    public void exampleSchema(MimeType mimeType) {
        if (has(Validation.EXAMPLE)) {
            final String schema = mimeType.getSchema();
            final String example = mimeType.getExample();
            final SchemaValidator validator = findSchemaValidator(schemaValidators, MediaType.valueOf(mimeType.getType()));
            if (schema != null && example != null && validator != null) {
                validator.validate(new NamedReader(example, new Message("example").toString()), resolveSchema(raml, schema), violations,
                        new Message("schema.example.mismatch", locator, example));
            }
        }
    }

    private boolean isNullOrEmpty(String s) {
        return s == null || s.isEmpty();
    }

    private boolean isNullOrEmpty(List s) {
        return s == null || s.isEmpty();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy