Skip to content
This repository has been archived by the owner on Feb 12, 2022. It is now read-only.

Commit

Permalink
issue-back-dates (#687)
Browse files Browse the repository at this point in the history
Options to allow more flexible verification.
  • Loading branch information
jpbelang authored Mar 26, 2020
1 parent 0bc2943 commit 52a9e4b
Show file tree
Hide file tree
Showing 9 changed files with 203 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@
public class TypeToRuleVisitor implements TypeVisitor<Rule>
{

private static final String CAST_STRINGS_AS_NUMBERS_PROP = "org.raml.cast_strings_as_number";
public static boolean CAST_STRINGS_AS_NUMBERS = Boolean.parseBoolean(System.getProperty(CAST_STRINGS_AS_NUMBERS_PROP, "false"));
private static final String NILLABLE_STRINGS_PROP = "org.raml.nillable_strings";
public static boolean NILLABLE_STRINGS = Boolean.parseBoolean(System.getProperty(NILLABLE_STRINGS_PROP, "false"));

private ResourceLoader resourceLoader;
private final boolean useDiscriminatorsToCalculateTypes;
private boolean strictMode = false;
Expand Down Expand Up @@ -84,11 +89,11 @@ public Rule generateRule(ResolvedType items)
@Override
public Rule visitString(StringResolvedType stringTypeNode)
{
final AllOfRule typeRule = new AllOfRule(new StringTypeRule());
final AllOfRule typeRule = new AllOfRule(new StringTypeRule(NILLABLE_STRINGS));
registerRule(stringTypeNode, typeRule);
if (isNotEmpty(stringTypeNode.getPattern()))
{
typeRule.and(new RegexValueRule(Pattern.compile(stringTypeNode.getPattern())));
typeRule.and(new RegexValueRule(Pattern.compile(stringTypeNode.getPattern()), NILLABLE_STRINGS));
}

if (stringTypeNode.getEnums() != null && !stringTypeNode.getEnums().isEmpty())
Expand All @@ -99,13 +104,13 @@ public Rule visitString(StringResolvedType stringTypeNode)
if (stringTypeNode.getMaxLength() != null)
{
Integer maxLength = stringTypeNode.getMaxLength();
typeRule.and(new MaxLengthRule(maxLength));
typeRule.and(new MaxLengthRule(maxLength, NILLABLE_STRINGS));
}

if (stringTypeNode.getMinLength() != null)
{
Integer maxLength = stringTypeNode.getMinLength();
typeRule.and(new MinLengthRule(maxLength));
typeRule.and(new MinLengthRule(maxLength, NILLABLE_STRINGS));
}
return typeRule;
}
Expand Down Expand Up @@ -307,13 +312,13 @@ public Rule visitBoolean(BooleanResolvedType booleanTypeDefinition)
@Override
public Rule visitInteger(IntegerResolvedType integerTypeDefinition)
{
return visitNumber(integerTypeDefinition, new IntegerTypeRule());
return visitNumber(integerTypeDefinition, new IntegerTypeRule(CAST_STRINGS_AS_NUMBERS));
}

@Override
public Rule visitNumber(NumberResolvedType numberTypeDefinition)
{
return visitNumber(numberTypeDefinition, new NumberTypeRule());
return visitNumber(numberTypeDefinition, new NumberTypeRule(CAST_STRINGS_AS_NUMBERS));
}

private Rule visitNumber(NumberResolvedType numericTypeNode, Rule numericTypeRule)
Expand Down Expand Up @@ -343,7 +348,7 @@ else if (numericTypeNode.getMaximum() != null)
}
if (numericTypeNode.getMultiple() != null)
{
typeRule.and(new DivisorValueRule(numericTypeNode.getMultiple()));
typeRule.and(new DivisorValueRule(numericTypeNode.getMultiple(), CAST_STRINGS_AS_NUMBERS));
}
if (numericTypeNode.getFormat() != null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,7 @@
*/
package org.raml.yagi.framework.grammar.rule;

import org.raml.yagi.framework.nodes.FloatingNode;
import org.raml.yagi.framework.nodes.IntegerNode;
import org.raml.yagi.framework.nodes.Node;
import org.raml.yagi.framework.nodes.SimpleTypeNode;
import org.raml.yagi.framework.nodes.*;
import org.raml.yagi.framework.suggester.ParsingContext;
import org.raml.yagi.framework.suggester.Suggestion;

Expand All @@ -32,11 +29,20 @@
public class DivisorValueRule extends Rule
{

private final boolean castStringsAsNumbers;
private Number divisorValue;

public DivisorValueRule(Number divisorValue)
{
this.divisorValue = divisorValue;
this.castStringsAsNumbers = false;
}

public DivisorValueRule(Number multiple, boolean castStringsAsNumbers)
{

this.divisorValue = multiple;
this.castStringsAsNumbers = castStringsAsNumbers;
}

@Nonnull
Expand All @@ -51,6 +57,18 @@ public boolean matches(@Nonnull Node node)
{
final BigDecimal divisor = new BigDecimal(divisorValue.toString());
BigDecimal value = null;
if (node instanceof StringNode && castStringsAsNumbers)
{
String intString = ((StringNode) node).getValue();
try
{
value = new BigDecimal(intString);
}
catch (NumberFormatException e)
{
return false;
}
}
if (node instanceof IntegerNode)
{
value = new BigDecimal(((IntegerNode) node).getValue());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,7 @@
package org.raml.yagi.framework.grammar.rule;

import com.google.common.collect.Range;
import org.raml.yagi.framework.nodes.FloatingNode;
import org.raml.yagi.framework.nodes.IntegerNode;
import org.raml.yagi.framework.nodes.Node;
import org.raml.yagi.framework.nodes.NodeType;
import org.raml.yagi.framework.nodes.jackson.JFloatingNode;
import org.raml.yagi.framework.nodes.*;
import org.raml.yagi.framework.suggester.ParsingContext;
import org.raml.yagi.framework.suggester.Suggestion;

Expand All @@ -33,19 +29,27 @@
public class IntegerTypeRule extends AbstractTypeRule
{

private final boolean castStringsAsNumbers;
@Nullable
private Range<Long> range;

public IntegerTypeRule(@Nullable Range<Long> range)
{
this.range = range;
this.castStringsAsNumbers = false;
}

public IntegerTypeRule()
{
this(null);
}

public IntegerTypeRule(boolean castStringsAsNumbers)
{

this.castStringsAsNumbers = castStringsAsNumbers;
}

@Nonnull
@Override
public List<Suggestion> getSuggestions(Node node, ParsingContext context)
Expand All @@ -57,6 +61,20 @@ public List<Suggestion> getSuggestions(Node node, ParsingContext context)
@Override
public boolean matches(@Nonnull Node node)
{
if (node instanceof StringNode && castStringsAsNumbers)
{
String intString = ((StringNode) node).getValue();
try
{
long longValue = Long.parseLong(intString);
return isInRange(longValue);
}
catch (NumberFormatException e)
{
return false;
}
}

if (node instanceof IntegerNode)
{
return isInRange(((IntegerNode) node).getValue());
Expand All @@ -68,7 +86,6 @@ else if (node instanceof FloatingNode)
long value = ((FloatingNode) node).getValue().longValue();
if (((FloatingNode) node).getValue().compareTo(new BigDecimal(value)) != 0)
{

return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@


import org.raml.yagi.framework.nodes.Node;
import org.raml.yagi.framework.nodes.NullNode;
import org.raml.yagi.framework.nodes.SimpleTypeNode;
import org.raml.yagi.framework.suggester.ParsingContext;
import org.raml.yagi.framework.suggester.Suggestion;
Expand All @@ -27,11 +28,20 @@

public class MaxLengthRule extends Rule
{
private int maxLength;
private final int maxLength;
private final boolean nillableStrings;

public MaxLengthRule(int maxLength)
{
this.maxLength = maxLength;
this.nillableStrings = false;
}

public MaxLengthRule(int maxLength, boolean nillableStrings)
{

this.maxLength = maxLength;
this.nillableStrings = nillableStrings;
}

@Nonnull
Expand All @@ -44,6 +54,11 @@ public List<Suggestion> getSuggestions(Node node, ParsingContext context)
@Override
public boolean matches(@Nonnull Node node)
{
if (node instanceof NullNode && nillableStrings)
{
return true;
}

if (node instanceof SimpleTypeNode)
{
return ((SimpleTypeNode) node).getLiteralValue().length() <= maxLength;
Expand All @@ -54,10 +69,17 @@ public boolean matches(@Nonnull Node node)
@Override
public Node apply(@Nonnull Node node)
{

if (!matches(node))
{
return ErrorNodeFactory.createInvalidMaxLength(maxLength, node);
}

if (node instanceof NullNode && nillableStrings)
{
return createNodeUsingFactory(node, "");
}

return createNodeUsingFactory(node, ((SimpleTypeNode) node).getLiteralValue());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@


import org.raml.yagi.framework.nodes.Node;
import org.raml.yagi.framework.nodes.NullNode;
import org.raml.yagi.framework.nodes.SimpleTypeNode;
import org.raml.yagi.framework.suggester.ParsingContext;
import org.raml.yagi.framework.suggester.Suggestion;
Expand All @@ -27,11 +28,20 @@

public class MinLengthRule extends Rule
{
private int minLength;
private final int minLength;
private final boolean nillableStrings;

public MinLengthRule(int minLength)
{
this.minLength = minLength;
this.nillableStrings = false;
}

public MinLengthRule(int minLength, boolean nillableStrings)
{

this.minLength = minLength;
this.nillableStrings = nillableStrings;
}

@Nonnull
Expand All @@ -44,6 +54,12 @@ public List<Suggestion> getSuggestions(Node node, ParsingContext context)
@Override
public boolean matches(@Nonnull Node node)
{
if (node instanceof NullNode && nillableStrings)
{

return minLength == 0;
}

if (node instanceof SimpleTypeNode)
{
return ((SimpleTypeNode) node).getLiteralValue().length() >= minLength;
Expand All @@ -58,6 +74,12 @@ public Node apply(@Nonnull Node node)
{
return ErrorNodeFactory.createInvalidMinLength(minLength, node);
}

if (node instanceof NullNode && nillableStrings)
{
return createNodeUsingFactory(node, "");
}

return createNodeUsingFactory(node, ((SimpleTypeNode) node).getLiteralValue());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,27 @@

public class NumberTypeRule extends AbstractTypeRule
{
private final boolean castStringsAsNumbers;
@Nullable
private Range<Double> range;

public NumberTypeRule(@Nullable Range<Double> range)
{
this.range = range;
this.castStringsAsNumbers = false;
}

public NumberTypeRule()
{
this(null);
}

public NumberTypeRule(boolean castStringsAsNumbers)
{

this.castStringsAsNumbers = castStringsAsNumbers;
}

@Nonnull
@Override
public List<Suggestion> getSuggestions(Node node, ParsingContext context)
Expand All @@ -55,6 +63,19 @@ public List<Suggestion> getSuggestions(Node node, ParsingContext context)
@Override
public boolean matches(@Nonnull Node node)
{
if (node instanceof StringNode && castStringsAsNumbers)
{
String intString = ((StringNode) node).getValue();
try
{
double doubleValue = Double.parseDouble(intString);
return range == null || range.contains(doubleValue);
}
catch (NumberFormatException e)
{
return false;
}
}
if (node instanceof FloatingNode)
{
return range == null || range.contains(((FloatingNode) node).getValue().doubleValue());
Expand Down
Loading

0 comments on commit 52a9e4b

Please sign in to comment.