From 154bf206d06219d5fbb4c9d4b38fc45dcb8f6f9f Mon Sep 17 00:00:00 2001 From: jpbelang Date: Tue, 24 Mar 2020 07:26:41 -0400 Subject: [PATCH 1/9] Beginning to fix backwards compat problem with dates. --- .../raml/yagi/framework/util/DateUtils.java | 37 ++++++++++++++----- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/yagi/src/main/java/org/raml/yagi/framework/util/DateUtils.java b/yagi/src/main/java/org/raml/yagi/framework/util/DateUtils.java index 4c2b3e83..6be889ee 100644 --- a/yagi/src/main/java/org/raml/yagi/framework/util/DateUtils.java +++ b/yagi/src/main/java/org/raml/yagi/framework/util/DateUtils.java @@ -21,6 +21,8 @@ import org.joda.time.format.DateTimeFormatterBuilder; import org.joda.time.format.ISODateTimeFormat; +import java.util.IllegalFormatException; + import static org.joda.time.format.ISODateTimeFormat.*; public class DateUtils @@ -153,16 +155,11 @@ public boolean isValidDate(String date, DateType format, String rfc) timeOnlyFormatter.parseLocalTime(date); break; case datetime_only: - try - { - dateTimeOnlyFormatterNoMillis.parseLocalDateTime(date); - } - catch (Exception e) - { - dateTimeOnlyFormatterMillis.parseLocalDateTime(date); - } + checkDatetimeOnly(date); break; case datetime: + // Mon., 20 Jan. 2020 19:21:21 EST + // Mon, 20 Jan 2020 19:23:30 EST if ("rfc2616".equals(rfc)) { rfc2616Formatter.parseLocalDateTime(date); @@ -174,9 +171,17 @@ public boolean isValidDate(String date, DateType format, String rfc) { rfc3339FormatterMillis.parseLocalDateTime(date); } - catch (Exception e) + catch (IllegalArgumentException e) { - rfc3339FormatterNoMillis.parseLocalDateTime(date); + try + { + rfc3339FormatterNoMillis.parseLocalDateTime(date); + } + catch (IllegalArgumentException e2) + { + throw e2; + // checkDatetimeOnly(date); + } } break; } @@ -191,6 +196,18 @@ public boolean isValidDate(String date, DateType format, String rfc) } } + private void checkDatetimeOnly(String date) + { + try + { + dateTimeOnlyFormatterNoMillis.parseLocalDateTime(date); + } + catch (IllegalArgumentException e) + { + dateTimeOnlyFormatterMillis.parseLocalDateTime(date); + } + } + private DateTimeFormatterBuilder yearFormat(boolean strictYear, boolean strictDates) { From 786efae3676ffebd03d3a2d28c0ad93391adae1d Mon Sep 17 00:00:00 2001 From: jpbelang Date: Tue, 24 Mar 2020 07:40:46 -0400 Subject: [PATCH 2/9] Beginning to fix backwards compat problem with dates. --- .../org/raml/yagi/framework/util/DateUtils.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/yagi/src/main/java/org/raml/yagi/framework/util/DateUtils.java b/yagi/src/main/java/org/raml/yagi/framework/util/DateUtils.java index 6be889ee..e3571443 100644 --- a/yagi/src/main/java/org/raml/yagi/framework/util/DateUtils.java +++ b/yagi/src/main/java/org/raml/yagi/framework/util/DateUtils.java @@ -37,9 +37,11 @@ public class DateUtils DATE_ONLY_FOUR_DIGITS_YEAR_LENGTH_VALIDATION, System.getProperty(DATE_ONLY_FOUR_DIGITS_YEAR_LENGTH_VALIDATION_ALTERNATE, "true"))); public static boolean STRICT_DATES_VALIDATION_3339 = Boolean.parseBoolean(System.getProperty(STRICT_DATES_RFC3339, "true")); public static boolean STRICT_DATES_VALIDATION_2616 = Boolean.parseBoolean(System.getProperty(STRICT_DATES_RFC2616, "true")); + private final boolean strictDates3339; private DateUtils(boolean strictYear, boolean strictDates3339, boolean strictDates2616) { + this.strictDates3339 = strictDates3339; setFormatters(strictYear, strictDates3339, strictDates2616); } @@ -179,8 +181,15 @@ public boolean isValidDate(String date, DateType format, String rfc) } catch (IllegalArgumentException e2) { - throw e2; - // checkDatetimeOnly(date); + + if (!strictDates3339) + { + checkDatetimeOnly(date); + } + else + { + throw e2; + } } } break; From c7bfb96bb0aac712e28cb5722923784e20bd8640 Mon Sep 17 00:00:00 2001 From: jpbelang Date: Wed, 25 Mar 2020 17:16:35 -0400 Subject: [PATCH 3/9] Appropriate system prop for fallback of dates. --- .../raml/yagi/framework/util/DateUtils.java | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/yagi/src/main/java/org/raml/yagi/framework/util/DateUtils.java b/yagi/src/main/java/org/raml/yagi/framework/util/DateUtils.java index e3571443..19857c6e 100644 --- a/yagi/src/main/java/org/raml/yagi/framework/util/DateUtils.java +++ b/yagi/src/main/java/org/raml/yagi/framework/util/DateUtils.java @@ -19,11 +19,6 @@ import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; import org.joda.time.format.DateTimeFormatterBuilder; -import org.joda.time.format.ISODateTimeFormat; - -import java.util.IllegalFormatException; - -import static org.joda.time.format.ISODateTimeFormat.*; public class DateUtils { @@ -33,31 +28,36 @@ public class DateUtils private static final String STRICT_DATES_RFC3339 = "org.raml.dates_rfc3339_validation"; private static final String STRICT_DATES_RFC2616 = "org.raml.dates_rfc2616_validation"; + private static final String FALLBACK_DATETIME = "org.raml.fallback_datetime_to_datetime-only"; + public static boolean FOUR_YEARS_VALIDATION = Boolean.parseBoolean(System.getProperty( DATE_ONLY_FOUR_DIGITS_YEAR_LENGTH_VALIDATION, System.getProperty(DATE_ONLY_FOUR_DIGITS_YEAR_LENGTH_VALIDATION_ALTERNATE, "true"))); public static boolean STRICT_DATES_VALIDATION_3339 = Boolean.parseBoolean(System.getProperty(STRICT_DATES_RFC3339, "true")); public static boolean STRICT_DATES_VALIDATION_2616 = Boolean.parseBoolean(System.getProperty(STRICT_DATES_RFC2616, "true")); - private final boolean strictDates3339; - private DateUtils(boolean strictYear, boolean strictDates3339, boolean strictDates2616) + public static boolean FALLBACK_DATETIME_TO_DATETIME_ONLY = Boolean.parseBoolean(System.getProperty(FALLBACK_DATETIME, "false")); + + private final boolean fallbackDatetime; + + private DateUtils(boolean strictYear, boolean strictDates3339, boolean strictDates2616, boolean fallbackDatetime) { - this.strictDates3339 = strictDates3339; + this.fallbackDatetime = fallbackDatetime; setFormatters(strictYear, strictDates3339, strictDates2616); } public static DateUtils createStrictDateUtils() { - return new DateUtils(true, true, true); + return new DateUtils(true, true, true, false); } public static DateUtils createNonStrictDateUtils() { - return new DateUtils(false, false, false); + return new DateUtils(false, false, false, true); } public static DateUtils createFromProperties() { - return new DateUtils(FOUR_YEARS_VALIDATION, STRICT_DATES_VALIDATION_3339, STRICT_DATES_VALIDATION_2616); + return new DateUtils(FOUR_YEARS_VALIDATION, STRICT_DATES_VALIDATION_3339, STRICT_DATES_VALIDATION_2616, FALLBACK_DATETIME_TO_DATETIME_ONLY); } public void setFormatters(boolean strictYear, boolean strictDates3339, boolean strictDates2616) @@ -182,7 +182,7 @@ public boolean isValidDate(String date, DateType format, String rfc) catch (IllegalArgumentException e2) { - if (!strictDates3339) + if (fallbackDatetime) { checkDatetimeOnly(date); } From 5ac54de73ede2315b7984498401121a9541e1526 Mon Sep 17 00:00:00 2001 From: jpbelang Date: Wed, 25 Mar 2020 17:47:22 -0400 Subject: [PATCH 4/9] Parsing strings! --- .../framework/grammar/rule/IntegerTypeRule.java | 17 +++++++++++------ .../framework/grammar/rule/NumberFallback.java | 9 +++++++++ .../framework/grammar/rule/NumberTypeRule.java | 9 +++++++++ 3 files changed, 29 insertions(+), 6 deletions(-) create mode 100644 yagi/src/main/java/org/raml/yagi/framework/grammar/rule/NumberFallback.java diff --git a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/IntegerTypeRule.java b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/IntegerTypeRule.java index 0f73088d..79f8a092 100644 --- a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/IntegerTypeRule.java +++ b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/IntegerTypeRule.java @@ -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; @@ -57,6 +53,16 @@ public List getSuggestions(Node node, ParsingContext context) @Override public boolean matches(@Nonnull Node node) { + if ( node instanceof StringNode && NumberFallback.CAST_STRINGS_AS_NUMBERS ) { + 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()); @@ -68,7 +74,6 @@ else if (node instanceof FloatingNode) long value = ((FloatingNode) node).getValue().longValue(); if (((FloatingNode) node).getValue().compareTo(new BigDecimal(value)) != 0) { - return false; } diff --git a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/NumberFallback.java b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/NumberFallback.java new file mode 100644 index 00000000..a66b13d7 --- /dev/null +++ b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/NumberFallback.java @@ -0,0 +1,9 @@ +package org.raml.yagi.framework.grammar.rule; + +/** + * Created. There, you have it. + */ +public class NumberFallback { + 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")); +} diff --git a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/NumberTypeRule.java b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/NumberTypeRule.java index 96acb882..e2752de4 100644 --- a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/NumberTypeRule.java +++ b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/NumberTypeRule.java @@ -55,6 +55,15 @@ public List getSuggestions(Node node, ParsingContext context) @Override public boolean matches(@Nonnull Node node) { + if ( node instanceof StringNode && NumberFallback.CAST_STRINGS_AS_NUMBERS ) { + 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()); From 77b1f6e0dd0f3c01ccbb420ee636f4ece8ddd068 Mon Sep 17 00:00:00 2001 From: jpbelang Date: Wed, 25 Mar 2020 18:49:48 -0400 Subject: [PATCH 5/9] Forgot the DivisorValueRule. --- .../framework/grammar/rule/DivisorValueRule.java | 14 +++++++++----- .../framework/grammar/rule/StringTypeRule.java | 3 ++- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/DivisorValueRule.java b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/DivisorValueRule.java index abe6decf..029bb27a 100644 --- a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/DivisorValueRule.java +++ b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/DivisorValueRule.java @@ -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; @@ -51,7 +48,14 @@ public boolean matches(@Nonnull Node node) { final BigDecimal divisor = new BigDecimal(divisorValue.toString()); BigDecimal value = null; - if (node instanceof IntegerNode) + if ( node instanceof StringNode && NumberFallback.CAST_STRINGS_AS_NUMBERS ) { + 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()); } diff --git a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/StringTypeRule.java b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/StringTypeRule.java index c25b8e36..501838d1 100644 --- a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/StringTypeRule.java +++ b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/StringTypeRule.java @@ -17,6 +17,7 @@ import org.raml.yagi.framework.nodes.Node; import org.raml.yagi.framework.nodes.NodeType; +import org.raml.yagi.framework.nodes.NullNode; import org.raml.yagi.framework.nodes.StringNode; import org.raml.yagi.framework.suggester.ParsingContext; import org.raml.yagi.framework.suggester.Suggestion; @@ -37,7 +38,7 @@ public List getSuggestions(Node node, ParsingContext context) @Override public boolean matches(@Nonnull Node node) { - return node instanceof StringNode; + return node instanceof StringNode || node instanceof NullNode; } @Override From 07b4a3bc1c5cecf7efede4937651ee241c2a0d79 Mon Sep 17 00:00:00 2001 From: jpbelang Date: Wed, 25 Mar 2020 19:00:30 -0400 Subject: [PATCH 6/9] Reformat, and rollback of the string.... --- .../grammar/rule/DivisorValueRule.java | 13 +++++++++---- .../grammar/rule/IntegerTypeRule.java | 10 +++++++--- .../framework/grammar/rule/NumberFallback.java | 18 +++++++++++++++++- .../framework/grammar/rule/NumberTypeRule.java | 10 +++++++--- .../framework/grammar/rule/StringTypeRule.java | 2 +- 5 files changed, 41 insertions(+), 12 deletions(-) diff --git a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/DivisorValueRule.java b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/DivisorValueRule.java index 029bb27a..f4cc0284 100644 --- a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/DivisorValueRule.java +++ b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/DivisorValueRule.java @@ -48,14 +48,19 @@ public boolean matches(@Nonnull Node node) { final BigDecimal divisor = new BigDecimal(divisorValue.toString()); BigDecimal value = null; - if ( node instanceof StringNode && NumberFallback.CAST_STRINGS_AS_NUMBERS ) { + if (node instanceof StringNode && NumberFallback.CAST_STRINGS_AS_NUMBERS) + { String intString = ((StringNode) node).getValue(); - try { + try + { value = new BigDecimal(intString); - } catch (NumberFormatException e) { + } + catch (NumberFormatException e) + { return false; } - } if (node instanceof IntegerNode) + } + if (node instanceof IntegerNode) { value = new BigDecimal(((IntegerNode) node).getValue()); } diff --git a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/IntegerTypeRule.java b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/IntegerTypeRule.java index 79f8a092..d84c3c00 100644 --- a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/IntegerTypeRule.java +++ b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/IntegerTypeRule.java @@ -53,12 +53,16 @@ public List getSuggestions(Node node, ParsingContext context) @Override public boolean matches(@Nonnull Node node) { - if ( node instanceof StringNode && NumberFallback.CAST_STRINGS_AS_NUMBERS ) { + if (node instanceof StringNode && NumberFallback.CAST_STRINGS_AS_NUMBERS) + { String intString = ((StringNode) node).getValue(); - try { + try + { long longValue = Long.parseLong(intString); return isInRange(longValue); - } catch (NumberFormatException e) { + } + catch (NumberFormatException e) + { return false; } } diff --git a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/NumberFallback.java b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/NumberFallback.java index a66b13d7..75c9d281 100644 --- a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/NumberFallback.java +++ b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/NumberFallback.java @@ -1,9 +1,25 @@ +/* + * Copyright 2013 (c) MuleSoft, Inc. + * + * 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.raml.yagi.framework.grammar.rule; /** * Created. There, you have it. */ -public class NumberFallback { +public class NumberFallback +{ 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")); } diff --git a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/NumberTypeRule.java b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/NumberTypeRule.java index e2752de4..f4b69a55 100644 --- a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/NumberTypeRule.java +++ b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/NumberTypeRule.java @@ -55,12 +55,16 @@ public List getSuggestions(Node node, ParsingContext context) @Override public boolean matches(@Nonnull Node node) { - if ( node instanceof StringNode && NumberFallback.CAST_STRINGS_AS_NUMBERS ) { + if (node instanceof StringNode && NumberFallback.CAST_STRINGS_AS_NUMBERS) + { String intString = ((StringNode) node).getValue(); - try { + try + { double doubleValue = Double.parseDouble(intString); return range == null || range.contains(doubleValue); - } catch (NumberFormatException e) { + } + catch (NumberFormatException e) + { return false; } } diff --git a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/StringTypeRule.java b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/StringTypeRule.java index 501838d1..b087eaff 100644 --- a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/StringTypeRule.java +++ b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/StringTypeRule.java @@ -38,7 +38,7 @@ public List getSuggestions(Node node, ParsingContext context) @Override public boolean matches(@Nonnull Node node) { - return node instanceof StringNode || node instanceof NullNode; + return node instanceof StringNode; } @Override From 82e30f2a3759ed20827fd5d5aeb99a94c059cfcc Mon Sep 17 00:00:00 2001 From: jpbelang Date: Wed, 25 Mar 2020 21:43:22 -0400 Subject: [PATCH 7/9] Nil strings almost. --- .../framework/grammar/rule/MaxLengthRule.java | 6 +++++ .../framework/grammar/rule/MinLengthRule.java | 6 +++++ .../grammar/rule/NilStringFallback.java | 25 +++++++++++++++++++ .../grammar/rule/RegexValueRule.java | 12 +++++++++ .../grammar/rule/StringTypeRule.java | 2 +- 5 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 yagi/src/main/java/org/raml/yagi/framework/grammar/rule/NilStringFallback.java diff --git a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/MaxLengthRule.java b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/MaxLengthRule.java index 563a2ad8..a3bfedbf 100644 --- a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/MaxLengthRule.java +++ b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/MaxLengthRule.java @@ -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; @@ -44,6 +45,11 @@ public List getSuggestions(Node node, ParsingContext context) @Override public boolean matches(@Nonnull Node node) { + if (node instanceof NullNode && NilStringFallback.NILLABLE_STRINGS) { + + return true; + } + if (node instanceof SimpleTypeNode) { return ((SimpleTypeNode) node).getLiteralValue().length() <= maxLength; diff --git a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/MinLengthRule.java b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/MinLengthRule.java index bd46770e..5c2904dc 100644 --- a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/MinLengthRule.java +++ b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/MinLengthRule.java @@ -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; @@ -44,6 +45,11 @@ public List getSuggestions(Node node, ParsingContext context) @Override public boolean matches(@Nonnull Node node) { + if (node instanceof NullNode && NilStringFallback.NILLABLE_STRINGS) { + + return minLength == 0; + } + if (node instanceof SimpleTypeNode) { return ((SimpleTypeNode) node).getLiteralValue().length() >= minLength; diff --git a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/NilStringFallback.java b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/NilStringFallback.java new file mode 100644 index 00000000..c568ab41 --- /dev/null +++ b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/NilStringFallback.java @@ -0,0 +1,25 @@ +/* + * Copyright 2013 (c) MuleSoft, Inc. + * + * 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.raml.yagi.framework.grammar.rule; + +/** + * Created. There, you have it. + */ +public class NilStringFallback +{ + private static final String NILLABLE_STRINGS_PROP = "org.raml.nillable_strings"; + public static boolean NILLABLE_STRINGS = Boolean.parseBoolean(System.getProperty(NILLABLE_STRINGS_PROP, "false")); +} diff --git a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/RegexValueRule.java b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/RegexValueRule.java index faf117ea..185d9abb 100644 --- a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/RegexValueRule.java +++ b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/RegexValueRule.java @@ -18,6 +18,7 @@ import org.apache.commons.lang.StringUtils; 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.DefaultSuggestion; import org.raml.yagi.framework.suggester.ParsingContext; @@ -72,6 +73,11 @@ public List getSuggestions(Node node, ParsingContext context) @Override public boolean matches(@Nonnull Node node) { + if (node instanceof NullNode && NilStringFallback.NILLABLE_STRINGS ) { + + return fullMatch ? value.matcher("").matches() : value.matcher("").find(); + } + return node instanceof SimpleTypeNode && (fullMatch ? getMatcher((SimpleTypeNode) node).matches() : getMatcher((SimpleTypeNode) node).find()); } @@ -107,6 +113,12 @@ public RegexValueRule fullMatch(boolean fullMatch) @Override public Node apply(@Nonnull Node node) { + + if (node instanceof NullNode && NilStringFallback.NILLABLE_STRINGS ) { + + return node; + } + if (!matches(node)) { return ErrorNodeFactory.createInvalidValue(node, String.valueOf(value)); diff --git a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/StringTypeRule.java b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/StringTypeRule.java index b087eaff..496e05d2 100644 --- a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/StringTypeRule.java +++ b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/StringTypeRule.java @@ -38,7 +38,7 @@ public List getSuggestions(Node node, ParsingContext context) @Override public boolean matches(@Nonnull Node node) { - return node instanceof StringNode; + return node instanceof StringNode || (node instanceof NullNode && NilStringFallback.NILLABLE_STRINGS); } @Override From 293b20f11e49fa2961c0faa3a5ece70fb1b3c46c Mon Sep 17 00:00:00 2001 From: jpbelang Date: Wed, 25 Mar 2020 22:15:36 -0400 Subject: [PATCH 8/9] Better nillable strings. Only affects types. --- .../impl/v10/type/TypeToRuleVisitor.java | 12 ++++++--- .../framework/grammar/rule/MaxLengthRule.java | 22 +++++++++++++--- .../framework/grammar/rule/MinLengthRule.java | 20 +++++++++++++-- .../grammar/rule/NilStringFallback.java | 25 ------------------- .../grammar/rule/RegexValueRule.java | 14 +++++++++-- .../grammar/rule/StringTypeRule.java | 14 ++++++++++- 6 files changed, 70 insertions(+), 37 deletions(-) delete mode 100644 yagi/src/main/java/org/raml/yagi/framework/grammar/rule/NilStringFallback.java diff --git a/raml-parser-2/src/main/java/org/raml/v2/internal/impl/v10/type/TypeToRuleVisitor.java b/raml-parser-2/src/main/java/org/raml/v2/internal/impl/v10/type/TypeToRuleVisitor.java index 27b44a6d..c63f7d09 100644 --- a/raml-parser-2/src/main/java/org/raml/v2/internal/impl/v10/type/TypeToRuleVisitor.java +++ b/raml-parser-2/src/main/java/org/raml/v2/internal/impl/v10/type/TypeToRuleVisitor.java @@ -48,6 +48,10 @@ public class TypeToRuleVisitor implements TypeVisitor { + + 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; @@ -84,11 +88,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()) @@ -99,13 +103,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; } diff --git a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/MaxLengthRule.java b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/MaxLengthRule.java index a3bfedbf..c0f8c424 100644 --- a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/MaxLengthRule.java +++ b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/MaxLengthRule.java @@ -28,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 @@ -45,8 +54,8 @@ public List getSuggestions(Node node, ParsingContext context) @Override public boolean matches(@Nonnull Node node) { - if (node instanceof NullNode && NilStringFallback.NILLABLE_STRINGS) { - + if (node instanceof NullNode && nillableStrings) + { return true; } @@ -60,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()); } diff --git a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/MinLengthRule.java b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/MinLengthRule.java index 5c2904dc..e0af9a57 100644 --- a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/MinLengthRule.java +++ b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/MinLengthRule.java @@ -28,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 @@ -45,7 +54,8 @@ public List getSuggestions(Node node, ParsingContext context) @Override public boolean matches(@Nonnull Node node) { - if (node instanceof NullNode && NilStringFallback.NILLABLE_STRINGS) { + if (node instanceof NullNode && nillableStrings) + { return minLength == 0; } @@ -64,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()); } diff --git a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/NilStringFallback.java b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/NilStringFallback.java deleted file mode 100644 index c568ab41..00000000 --- a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/NilStringFallback.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2013 (c) MuleSoft, Inc. - * - * 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.raml.yagi.framework.grammar.rule; - -/** - * Created. There, you have it. - */ -public class NilStringFallback -{ - private static final String NILLABLE_STRINGS_PROP = "org.raml.nillable_strings"; - public static boolean NILLABLE_STRINGS = Boolean.parseBoolean(System.getProperty(NILLABLE_STRINGS_PROP, "false")); -} diff --git a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/RegexValueRule.java b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/RegexValueRule.java index 185d9abb..0b957e24 100644 --- a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/RegexValueRule.java +++ b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/RegexValueRule.java @@ -34,6 +34,7 @@ public class RegexValueRule extends Rule { + private final boolean nillableString; private Pattern value; private String description; private List suggestions = new ArrayList<>(); @@ -43,6 +44,13 @@ public class RegexValueRule extends Rule public RegexValueRule(Pattern value) { this.value = value; + this.nillableString = false; + } + + public RegexValueRule(Pattern value, boolean nillableString) + { + this.value = value; + this.nillableString = nillableString; } @Nonnull @@ -73,7 +81,8 @@ public List getSuggestions(Node node, ParsingContext context) @Override public boolean matches(@Nonnull Node node) { - if (node instanceof NullNode && NilStringFallback.NILLABLE_STRINGS ) { + if (node instanceof NullNode && nillableString) + { return fullMatch ? value.matcher("").matches() : value.matcher("").find(); } @@ -114,7 +123,8 @@ public RegexValueRule fullMatch(boolean fullMatch) public Node apply(@Nonnull Node node) { - if (node instanceof NullNode && NilStringFallback.NILLABLE_STRINGS ) { + if (node instanceof NullNode && nillableString) + { return node; } diff --git a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/StringTypeRule.java b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/StringTypeRule.java index 496e05d2..cd963f73 100644 --- a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/StringTypeRule.java +++ b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/StringTypeRule.java @@ -28,6 +28,18 @@ public class StringTypeRule extends AbstractTypeRule { + private final boolean nillableStrings; + + public StringTypeRule() + { + nillableStrings = false; + } + + public StringTypeRule(boolean nillableStrings) + { + this.nillableStrings = nillableStrings; + } + @Nonnull @Override public List getSuggestions(Node node, ParsingContext context) @@ -38,7 +50,7 @@ public List getSuggestions(Node node, ParsingContext context) @Override public boolean matches(@Nonnull Node node) { - return node instanceof StringNode || (node instanceof NullNode && NilStringFallback.NILLABLE_STRINGS); + return node instanceof StringNode || (node instanceof NullNode && nillableStrings); } @Override From 8e2a7ca9b4be3354c83c745fbc09d55e73e022e3 Mon Sep 17 00:00:00 2001 From: jpbelang Date: Wed, 25 Mar 2020 22:38:56 -0400 Subject: [PATCH 9/9] Made integers and string better. --- .../impl/v10/type/TypeToRuleVisitor.java | 9 ++++--- .../grammar/rule/DivisorValueRule.java | 11 +++++++- .../grammar/rule/IntegerTypeRule.java | 10 +++++++- .../grammar/rule/NumberFallback.java | 25 ------------------- .../grammar/rule/NumberTypeRule.java | 10 +++++++- 5 files changed, 33 insertions(+), 32 deletions(-) delete mode 100644 yagi/src/main/java/org/raml/yagi/framework/grammar/rule/NumberFallback.java diff --git a/raml-parser-2/src/main/java/org/raml/v2/internal/impl/v10/type/TypeToRuleVisitor.java b/raml-parser-2/src/main/java/org/raml/v2/internal/impl/v10/type/TypeToRuleVisitor.java index c63f7d09..77728616 100644 --- a/raml-parser-2/src/main/java/org/raml/v2/internal/impl/v10/type/TypeToRuleVisitor.java +++ b/raml-parser-2/src/main/java/org/raml/v2/internal/impl/v10/type/TypeToRuleVisitor.java @@ -48,7 +48,8 @@ public class TypeToRuleVisitor implements TypeVisitor { - + 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")); @@ -311,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) @@ -347,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) { diff --git a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/DivisorValueRule.java b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/DivisorValueRule.java index f4cc0284..e3b6c5b7 100644 --- a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/DivisorValueRule.java +++ b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/DivisorValueRule.java @@ -29,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 @@ -48,7 +57,7 @@ public boolean matches(@Nonnull Node node) { final BigDecimal divisor = new BigDecimal(divisorValue.toString()); BigDecimal value = null; - if (node instanceof StringNode && NumberFallback.CAST_STRINGS_AS_NUMBERS) + if (node instanceof StringNode && castStringsAsNumbers) { String intString = ((StringNode) node).getValue(); try diff --git a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/IntegerTypeRule.java b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/IntegerTypeRule.java index d84c3c00..1d750cad 100644 --- a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/IntegerTypeRule.java +++ b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/IntegerTypeRule.java @@ -29,12 +29,14 @@ public class IntegerTypeRule extends AbstractTypeRule { + private final boolean castStringsAsNumbers; @Nullable private Range range; public IntegerTypeRule(@Nullable Range range) { this.range = range; + this.castStringsAsNumbers = false; } public IntegerTypeRule() @@ -42,6 +44,12 @@ public IntegerTypeRule() this(null); } + public IntegerTypeRule(boolean castStringsAsNumbers) + { + + this.castStringsAsNumbers = castStringsAsNumbers; + } + @Nonnull @Override public List getSuggestions(Node node, ParsingContext context) @@ -53,7 +61,7 @@ public List getSuggestions(Node node, ParsingContext context) @Override public boolean matches(@Nonnull Node node) { - if (node instanceof StringNode && NumberFallback.CAST_STRINGS_AS_NUMBERS) + if (node instanceof StringNode && castStringsAsNumbers) { String intString = ((StringNode) node).getValue(); try diff --git a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/NumberFallback.java b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/NumberFallback.java deleted file mode 100644 index 75c9d281..00000000 --- a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/NumberFallback.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2013 (c) MuleSoft, Inc. - * - * 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.raml.yagi.framework.grammar.rule; - -/** - * Created. There, you have it. - */ -public class NumberFallback -{ - 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")); -} diff --git a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/NumberTypeRule.java b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/NumberTypeRule.java index f4b69a55..ce609522 100644 --- a/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/NumberTypeRule.java +++ b/yagi/src/main/java/org/raml/yagi/framework/grammar/rule/NumberTypeRule.java @@ -31,12 +31,14 @@ public class NumberTypeRule extends AbstractTypeRule { + private final boolean castStringsAsNumbers; @Nullable private Range range; public NumberTypeRule(@Nullable Range range) { this.range = range; + this.castStringsAsNumbers = false; } public NumberTypeRule() @@ -44,6 +46,12 @@ public NumberTypeRule() this(null); } + public NumberTypeRule(boolean castStringsAsNumbers) + { + + this.castStringsAsNumbers = castStringsAsNumbers; + } + @Nonnull @Override public List getSuggestions(Node node, ParsingContext context) @@ -55,7 +63,7 @@ public List getSuggestions(Node node, ParsingContext context) @Override public boolean matches(@Nonnull Node node) { - if (node instanceof StringNode && NumberFallback.CAST_STRINGS_AS_NUMBERS) + if (node instanceof StringNode && castStringsAsNumbers) { String intString = ((StringNode) node).getValue(); try