Skip to content

Commit

Permalink
Merge pull request #311 from Buuhuu/master
Browse files Browse the repository at this point in the history
Split the PatternValidator into 2 classes.
  • Loading branch information
stevehu authored Jun 27, 2020
2 parents b717e50 + 0fdee4a commit 5cceac7
Showing 1 changed file with 107 additions and 50 deletions.
157 changes: 107 additions & 50 deletions src/main/java/com/networknt/schema/PatternValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@

package com.networknt.schema;

import com.fasterxml.jackson.databind.JsonNode;
import java.util.Collections;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

import org.jcodings.specific.UTF8Encoding;
import org.joni.Option;
import org.joni.Regex;
Expand All @@ -25,78 +29,131 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collections;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import com.fasterxml.jackson.databind.JsonNode;

public class PatternValidator extends BaseJsonValidator implements JsonValidator {
private static final Logger logger = LoggerFactory.getLogger(PatternValidator.class);
public class PatternValidator implements JsonValidator {

private String pattern;
private Pattern compiledPattern;
private Regex compiledRegex;
private final JsonValidator delegate;

public PatternValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentSchema, ValidationContext validationContext) {
if (validationContext.getConfig() != null && validationContext.getConfig().isEcma262Validator()) {
delegate = new PatternValidatorEcma262(schemaPath, schemaNode, parentSchema, validationContext);
} else {
delegate = new PatternValidatorJava(schemaPath, schemaNode, parentSchema, validationContext);
}
}

@Override
public Set<ValidationMessage> validate(JsonNode rootNode) {
return delegate.validate(rootNode);
}

@Override
public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String at) {
return delegate.validate(node, rootNode, at);
}

private static class PatternValidatorJava extends BaseJsonValidator implements JsonValidator {
private static final Logger logger = LoggerFactory.getLogger(PatternValidator.class);

private String pattern;
private Pattern compiledPattern;

public PatternValidatorJava(String schemaPath, JsonNode schemaNode, JsonSchema parentSchema, ValidationContext validationContext) {

super(schemaPath, schemaNode, parentSchema, ValidatorTypeCode.PATTERN, validationContext);
pattern = "";
if (schemaNode != null && schemaNode.isTextual()) {
pattern = schemaNode.textValue();
try {
compiledPattern = Pattern.compile(pattern);
} catch (PatternSyntaxException pse) {
logger.error("Failed to compile pattern : Invalid syntax [" + pattern + "]", pse);
throw pse;
}
}

parseErrorCode(getValidatorType().getErrorCodeKey());
}

private boolean matches(String value) {
return compiledPattern == null || compiledPattern.matcher(value).find();
}

public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String at) {
debug(logger, node, rootNode, at);

JsonType nodeType = TypeFactory.getValueNodeType(node);
if (nodeType != JsonType.STRING) {
return Collections.emptySet();
}

super(schemaPath, schemaNode, parentSchema, ValidatorTypeCode.PATTERN, validationContext);
pattern = "";
if (schemaNode != null && schemaNode.isTextual()) {
pattern = schemaNode.textValue();
try {
compileRegexPattern(pattern, validationContext.getConfig() != null && validationContext.getConfig().isEcma262Validator());
if (!matches(node.asText())) {
return Collections.singleton(buildValidationMessage(at, pattern));
}
} catch (PatternSyntaxException pse) {
logger.error("Failed to compile pattern : Invalid syntax [" + pattern + "]", pse);
throw pse;
} catch (SyntaxException se) {
logger.error("Failed to compile pattern : Invalid syntax [" + pattern + "]", se);
throw se;
logger.error("Failed to apply pattern on " + at + ": Invalid syntax [" + pattern + "]", pse);
}
}

parseErrorCode(getValidatorType().getErrorCodeKey());
return Collections.emptySet();
}
}

private void compileRegexPattern(String regex, boolean useEcma262Validator) {
if (useEcma262Validator) {
private static class PatternValidatorEcma262 extends BaseJsonValidator implements JsonValidator {
private static final Logger logger = LoggerFactory.getLogger(PatternValidator.class);

private String pattern;
private Regex compiledRegex;

public PatternValidatorEcma262(String schemaPath, JsonNode schemaNode, JsonSchema parentSchema, ValidationContext validationContext) {

super(schemaPath, schemaNode, parentSchema, ValidatorTypeCode.PATTERN, validationContext);
pattern = "";
if (schemaNode != null && schemaNode.isTextual()) {
pattern = schemaNode.textValue();
try {
compileRegexPattern(pattern, validationContext.getConfig() != null && validationContext.getConfig().isEcma262Validator());
} catch (SyntaxException se) {
logger.error("Failed to compile pattern : Invalid syntax [" + pattern + "]", se);
throw se;
}
}

parseErrorCode(getValidatorType().getErrorCodeKey());
}

private void compileRegexPattern(String regex, boolean useEcma262Validator) {
byte[] regexBytes = regex.getBytes();
this.compiledRegex = new Regex(regexBytes, 0, regexBytes.length, Option.NONE, UTF8Encoding.INSTANCE, Syntax.ECMAScript);
} else {
compiledPattern = Pattern.compile(pattern);
}
}

private boolean matches(String value) {
if (compiledRegex == null && compiledPattern == null) {
return true;
}
private boolean matches(String value) {
if (compiledRegex == null) {
return true;
}

if (compiledPattern == null) {
byte[] bytes = value.getBytes();
return compiledRegex.matcher(bytes).search(0, bytes.length, Option.NONE) >= 0;
} else {
return compiledPattern.matcher(value).find();
}

}
public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String at) {
debug(logger, node, rootNode, at);

public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String at) {
debug(logger, node, rootNode, at);

JsonType nodeType = TypeFactory.getValueNodeType(node);
if (nodeType != JsonType.STRING) {
return Collections.emptySet();
}
JsonType nodeType = TypeFactory.getValueNodeType(node);
if (nodeType != JsonType.STRING) {
return Collections.emptySet();
}

try {
if (!matches(node.asText())) {
return Collections.singleton(buildValidationMessage(at, pattern));
try {
if (!matches(node.asText())) {
return Collections.singleton(buildValidationMessage(at, pattern));
}
} catch (PatternSyntaxException pse) {
logger.error("Failed to apply pattern on " + at + ": Invalid syntax [" + pattern + "]", pse);
}
} catch (PatternSyntaxException pse) {
logger.error("Failed to apply pattern on " + at + ": Invalid syntax [" + pattern + "]", pse);
}

return Collections.emptySet();
return Collections.emptySet();
}
}
}

0 comments on commit 5cceac7

Please sign in to comment.