Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[core] Initial implementation of a validation framework in core #3183

Merged
merged 5 commits into from
Jun 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions modules/openapi-generator-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,11 @@
<artifactId>openapi-generator-core</artifactId>
<name>openapi-generator-core</name>
<url>https://github.com/openapitools/openapi-generator</url>
<dependencies>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright 2019 OpenAPI-Generator Contributors (https://openapi-generator.tech)
*
* 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 org.openapitools.codegen.validation;

import java.util.List;

/**
* A generic implementation of a validator instance which simply applies rules to an input instance.
*
* @param <TInput> The type of object being evaluated.
*/
@SuppressWarnings({"WeakerAccess"})
public class GenericValidator<TInput> implements Validator<TInput> {
private List<ValidationRule> rules;

/**
* Constructs a new instance of {@link GenericValidator}.
*
* @param rules The rules to be evaluated during validation.
*/
public GenericValidator(List<ValidationRule> rules) {
this.rules = rules;
}

/**
* Validates input, resulting in a instance of {@link ValidationResult} which provides details on all validations performed (success, error, warning).
*
* @param input The object instance to be validated.
*
* @return A {@link ValidationResult} which details the success, error, and warning validation results.
*/
@Override
public ValidationResult validate(TInput input) {
ValidationResult result = new ValidationResult();
if (rules != null) {
rules.forEach(it -> {
boolean passes = it.evaluate(input);
if (passes) {
result.addResult(Validated.valid(it));
} else {
result.addResult(Validated.invalid(it, it.getFailureMessage()));
}
});
}
return result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Copyright 2019 OpenAPI-Generator Contributors (https://openapi-generator.tech)
*
* 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 org.openapitools.codegen.validation;

/**
* Represents a {@link Validated} state which is "Invalid" to some degree of {@link Severity}.
*/
@SuppressWarnings({"WeakerAccess"})
public final class Invalid extends Validated {
private String message;
private ValidationRule rule;

/**
* Constructs a new {@link Invalid} instance.
*
* @param rule The rule which was evaluated and resulted in this state.
* @param message The message to be displayed for this invalid state.
*/
Invalid(ValidationRule rule, String message) {
this.rule = rule;
this.message = message;
}

@Override
String getMessage() {
return message;
}

@Override
ValidationRule getRule() {
return rule;
}

/**
* Get details about the severity of this invalid state.
* For instance, is this an {@link Severity#ERROR} or simply a {@link Severity#WARNING}.
*
* @return The {@link Severity} enum detailing this state's severity.
*/
public Severity getSeverity() {
return rule.getSeverity();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright 2019 OpenAPI-Generator Contributors (https://openapi-generator.tech)
*
* 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 org.openapitools.codegen.validation;

/**
* Defines different levels of severity to be used during validation.
*/
public enum Severity {
/**
* Lower severity indicating that the target state may be unpredictable, no longer supported, or known to have issues.
* Marking a type with this value should not result in application exceptions under normal operating circumstances.
*/
WARNING,
/**
* Higher severity indicating that the target state is not supported, or is known to cause problems with the application.
* Marking a type with this value should result in an application exception or error exit code under normal operating circumstances.
*/
ERROR
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright 2019 OpenAPI-Generator Contributors (https://openapi-generator.tech)
*
* 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 org.openapitools.codegen.validation;

/**
* Represents a {@link Validated} state which is "valid" according to the defined rule.
*/
public final class Valid extends Validated {
private ValidationRule rule;

/**
* Defines whether or not the validation resulted in a "valid" condition.
*
* @return <code>true</code> if the instance passed validation of the rule returned by {@link Validated#getRule()}.
*/
@Override
boolean isValid() {
return true;
}

/**
* Constructs a new {@link Valid} instance.
*
* @param rule The rule which was evaluated and resulted in this state.
*/
Valid(ValidationRule rule) {
this.rule = rule;
}

@Override
public String getMessage() {
return null;
}

@Override
public ValidationRule getRule() {
return rule;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright 2019 OpenAPI-Generator Contributors (https://openapi-generator.tech)
*
* 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 org.openapitools.codegen.validation;

/**
* Provides details about the state of a completed validation.
*/
public abstract class Validated {
/**
* Defines whether or not the validation resulted in a "valid" condition.
*
* @return <code>true</code> if the instance passed validation of the rule returned by {@link Validated#getRule()}.
*/
boolean isValid() {
return false;
}

/**
* Gets the rule which was evaluated and resulted in this state.
*
* @return The instance of {@link ValidationRule} which was evaluated.
*/
abstract ValidationRule getRule();

/**
* Gets the message with details about this validated state.
*
* @return A string intended to be displayed to a user.
*/
abstract String getMessage();

/**
* Creates an instance of an {@link Invalid} validation state.
*
* @param rule The rule which was evaluated.
* @param message The message to display to a user.
*
* @return A {@link Validated} instance representing an invalid state according to the rule.
*/
public static Validated invalid(ValidationRule rule, String message) {
return new Invalid(rule, message);
}

/**
* Creates an instance of an {@link Valid} validation state.
*
* @param rule The rule which was evaluated.
*
* @return A {@link Validated} instance representing a valid state according to the rule.
*/
public static Validated valid(ValidationRule rule) {
return new Valid(rule);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/*
* Copyright 2019 OpenAPI-Generator Contributors (https://openapi-generator.tech)
*
* 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 org.openapitools.codegen.validation;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
* Encapsulates details about the result of a validation test.
*/
@SuppressWarnings("WeakerAccess")
public final class ValidationResult {
private final List<Validated> validations;

/**
* Constructs a new {@link ValidationResult} instance, backed by the provided validations (useful for testing).
*
* @param validations A pre-defined set of validations to begin with.
*/
private ValidationResult(List<Validated> validations) {
this.validations = Collections.synchronizedList(validations);
}

/**
* Constructs a new {@link ValidationResult} instance.
*/
public ValidationResult() {
this(new ArrayList<>());
}

/**
* Gets all the validated states resulting from the evaluation. This includes all {@link Valid} and {@link Invalid} instances.
*
* @return All validated results.
*/
public List<Validated> getAll() {
return validations;
}

/**
* Gets a filtered list of {@link Valid} states.
*
* @return A list containing only {@link Valid} states.
*/
public List<Valid> getValid(){
return validations.stream().filter(Validated::isValid).map(it -> (Valid)it).collect(Collectors.toList());
}

/**
* Gets a filters list of {@link Invalid} states with the level of {@link Severity#ERROR}
*
* @return A list of all validation errors.
*/
public List<Invalid> getErrors(){
return validations.stream()
.filter(it -> !it.isValid())
.map(it -> (Invalid)it)
.filter(it -> it.getSeverity().equals(Severity.ERROR))
.collect(Collectors.toList());
}

/**
* Gets a filtered list of {@link Invalid} states with the level of {@link Severity#WARNING}
*
* @return A list of all validation warnings.
*/
public List<Invalid> getWarnings(){
return validations.stream()
.filter(it -> !it.isValid())
.map(it -> (Invalid)it)
.filter(it -> it.getSeverity().equals(Severity.WARNING))
.collect(Collectors.toList());
}

/**
* Adds a validation state to the final results.
*
* @param validated The {@link Valid} or {@link Invalid} instance to add to validations.
*/
public void addResult(Validated validated) {
synchronized (validations) {
ValidationRule rule = validated.getRule();
if (rule != null && !rule.equals(ValidationRule.empty())) {
validations.add(validated);
}
}
}
}
Loading