From 130277a4aae6a519d84b1ab0dba207b738f91183 Mon Sep 17 00:00:00 2001 From: Sebastian Toepfer <61313468+sebastian-toepfer@users.noreply.github.com> Date: Thu, 2 Nov 2023 00:38:01 +0100 Subject: [PATCH] add abnf basic structure --- vocabulary-format-assertion/pom.xml | 13 +- .../format/assertion/abnf/CoreRules.java | 165 +++++++++++++++ .../format/assertion/abnf/Rule.java | 78 +++++++ .../format/assertion/abnf/RuleList.java | 77 +++++++ .../assertion/abnf/element/Alternative.java | 82 ++++++++ .../abnf/element/ConcatedString.java | 87 ++++++++ .../assertion/abnf/element/Concatenation.java | 82 ++++++++ .../assertion/abnf/element/Element.java} | 10 +- .../abnf/element/NumericCharacter.java | 109 ++++++++++ .../abnf/element/OptionalSequence.java | 71 +++++++ .../assertion/abnf/element/RuleName.java | 67 ++++++ .../assertion/abnf/element/RuleReference.java | 71 +++++++ .../assertion/abnf/element/SequenceGroup.java | 71 +++++++ .../abnf/element/SpecificRepetition.java | 77 +++++++ .../assertion/abnf/element/StringElement.java | 76 +++++++ .../abnf/element/ValueRangeAlternatives.java | 77 +++++++ .../abnf/element/VariableRepetition.java | 108 ++++++++++ .../format/assertion/abnf/reader/ABNF.java | 30 +++ .../abnf/reader/AlternativeDecisionMaker.java | 72 +++++++ .../abnf/reader/AlternativeExtractor.java | 99 +++++++++ .../abnf/reader/CommentaryExtractor.java | 63 ++++++ .../assertion/abnf/reader/ElementToken.java | 30 +++ .../abnf/reader/ElementsExtractor.java | 135 ++++++++++++ .../assertion/abnf/reader/Extractor.java | 30 +++ .../abnf/reader/ExtractorEndsWithNewLine.java | 74 +++++++ .../ExtractorWithEndpositionDetection.java | 31 +++ .../abnf/reader/NewLineDetector.java | 77 +++++++ .../reader/NumericCharactersExtractor.java | 82 ++++++++ .../reader/OptionalSequenceExtractor.java | 61 ++++++ .../abnf/reader/RepetitionExtractor.java | 149 +++++++++++++ .../assertion/abnf/reader/RuleExtractor.java | 128 +++++++++++ .../abnf/reader/RuleNameExtractor.java | 69 ++++++ .../abnf/reader/RuleReferenceExtractor.java | 59 ++++++ .../reader/SequenceGroupElementExtractor.java | 79 +++++++ .../abnf/reader/StringElementExtractor.java | 59 ++++++ .../assertion/abnf/reader/TextABNF.java | 79 +++++++ .../abnf/reader/UsefulCodepoints.java | 38 ++++ .../format/assertion/abnf/RuleTest.java | 48 +++++ .../abnf/element/AlternativeTest.java | 50 +++++ .../abnf/element/ConcatedStringTest.java | 35 +++ .../abnf/element/ConcatenationTest.java | 50 +++++ .../abnf/element/NumericCharacterTest.java | 35 +++ .../abnf/element/OptionalSequenceTest.java | 35 +++ .../assertion/abnf/element/RuleNameTest.java | 35 +++ .../abnf/element/SequenceGroupTest.java | 35 +++ .../abnf/element/SpecificRepetitionTest.java | 35 +++ .../abnf/element/StringElementTest.java | 35 +++ .../element/ValueRangeAlternativesTest.java | 51 +++++ .../abnf/element/VariableRepetitionTest.java | 46 ++++ .../abnf/reader/ElementsExtractorTest.java | 199 ++++++++++++++++++ .../abnf/reader/ExtractableTestString.java | 56 +++++ .../abnf/reader/RuleExtractorTest.java | 111 ++++++++++ .../assertion/abnf/reader/TextABNFTest.java | 103 +++++++++ 53 files changed, 3710 insertions(+), 14 deletions(-) create mode 100644 vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/CoreRules.java create mode 100644 vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/Rule.java create mode 100644 vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/RuleList.java create mode 100644 vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/Alternative.java create mode 100644 vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/ConcatedString.java create mode 100644 vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/Concatenation.java rename vocabulary-format-assertion/src/main/java/{module-info.java => io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/Element.java} (73%) create mode 100644 vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/NumericCharacter.java create mode 100644 vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/OptionalSequence.java create mode 100644 vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/RuleName.java create mode 100644 vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/RuleReference.java create mode 100644 vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/SequenceGroup.java create mode 100644 vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/SpecificRepetition.java create mode 100644 vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/StringElement.java create mode 100644 vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/ValueRangeAlternatives.java create mode 100644 vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/VariableRepetition.java create mode 100644 vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/ABNF.java create mode 100644 vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/AlternativeDecisionMaker.java create mode 100644 vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/AlternativeExtractor.java create mode 100644 vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/CommentaryExtractor.java create mode 100644 vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/ElementToken.java create mode 100644 vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/ElementsExtractor.java create mode 100644 vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/Extractor.java create mode 100644 vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/ExtractorEndsWithNewLine.java create mode 100644 vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/ExtractorWithEndpositionDetection.java create mode 100644 vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/NewLineDetector.java create mode 100644 vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/NumericCharactersExtractor.java create mode 100644 vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/OptionalSequenceExtractor.java create mode 100644 vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/RepetitionExtractor.java create mode 100644 vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/RuleExtractor.java create mode 100644 vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/RuleNameExtractor.java create mode 100644 vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/RuleReferenceExtractor.java create mode 100644 vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/SequenceGroupElementExtractor.java create mode 100644 vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/StringElementExtractor.java create mode 100644 vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/TextABNF.java create mode 100644 vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/UsefulCodepoints.java create mode 100644 vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/RuleTest.java create mode 100644 vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/AlternativeTest.java create mode 100644 vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/ConcatedStringTest.java create mode 100644 vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/ConcatenationTest.java create mode 100644 vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/NumericCharacterTest.java create mode 100644 vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/OptionalSequenceTest.java create mode 100644 vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/RuleNameTest.java create mode 100644 vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/SequenceGroupTest.java create mode 100644 vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/SpecificRepetitionTest.java create mode 100644 vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/StringElementTest.java create mode 100644 vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/ValueRangeAlternativesTest.java create mode 100644 vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/VariableRepetitionTest.java create mode 100644 vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/ElementsExtractorTest.java create mode 100644 vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/ExtractableTestString.java create mode 100644 vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/RuleExtractorTest.java create mode 100644 vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/TextABNFTest.java diff --git a/vocabulary-format-assertion/pom.xml b/vocabulary-format-assertion/pom.xml index 9b8e321f..5c9aed12 100644 --- a/vocabulary-format-assertion/pom.xml +++ b/vocabulary-format-assertion/pom.xml @@ -25,13 +25,11 @@ org.junit.jupiter junit-jupiter-api test - 5.6.0 org.junit.jupiter junit-jupiter-engine test - 5.6.0 org.hamcrest @@ -43,6 +41,11 @@ hamcrest-optional test + + nl.jqno.equalsverifier + equalsverifier + test + ${project.groupId} json-schema-core @@ -61,11 +64,5 @@ parsson test - - org.junit.jupiter - junit-jupiter-params - 5.6.0 - test - diff --git a/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/CoreRules.java b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/CoreRules.java new file mode 100644 index 00000000..eebf95b3 --- /dev/null +++ b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/CoreRules.java @@ -0,0 +1,165 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf; + +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.Alternative; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.Element; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.NumericCharacter; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.RuleName; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.StringElement; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.ValueRangeAlternatives; + +public enum CoreRules implements Element { + ALPHA() { + @Override + public boolean isValidFor(final int codePoint) { + return Alternative + .of( + ValueRangeAlternatives.of( + NumericCharacter.of(NumericCharacter.BASE.HEXADECIMAL, 0x41), + NumericCharacter.of(NumericCharacter.BASE.HEXADECIMAL, 0x51A) + ), + ValueRangeAlternatives.of( + NumericCharacter.of(NumericCharacter.BASE.HEXADECIMAL, 0x61), + NumericCharacter.of(NumericCharacter.BASE.HEXADECIMAL, 0x7A) + ) + ) + .isValidFor(codePoint); + } + }, + BIT() { + @Override + public boolean isValidFor(final int codePoint) { + return Alternative.of(StringElement.of("0"), StringElement.of("1")).isValidFor(codePoint); + } + }, + CHAR() { + @Override + public boolean isValidFor(final int codePoint) { + return ValueRangeAlternatives + .of( + NumericCharacter.of(NumericCharacter.BASE.HEXADECIMAL, 0x01), + NumericCharacter.of(NumericCharacter.BASE.HEXADECIMAL, 0x7F) + ) + .isValidFor(codePoint); + } + }, + CR() { + @Override + public boolean isValidFor(final int codePoint) { + return NumericCharacter.of(NumericCharacter.BASE.HEXADECIMAL, 0x0D).isValidFor(codePoint); + } + }, + CRLF, //CR LF + CTL, //%x00-1F / %x7F + DIGIT() { + @Override + public boolean isValidFor(final int codePoint) { + return ValueRangeAlternatives + .of( + NumericCharacter.of(NumericCharacter.BASE.HEXADECIMAL, 0x30), + NumericCharacter.of(NumericCharacter.BASE.HEXADECIMAL, 0x39) + ) + .isValidFor(codePoint); + } + }, + DQUOTE() { + @Override + public boolean isValidFor(final int codePoint) { + return NumericCharacter.of(NumericCharacter.BASE.HEXADECIMAL, 0x22).isValidFor(codePoint); + } + }, + HEXDIG() { + @Override + public boolean isValidFor(final int codePoint) { + return Alternative + .of( + DIGIT, + StringElement.of("A"), + StringElement.of("B"), + StringElement.of("C"), + StringElement.of("D"), + StringElement.of("E"), + StringElement.of("F") + ) + .isValidFor(codePoint); + } + }, + HTAB() { + @Override + public boolean isValidFor(final int codePoint) { + return NumericCharacter.of(NumericCharacter.BASE.HEXADECIMAL, 0x09).isValidFor(codePoint); + } + }, + LF() { + @Override + public boolean isValidFor(final int codePoint) { + return NumericCharacter.of(NumericCharacter.BASE.HEXADECIMAL, 0x0A).isValidFor(codePoint); + } + }, + LWSP, //*(WSP / CRLF WSP) + OCTET() { + @Override + public boolean isValidFor(final int codePoint) { + return ValueRangeAlternatives + .of( + NumericCharacter.of(NumericCharacter.BASE.HEXADECIMAL, 0x00), + NumericCharacter.of(NumericCharacter.BASE.HEXADECIMAL, 0xFF) + ) + .isValidFor(codePoint); + } + }, + SP() { + @Override + public boolean isValidFor(final int codePoint) { + return NumericCharacter.of(NumericCharacter.BASE.HEXADECIMAL, 0x20).isValidFor(codePoint); + } + }, + VCHAR() { + @Override + public boolean isValidFor(final int codePoint) { + return ValueRangeAlternatives + .of( + NumericCharacter.of(NumericCharacter.BASE.HEXADECIMAL, 0x21), + NumericCharacter.of(NumericCharacter.BASE.HEXADECIMAL, 0x7E) + ) + .isValidFor(codePoint); + } + }, + WSP { + @Override + public boolean isValidFor(final int codePoint) { + return Alternative.of(SP, HTAB).isValidFor(codePoint); + } + }; + + public RuleName asRuleName() { + return RuleName.of(name()); + } + + @Override + public boolean isValidFor(final int codePoint) { + throw new UnsupportedOperationException("Not supported yet."); + } +} diff --git a/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/Rule.java b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/Rule.java new file mode 100644 index 00000000..7645cba3 --- /dev/null +++ b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/Rule.java @@ -0,0 +1,78 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf; + +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.Element; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.RuleName; +import java.util.Objects; + +public final class Rule { + + public static Rule of(final RuleName name, final Element elements) { + return new Rule(name, elements); + } + + private final RuleName name; + private final Element elements; + + private Rule(final RuleName name, final Element elements) { + this.name = Objects.requireNonNull(name); + this.elements = Objects.requireNonNull(elements); + } + + public boolean hasRuleName(final RuleName name) { + return Objects.equals(this.name, name); + } + + @Override + public String toString() { + return "Rule{" + "name=" + name + ", elements=" + elements + '}'; + } + + @Override + public int hashCode() { + int hash = 5; + hash = 83 * hash + Objects.hashCode(this.name); + hash = 83 * hash + Objects.hashCode(this.elements); + return hash; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final Rule other = (Rule) obj; + if (!Objects.equals(this.name, other.name)) { + return false; + } + return Objects.equals(this.elements, other.elements); + } +} diff --git a/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/RuleList.java b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/RuleList.java new file mode 100644 index 00000000..10aa37ba --- /dev/null +++ b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/RuleList.java @@ -0,0 +1,77 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf; + +import static java.util.Arrays.asList; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +public final class RuleList { + + public static RuleList of(final Rule rule, final Rule... rules) { + final List ruleList = new ArrayList<>(); + ruleList.add(Objects.requireNonNull(rule)); + ruleList.addAll(asList(rules)); + return of(ruleList); + } + + public static RuleList of(final List rules) { + return new RuleList(rules); + } + + private final List rules; + + private RuleList(final List rules) { + this.rules = List.copyOf(rules); + } + + @Override + public String toString() { + return "RuleList{" + "rules=" + rules + '}'; + } + + @Override + public int hashCode() { + int hash = 7; + hash = 73 * hash + Objects.hashCode(this.rules); + return hash; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final RuleList other = (RuleList) obj; + return Objects.equals(this.rules, other.rules); + } +} diff --git a/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/Alternative.java b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/Alternative.java new file mode 100644 index 00000000..fdb83bf0 --- /dev/null +++ b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/Alternative.java @@ -0,0 +1,82 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +public final class Alternative implements Element { + + public static Alternative of(final Element left, final Element right, final Element... more) { + final List alternatives = new ArrayList<>(); + alternatives.add(left); + alternatives.add(right); + alternatives.addAll(Arrays.asList(more)); + return of(alternatives); + } + + public static Alternative of(final List alternatives) { + return new Alternative(alternatives); + } + + private final List alternatives; + + private Alternative(final List alternatives) { + this.alternatives = List.copyOf(alternatives); + } + + @Override + public boolean isValidFor(final int codePoint) { + return alternatives.stream().anyMatch(e -> e.isValidFor(codePoint)); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 41 * hash + Objects.hashCode(this.alternatives); + return hash; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final Alternative other = (Alternative) obj; + return Objects.equals(this.alternatives, other.alternatives); + } + + @Override + public String toString() { + return "Alternative{" + "alternatives=" + alternatives + '}'; + } +} diff --git a/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/ConcatedString.java b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/ConcatedString.java new file mode 100644 index 00000000..10c01bc9 --- /dev/null +++ b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/ConcatedString.java @@ -0,0 +1,87 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Objects; + +public final class ConcatedString implements Element { + + public static ConcatedString of( + final NumericCharacter first, + final NumericCharacter second, + final NumericCharacter... more + ) { + final List values = new ArrayList<>(); + values.add(first); + values.add(second); + values.addAll(Arrays.asList(more)); + return new ConcatedString(values); + } + + public static ConcatedString of(final Collection values) { + return new ConcatedString(values); + } + + private final Collection values; + + private ConcatedString(final Collection values) { + this.values = List.copyOf(values); + } + + @Override + public boolean isValidFor(final int codePoint) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int hashCode() { + int hash = 3; + hash = 23 * hash + Objects.hashCode(this.values); + return hash; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final ConcatedString other = (ConcatedString) obj; + return Objects.equals(this.values, other.values); + } + + @Override + public String toString() { + return "ConcatedString{" + "values=" + values + '}'; + } +} diff --git a/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/Concatenation.java b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/Concatenation.java new file mode 100644 index 00000000..543a9b02 --- /dev/null +++ b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/Concatenation.java @@ -0,0 +1,82 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +public final class Concatenation implements Element { + + public static Concatenation of(final Element left, final Element right, final Element... more) { + final List concatenations = new ArrayList<>(); + concatenations.add(left); + concatenations.add(right); + concatenations.addAll(Arrays.asList(more)); + return of(concatenations); + } + + public static Concatenation of(final List alternatives) { + return new Concatenation(alternatives); + } + + private final List concatenations; + + private Concatenation(final List concatenations) { + this.concatenations = List.copyOf(concatenations); + } + + @Override + public boolean isValidFor(final int codePoint) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int hashCode() { + int hash = 5; + hash = 97 * hash + Objects.hashCode(this.concatenations); + return hash; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final Concatenation other = (Concatenation) obj; + return Objects.equals(this.concatenations, other.concatenations); + } + + @Override + public String toString() { + return "Concatenation{" + "concatenation=" + concatenations + '}'; + } +} diff --git a/vocabulary-format-assertion/src/main/java/module-info.java b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/Element.java similarity index 73% rename from vocabulary-format-assertion/src/main/java/module-info.java rename to vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/Element.java index 66c685cd..ad3999c7 100644 --- a/vocabulary-format-assertion/src/main/java/module-info.java +++ b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/Element.java @@ -21,11 +21,9 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -module io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion { - requires io.github.sebastiantoepfer.jsonschema.vocabulary.spi; - requires io.github.sebastiantoepfer.jsonschema; - requires jakarta.json; +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element; - provides io.github.sebastiantoepfer.jsonschema.vocabulary.spi.LazyVocabularies - with io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.FormatAssertionVocabulary; +public interface Element { + //no no, but let get start simple + boolean isValidFor(int codePoint); } diff --git a/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/NumericCharacter.java b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/NumericCharacter.java new file mode 100644 index 00000000..fa495fc7 --- /dev/null +++ b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/NumericCharacter.java @@ -0,0 +1,109 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element; + +import java.util.Arrays; +import java.util.Objects; + +public final class NumericCharacter implements Element { + + public static NumericCharacter of(final BASE base, final int value) { + return new NumericCharacter(base, value); + } + + private final BASE base; + private final int value; + + private NumericCharacter(final BASE base, final int value) { + this.base = Objects.requireNonNull(base); + this.value = value; + } + + @Override + public boolean isValidFor(final int codePoint) { + return value == codePoint; + } + + boolean lessThanOrEquals(final int codePoint) { + return value <= codePoint; + } + + boolean greatherThaneOrEquals(final int codePoint) { + return value >= codePoint; + } + + @Override + public int hashCode() { + int hash = 5; + hash = 97 * hash + Objects.hashCode(value); + return hash; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final NumericCharacter other = (NumericCharacter) obj; + return value == other.value; + } + + @Override + public String toString() { + return "NumericCharacter{" + "base=" + base + ", value=" + value + '}'; + } + + public enum BASE { + BINARY('b', 2), + DECIMAL('d', 10), + HEXADECIMAL('x', 16); + + private final char baseShortName; + private final int radix; + + private BASE(final char baseShortName, final int base) { + this.baseShortName = baseShortName; + this.radix = base; + } + + public Integer convert(final String value) { + return Integer.valueOf(value, radix); + } + + public static BASE findByShortName(final char baseChar) { + return Arrays + .stream(BASE.values()) + .filter(b -> b.baseShortName == baseChar) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException(String.format("\"%c\" is not a valid base!", baseChar)) + ); + } + } +} diff --git a/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/OptionalSequence.java b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/OptionalSequence.java new file mode 100644 index 00000000..7579338d --- /dev/null +++ b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/OptionalSequence.java @@ -0,0 +1,71 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element; + +import java.util.Objects; + +public final class OptionalSequence implements Element { + + public static OptionalSequence of(final Element optionalElement) { + return new OptionalSequence(optionalElement); + } + + private final Element optionalElement; + + public OptionalSequence(final Element optionalElement) { + this.optionalElement = Objects.requireNonNull(optionalElement); + } + + @Override + public boolean isValidFor(final int codePoint) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public String toString() { + return "OptionalSequence{" + "optionalElement=" + optionalElement + '}'; + } + + @Override + public int hashCode() { + int hash = 7; + hash = 67 * hash + Objects.hashCode(this.optionalElement); + return hash; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final OptionalSequence other = (OptionalSequence) obj; + return Objects.equals(this.optionalElement, other.optionalElement); + } +} diff --git a/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/RuleName.java b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/RuleName.java new file mode 100644 index 00000000..5521649b --- /dev/null +++ b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/RuleName.java @@ -0,0 +1,67 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element; + +import java.util.Locale; +import java.util.Objects; + +public final class RuleName { + + public static RuleName of(final String name) { + return new RuleName(name); + } + + private final String name; + + private RuleName(final String name) { + this.name = name.toLowerCase(Locale.US); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 67 * hash + Objects.hashCode(this.name); + return hash; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final RuleName other = (RuleName) obj; + return Objects.equals(this.name, other.name); + } + + @Override + public String toString() { + return "RuleName{" + "name=" + name + '}'; + } +} diff --git a/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/RuleReference.java b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/RuleReference.java new file mode 100644 index 00000000..0d7bb644 --- /dev/null +++ b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/RuleReference.java @@ -0,0 +1,71 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element; + +import java.util.Objects; + +public final class RuleReference implements Element { + + public static RuleReference of(final RuleName name) { + return new RuleReference(name); + } + + private final RuleName name; + + private RuleReference(final RuleName name) { + this.name = name; + } + + @Override + public boolean isValidFor(final int codePoint) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public String toString() { + return "RuleReference{" + "name=" + name + '}'; + } + + @Override + public int hashCode() { + int hash = 3; + hash = 79 * hash + Objects.hashCode(this.name); + return hash; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final RuleReference other = (RuleReference) obj; + return Objects.equals(this.name, other.name); + } +} diff --git a/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/SequenceGroup.java b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/SequenceGroup.java new file mode 100644 index 00000000..b201689a --- /dev/null +++ b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/SequenceGroup.java @@ -0,0 +1,71 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element; + +import java.util.Objects; + +public final class SequenceGroup implements Element { + + public static SequenceGroup of(final Element term) { + return new SequenceGroup(term); + } + + private final Element term; + + private SequenceGroup(final Element term) { + this.term = Objects.requireNonNull(term); + } + + @Override + public boolean isValidFor(final int codePoint) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int hashCode() { + int hash = 3; + hash = 83 * hash + Objects.hashCode(this.term); + return hash; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final SequenceGroup other = (SequenceGroup) obj; + return Objects.equals(this.term, other.term); + } + + @Override + public String toString() { + return "SequenceGroup{" + "term=" + term + '}'; + } +} diff --git a/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/SpecificRepetition.java b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/SpecificRepetition.java new file mode 100644 index 00000000..f6eaade4 --- /dev/null +++ b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/SpecificRepetition.java @@ -0,0 +1,77 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element; + +import java.util.Objects; + +public final class SpecificRepetition implements Element { + + public static SpecificRepetition of(final Element elementToRepeat, final int occurences) { + return new SpecificRepetition(elementToRepeat, occurences); + } + + private final Element elementToRepeat; + private final int occurences; + + private SpecificRepetition(final Element elementToRepeat, final int occurences) { + this.elementToRepeat = Objects.requireNonNull(elementToRepeat); + this.occurences = occurences; + } + + @Override + public boolean isValidFor(final int codePoint) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public String toString() { + return "SpecificRepetition{" + "elementToRepeat=" + elementToRepeat + ", occurences=" + occurences + '}'; + } + + @Override + public int hashCode() { + int hash = 5; + hash = 89 * hash + Objects.hashCode(this.elementToRepeat); + hash = 89 * hash + this.occurences; + return hash; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final SpecificRepetition other = (SpecificRepetition) obj; + if (this.occurences != other.occurences) { + return false; + } + return Objects.equals(this.elementToRepeat, other.elementToRepeat); + } +} diff --git a/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/StringElement.java b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/StringElement.java new file mode 100644 index 00000000..d18e76af --- /dev/null +++ b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/StringElement.java @@ -0,0 +1,76 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element; + +import java.util.Locale; +import java.util.Objects; + +public final class StringElement implements Element { + + public static StringElement of(final String value) { + return new StringElement(value); + } + + private final String value; + + private StringElement(final String value) { + this.value = value.toLowerCase(Locale.US); + } + + @Override + public boolean isValidFor(final int codePoint) { + if (value.length() == 1) { + final int lowerCaseCodePoint = value.codePointAt(0); + return lowerCaseCodePoint == codePoint || Character.toUpperCase(lowerCaseCodePoint) == codePoint; + } + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 17 * hash + Objects.hashCode(this.value); + return hash; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final StringElement other = (StringElement) obj; + return Objects.equals(this.value, other.value); + } + + @Override + public String toString() { + return "StringElement{" + "value=" + value + '}'; + } +} diff --git a/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/ValueRangeAlternatives.java b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/ValueRangeAlternatives.java new file mode 100644 index 00000000..39e14ab2 --- /dev/null +++ b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/ValueRangeAlternatives.java @@ -0,0 +1,77 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element; + +import java.util.Objects; + +public final class ValueRangeAlternatives implements Element { + + public static ValueRangeAlternatives of(final NumericCharacter start, final NumericCharacter end) { + return new ValueRangeAlternatives(start, end); + } + + private final NumericCharacter start; + private final NumericCharacter end; + + public ValueRangeAlternatives(final NumericCharacter start, final NumericCharacter end) { + this.start = start; + this.end = end; + } + + @Override + public boolean isValidFor(final int codePoint) { + return start.lessThanOrEquals(codePoint) && end.greatherThaneOrEquals(codePoint); + } + + @Override + public String toString() { + return "ValueRange{" + "start=" + start + ", end=" + end + '}'; + } + + @Override + public int hashCode() { + int hash = 5; + hash = 89 * hash + Objects.hashCode(this.start); + hash = 89 * hash + Objects.hashCode(this.end); + return hash; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final ValueRangeAlternatives other = (ValueRangeAlternatives) obj; + if (!Objects.equals(this.start, other.start)) { + return false; + } + return Objects.equals(this.end, other.end); + } +} diff --git a/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/VariableRepetition.java b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/VariableRepetition.java new file mode 100644 index 00000000..02acd3ed --- /dev/null +++ b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/VariableRepetition.java @@ -0,0 +1,108 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element; + +import java.util.Objects; + +public final class VariableRepetition implements Element { + + public static VariableRepetition of(final Element element) { + return ofAtLeast(element, 0); + } + + public static VariableRepetition ofAtLeast(final Element element, final int minOccurrences) { + return ofBetween(element, minOccurrences, Integer.MAX_VALUE); + } + + public static VariableRepetition ofAtMost(final Element element, final int maxOccurrences) { + return ofBetween(element, 0, maxOccurrences); + } + + public static VariableRepetition ofExactly(final Element element, final int exactly) { + return ofBetween(element, exactly, exactly); + } + + public static VariableRepetition ofBetween(final Element element, final int min, final int max) { + return new VariableRepetition(element, min, max); + } + + private final int minOccurrences; + private final int maxOccurrences; + private final Element element; + + private VariableRepetition(final Element element, final int minOccurrences, final int maxOccurrences) { + this.minOccurrences = minOccurrences; + this.maxOccurrences = maxOccurrences; + this.element = Objects.requireNonNull(element); + } + + @Override + public boolean isValidFor(final int codePoint) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int hashCode() { + int hash = 3; + hash = 17 * hash + this.minOccurrences; + hash = 17 * hash + this.maxOccurrences; + hash = 17 * hash + Objects.hashCode(this.element); + return hash; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final VariableRepetition other = (VariableRepetition) obj; + if (this.minOccurrences != other.minOccurrences) { + return false; + } + if (this.maxOccurrences != other.maxOccurrences) { + return false; + } + return Objects.equals(this.element, other.element); + } + + @Override + public String toString() { + return ( + "VariableRepetition{" + + "minOccurrences=" + + minOccurrences + + ", maxOccurrences=" + + maxOccurrences + + ", element=" + + element + + '}' + ); + } +} diff --git a/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/ABNF.java b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/ABNF.java new file mode 100644 index 00000000..3b2d3f30 --- /dev/null +++ b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/ABNF.java @@ -0,0 +1,30 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.reader; + +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.RuleList; + +public interface ABNF { + RuleList rules(); +} diff --git a/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/AlternativeDecisionMaker.java b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/AlternativeDecisionMaker.java new file mode 100644 index 00000000..186a3492 --- /dev/null +++ b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/AlternativeDecisionMaker.java @@ -0,0 +1,72 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.reader; + +import static io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.reader.UsefulCodepoints.SOLIDUS; + +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.Element; +import java.util.Objects; +import java.util.function.Supplier; + +class AlternativeDecisionMaker implements ExtractorWithEndpositionDetection { + + public static ExtractorWithEndpositionDetection of( + final ExtractorWithEndpositionDetection posibleAlternative, + final Supplier> newElementExtractor + ) { + return new AlternativeDecisionMaker(posibleAlternative, newElementExtractor); + } + + private final ExtractorWithEndpositionDetection posibleAlternative; + private final Supplier> newElementExtractor; + + private AlternativeDecisionMaker( + final ExtractorWithEndpositionDetection posibleAlternative, + final Supplier> newElementExtractor + ) { + this.posibleAlternative = Objects.requireNonNull(posibleAlternative); + this.newElementExtractor = Objects.requireNonNull(newElementExtractor); + } + + @Override + public boolean hasNoInteresedIn(final int codePoint) { + return codePoint != SOLIDUS && posibleAlternative.hasNoInteresedIn(codePoint); + } + + @Override + public ExtractorWithEndpositionDetection append(final int codePoint) { + final ExtractorWithEndpositionDetection result; + if (codePoint == SOLIDUS) { + result = AlternativeExtractor.of(posibleAlternative, newElementExtractor); + } else { + result = new AlternativeDecisionMaker(posibleAlternative.append(codePoint), newElementExtractor); + } + return result; + } + + @Override + public Element create() { + return posibleAlternative.create(); + } +} diff --git a/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/AlternativeExtractor.java b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/AlternativeExtractor.java new file mode 100644 index 00000000..d7343689 --- /dev/null +++ b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/AlternativeExtractor.java @@ -0,0 +1,99 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.reader; + +import static io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.reader.UsefulCodepoints.SOLIDUS; + +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.Alternative; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.Element; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +final class AlternativeExtractor implements ExtractorWithEndpositionDetection { + + public static ExtractorWithEndpositionDetection of( + final Extractor first, + final Supplier> newElementExtractor + ) { + return new AlternativeExtractor(first, newElementExtractor); + } + + private final List> left; + private final Supplier> newElementExtractor; + private final ExtractorWithEndpositionDetection currentElement; + + public AlternativeExtractor( + final Extractor left, + final Supplier> newElementExtractor + ) { + this(List.of(left), newElementExtractor); + } + + public AlternativeExtractor( + final List> left, + final Supplier> newElementExtractor + ) { + this(left, newElementExtractor, newElementExtractor.get()); + } + + public AlternativeExtractor( + final List> left, + final Supplier> newElementExtractor, + final ExtractorWithEndpositionDetection currentElement + ) { + this.left = Objects.requireNonNull(left); + this.newElementExtractor = Objects.requireNonNull(newElementExtractor); + this.currentElement = Objects.requireNonNull(currentElement); + } + + @Override + public boolean hasNoInteresedIn(final int codePoint) { + return codePoint != SOLIDUS && currentElement.hasNoInteresedIn(codePoint); + } + + @Override + public ExtractorWithEndpositionDetection append(final int codePoint) { + final AlternativeExtractor result; + if (codePoint == SOLIDUS) { + final ArrayList> newLeft = new ArrayList<>(left); + newLeft.add(currentElement); + result = new AlternativeExtractor(newLeft, newElementExtractor, newElementExtractor.get()); + } else { + result = new AlternativeExtractor(left, newElementExtractor, currentElement.append(codePoint)); + } + return result; + } + + @Override + public Element create() { + return Stream + .concat(left.stream(), Stream.of(currentElement)) + .map(Extractor::create) + .collect(Collectors.collectingAndThen(Collectors.toList(), Alternative::of)); + } +} diff --git a/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/CommentaryExtractor.java b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/CommentaryExtractor.java new file mode 100644 index 00000000..e38540be --- /dev/null +++ b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/CommentaryExtractor.java @@ -0,0 +1,63 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.reader; + +import java.util.logging.Logger; + +final class CommentaryExtractor implements Extractor { + + private static final Logger LOG = Logger.getLogger(CommentaryExtractor.class.getName()); + + static CommentaryExtractor startCommentary() { + return new CommentaryExtractor(); + } + + private final NewLineDetector newLine; + + public CommentaryExtractor() { + this(new NewLineDetector()); + } + + public CommentaryExtractor(final NewLineDetector newLine) { + this.newLine = newLine; + } + + @Override + public CommentaryExtractor append(final int codePoint) { + LOG.entering(CommentaryExtractor.class.getName(), "append", codePoint); + final CommentaryExtractor result = new CommentaryExtractor(newLine.append(codePoint)); + LOG.exiting(CommentaryExtractor.class.getName(), "append", result); + return result; + } + + @Override + public String create() { + return ""; + } + + @Override + public String toString() { + return "CommentaryExtractor{" + "newLine=" + newLine + '}'; + } +} diff --git a/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/ElementToken.java b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/ElementToken.java new file mode 100644 index 00000000..72e0c369 --- /dev/null +++ b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/ElementToken.java @@ -0,0 +1,30 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.reader; + +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.Element; + +interface ElementToken { + Element createElement(); +} diff --git a/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/ElementsExtractor.java b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/ElementsExtractor.java new file mode 100644 index 00000000..ed5b0c8d --- /dev/null +++ b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/ElementsExtractor.java @@ -0,0 +1,135 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.reader; + +import static io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.reader.UsefulCodepoints.ASTERISK; +import static io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.reader.UsefulCodepoints.LEFT_PARENTHESIS; +import static io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.reader.UsefulCodepoints.LEFT_SQUARE_BRACKET; +import static io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.reader.UsefulCodepoints.QUOTATION_MARK; + +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.Concatenation; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.Element; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +final class ElementsExtractor implements ExtractorWithEndpositionDetection { + + static ElementsExtractor startElements() { + return new ElementsExtractor(); + } + + private final List> elements; + private ExtractorWithEndpositionDetection currentElement; + + public ElementsExtractor() { + this(List.of(), null); + } + + private ElementsExtractor( + final List> elements, + final ExtractorWithEndpositionDetection currentElement + ) { + this.elements = elements; + this.currentElement = currentElement; + } + + @Override + public boolean hasNoInteresedIn(final int codePoint) { + return currentElement != null && currentElement.hasNoInteresedIn(codePoint); + } + + @Override + public Element create() { + final Element result; + if (currentElement == null && elements.size() == 1) { + result = elements.iterator().next().create(); + } else if (currentElement == null) { + result = + elements + .stream() + .map(Extractor::create) + .collect(Collectors.collectingAndThen(Collectors.toList(), Concatenation::of)); + } else if (elements.isEmpty()) { + result = currentElement.create(); + } else { + result = + Stream + .concat(elements.stream(), Stream.of(currentElement)) + .map(Extractor::create) + .collect(Collectors.collectingAndThen(Collectors.toList(), Concatenation::of)); + } + return result; + } + + @Override + public ExtractorWithEndpositionDetection append(final int codePoint) { + final ExtractorWithEndpositionDetection result; + if (currentElement == null && Character.isWhitespace(codePoint)) { + result = this; + } else if (currentElement == null) { + if (Character.isDigit(codePoint) || codePoint == ASTERISK) { + result = + new ElementsExtractor( + elements, + RepetitionExtractor.of(c -> ElementsExtractor.startElements().append(c), codePoint) + ); + } else if (codePoint == NumericCharactersExtractor.PERCENT_SIGN) { + result = + AlternativeDecisionMaker.of( + new ElementsExtractor(elements, NumericCharactersExtractor.of()), + ElementsExtractor::startElements + ); + } else if (codePoint == LEFT_PARENTHESIS) { + result = new ElementsExtractor(elements, SequenceGroupElementExtractor.startSequenceGroup()); + } else if (codePoint == LEFT_SQUARE_BRACKET) { + result = + new ElementsExtractor(elements, new OptionalSequenceExtractor(ElementsExtractor::startElements)); + } else if (codePoint == QUOTATION_MARK) { + result = + AlternativeDecisionMaker.of( + new ElementsExtractor(elements, StringElementExtractor.startNewSting()), + ElementsExtractor::startElements + ); + } else if (Character.isAlphabetic(codePoint)) { + result = + AlternativeDecisionMaker.of( + new ElementsExtractor(elements, RuleReferenceExtractor.of(codePoint)), + ElementsExtractor::startElements + ); + } else { + result = this; + } + } else if (currentElement.hasNoInteresedIn(codePoint)) { + final List> newElements = new ArrayList<>(); + newElements.addAll(elements); + newElements.add(currentElement); + result = new ElementsExtractor(newElements, null).append(codePoint); + } else { + result = new ElementsExtractor(elements, currentElement.append(codePoint)); + } + return result; + } +} diff --git a/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/Extractor.java b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/Extractor.java new file mode 100644 index 00000000..dd3fb40d --- /dev/null +++ b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/Extractor.java @@ -0,0 +1,30 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.reader; + +interface Extractor { + Extractor append(int codePoint); + + T create(); +} diff --git a/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/ExtractorEndsWithNewLine.java b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/ExtractorEndsWithNewLine.java new file mode 100644 index 00000000..90878c5c --- /dev/null +++ b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/ExtractorEndsWithNewLine.java @@ -0,0 +1,74 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.reader; + +import java.util.logging.Logger; + +final class ExtractorEndsWithNewLine implements ExtractorWithEndpositionDetection { + + private static final Logger LOG = Logger.getLogger(ExtractorEndsWithNewLine.class.getName()); + + public static ExtractorEndsWithNewLine of(final Extractor extractor) { + return new ExtractorEndsWithNewLine<>(extractor); + } + + private final Extractor extractor; + private final NewLineDetector newLine; + + private ExtractorEndsWithNewLine(final Extractor extractor) { + this(extractor, new NewLineDetector()); + } + + private ExtractorEndsWithNewLine(final Extractor extractor, final NewLineDetector newLine) { + this.extractor = extractor; + this.newLine = newLine; + } + + @Override + public boolean hasNoInteresedIn(final int codePoint) { + LOG.entering(ExtractorEndsWithNewLine.class.getName(), "hasNoInteresedIn", codePoint); + final boolean result = newLine.hasNoInteresedIn(codePoint); + LOG.exiting(ExtractorEndsWithNewLine.class.getName(), "hasNoInteresedIn", result); + return result; + } + + @Override + public ExtractorWithEndpositionDetection append(final int codePoint) { + LOG.entering(ExtractorEndsWithNewLine.class.getName(), "append", codePoint); + final ExtractorEndsWithNewLine result = new ExtractorEndsWithNewLine<>( + extractor.append(codePoint), + newLine.append(codePoint) + ); + LOG.exiting(ExtractorEndsWithNewLine.class.getName(), "append", result); + return result; + } + + @Override + public T create() { + LOG.entering(ExtractorEndsWithNewLine.class.getName(), "create"); + final T result = extractor.create(); + LOG.exiting(ExtractorEndsWithNewLine.class.getName(), "create", result); + return result; + } +} diff --git a/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/ExtractorWithEndpositionDetection.java b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/ExtractorWithEndpositionDetection.java new file mode 100644 index 00000000..7776454c --- /dev/null +++ b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/ExtractorWithEndpositionDetection.java @@ -0,0 +1,31 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.reader; + +interface ExtractorWithEndpositionDetection extends Extractor { + boolean hasNoInteresedIn(int codePoint); + + @Override + ExtractorWithEndpositionDetection append(int codePoint); +} diff --git a/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/NewLineDetector.java b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/NewLineDetector.java new file mode 100644 index 00000000..5ea48878 --- /dev/null +++ b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/NewLineDetector.java @@ -0,0 +1,77 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.reader; + +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.CoreRules; +import java.util.logging.Logger; + +final class NewLineDetector implements ExtractorWithEndpositionDetection { + + private static final Logger LOG = Logger.getLogger(NewLineDetector.class.getName()); + + private final boolean cr; + private final boolean lf; + + public NewLineDetector() { + this(false, false); + } + + private NewLineDetector(final boolean cr, final boolean lf) { + this.cr = cr; + this.lf = lf; + } + + @Override + public boolean hasNoInteresedIn(final int codePoint) { + LOG.entering(NewLineDetector.class.getName(), "hasNoInteresedIn", codePoint); + final boolean result = !CoreRules.WSP.isValidFor(codePoint) && cr && lf; + LOG.exiting(NewLineDetector.class.getName(), "hasNoInteresedIn", result); + return result; + } + + @Override + public NewLineDetector append(final int codePoint) { + LOG.entering(NewLineDetector.class.getName(), "append", codePoint); + final NewLineDetector result; + if (cr && CoreRules.LF.isValidFor(codePoint)) { + result = new NewLineDetector(cr, true); + } else if (cr) { + result = new NewLineDetector(); + } else { + result = new NewLineDetector(CoreRules.CR.isValidFor(codePoint), false); + } + LOG.exiting(NewLineDetector.class.getName(), "append", result); + return result; + } + + @Override + public String create() { + return ""; + } + + @Override + public String toString() { + return "NewLineDetector{" + "cr=" + cr + ", lf=" + lf + '}'; + } +} diff --git a/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/NumericCharactersExtractor.java b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/NumericCharactersExtractor.java new file mode 100644 index 00000000..037cf1d0 --- /dev/null +++ b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/NumericCharactersExtractor.java @@ -0,0 +1,82 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.reader; + +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.Element; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.NumericCharacter; +import java.util.logging.Logger; + +final class NumericCharactersExtractor implements ExtractorWithEndpositionDetection { + + private static final Logger LOG = Logger.getLogger(NumericCharactersExtractor.class.getName()); + static final int PERCENT_SIGN = 0x25; + + static NumericCharactersExtractor of() { + return new NumericCharactersExtractor(); + } + + private final NumericCharacter.BASE base; + private final StringBuilder value; + + private NumericCharactersExtractor() { + this(null, new StringBuilder()); + } + + public NumericCharactersExtractor(final NumericCharacter.BASE base, final StringBuilder value) { + this.base = base; + this.value = value; + } + + @Override + public boolean hasNoInteresedIn(final int codePoint) { + return Character.isWhitespace(codePoint); + } + + @Override + public ExtractorWithEndpositionDetection append(final int codePoint) { + LOG.entering(NumericCharactersExtractor.class.getName(), "append", codePoint); + final ExtractorWithEndpositionDetection result; + if (base == null && Character.isAlphabetic(codePoint)) { + result = + new NumericCharactersExtractor( + NumericCharacter.BASE.findByShortName(Character.toChars(codePoint)[0]), + value + ); + } else if (base == null) { + throw new IllegalStateException(); + } else { + result = new NumericCharactersExtractor(base, value.appendCodePoint(codePoint)); + } + LOG.entering(NumericCharactersExtractor.class.getName(), "append", result); + return result; + } + + @Override + public Element create() { + LOG.entering(NumericCharactersExtractor.class.getName(), "create"); + final NumericCharacter result = NumericCharacter.of(base, base.convert(value.toString())); + LOG.entering(NumericCharactersExtractor.class.getName(), "create"); + return result; + } +} diff --git a/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/OptionalSequenceExtractor.java b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/OptionalSequenceExtractor.java new file mode 100644 index 00000000..ff483b71 --- /dev/null +++ b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/OptionalSequenceExtractor.java @@ -0,0 +1,61 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.reader; + +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.Element; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.OptionalSequence; +import java.util.function.Supplier; + +final class OptionalSequenceExtractor implements ExtractorWithEndpositionDetection { + + private final Supplier> newElementExtractor; + private final ExtractorWithEndpositionDetection currentElement; + + public OptionalSequenceExtractor(final Supplier> newElementExtractor) { + this(newElementExtractor, newElementExtractor.get()); + } + + private OptionalSequenceExtractor( + final Supplier> newElementExtractor, + final ExtractorWithEndpositionDetection currentElement + ) { + this.newElementExtractor = newElementExtractor; + this.currentElement = currentElement; + } + + @Override + public boolean hasNoInteresedIn(final int codePoint) { + return codePoint == UsefulCodepoints.RIGHT_SQUARE_BRACKET || currentElement.hasNoInteresedIn(codePoint); + } + + @Override + public ExtractorWithEndpositionDetection append(final int codePoint) { + return new OptionalSequenceExtractor(newElementExtractor, currentElement.append(codePoint)); + } + + @Override + public Element create() { + return OptionalSequence.of(currentElement.create()); + } +} diff --git a/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/RepetitionExtractor.java b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/RepetitionExtractor.java new file mode 100644 index 00000000..fb65d1da --- /dev/null +++ b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/RepetitionExtractor.java @@ -0,0 +1,149 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.reader; + +import static io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.reader.UsefulCodepoints.ASTERISK; + +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.Element; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.SpecificRepetition; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.VariableRepetition; +import java.util.Objects; +import java.util.function.IntFunction; +import java.util.logging.Logger; + +final class RepetitionExtractor implements ExtractorWithEndpositionDetection { + + private static final Logger LOG = Logger.getLogger(RepetitionExtractor.class.getName()); + + static RepetitionExtractor of( + final IntFunction> extractorGenerator, + final int codePoint + ) { + final RepetitionExtractor result; + if (Character.isDigit(codePoint)) { + result = new RepetitionExtractor(extractorGenerator, Integer.valueOf(Character.toString(codePoint))); + } else { + result = new RepetitionExtractor(extractorGenerator); + } + return result; + } + + private final IntFunction> extractorGenerator; + private final Integer atLeast; + private final boolean variable; + private final Integer atMost; + private ExtractorWithEndpositionDetection element; + + private RepetitionExtractor(final IntFunction> extractorGenerator) { + this(extractorGenerator, null, true); + } + + private RepetitionExtractor( + final IntFunction> extractorGenerator, + final Integer atLeast + ) { + this(extractorGenerator, atLeast, false); + } + + private RepetitionExtractor( + final IntFunction> extractorGenerator, + final Integer atLeast, + final boolean variable + ) { + this(extractorGenerator, atLeast, variable, null, null); + } + + private RepetitionExtractor( + final IntFunction> extractorGenerator, + final Integer atLeast, + final boolean variable, + final Integer atMost, + final ExtractorWithEndpositionDetection elements + ) { + this.extractorGenerator = Objects.requireNonNull(extractorGenerator); + this.atLeast = atLeast; + this.variable = variable; + this.atMost = atMost; + this.element = elements; + } + + @Override + public boolean hasNoInteresedIn(final int codePoint) { + return element != null && element.hasNoInteresedIn(codePoint); + } + + @Override + public ExtractorWithEndpositionDetection append(final int codePoint) { + LOG.entering(RepetitionExtractor.class.getName(), "append", codePoint); + final ExtractorWithEndpositionDetection result; + if (element == null && Character.isWhitespace(codePoint)) { + result = this; + } else if (element == null) { + if (codePoint == ASTERISK) { + result = new RepetitionExtractor(extractorGenerator, atLeast, true, atMost, element); + } else if (Character.isDigit(codePoint)) { + result = + new RepetitionExtractor( + extractorGenerator, + atLeast, + variable, + Integer.valueOf(Character.toString(codePoint)), + element + ); + } else { + result = + new RepetitionExtractor( + extractorGenerator, + atLeast, + variable, + atMost, + extractorGenerator.apply(codePoint) + ); + } + } else { + result = new RepetitionExtractor(extractorGenerator, atLeast, variable, atMost, element.append(codePoint)); + } + LOG.exiting(RepetitionExtractor.class.getName(), "append", result); + return result; + } + + @Override + public Element create() { + LOG.entering(RepetitionExtractor.class.getName(), "create"); + final Element result; + if (variable && atLeast == null && atMost == null) { + result = VariableRepetition.of(element.create()); + } else if (variable && atLeast == null) { + result = VariableRepetition.ofAtMost(element.create(), atMost); + } else if (variable && atMost == null) { + result = VariableRepetition.ofAtLeast(element.create(), atLeast); + } else if (variable) { + result = VariableRepetition.ofBetween(element.create(), atLeast, atMost); + } else { + result = SpecificRepetition.of(element.create(), atLeast); + } + LOG.exiting(RepetitionExtractor.class.getName(), "create", result); + return result; + } +} diff --git a/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/RuleExtractor.java b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/RuleExtractor.java new file mode 100644 index 00000000..1a8fe9ce --- /dev/null +++ b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/RuleExtractor.java @@ -0,0 +1,128 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.reader; + +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.Rule; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.Element; +import java.util.logging.Logger; + +final class RuleExtractor implements ExtractorWithEndpositionDetection { + + private static final Logger LOG = Logger.getLogger(RuleExtractor.class.getName()); + + static RuleExtractor startNewRule(final int codePoint) { + return new RuleExtractor(codePoint); + } + + private final RuleNameExtractor name; + private final ExtractorWithEndpositionDetection elements; + private final ExtractorWithEndpositionDetection commentary; + + public RuleExtractor(final int codePoint) { + this(RuleNameExtractor.of(codePoint), null, null); + } + + private RuleExtractor( + final RuleNameExtractor name, + final ExtractorWithEndpositionDetection elements, + final ExtractorWithEndpositionDetection commentary + ) { + this.name = name; + this.elements = elements; + this.commentary = commentary; + } + + @Override + public boolean hasNoInteresedIn(final int codePoint) { + LOG.entering(RuleExtractor.class.getName(), "hasNoInteresedIn", codePoint); + final boolean result = + (commentary != null && commentary.hasNoInteresedIn(codePoint)) || + (elements != null && elements.hasNoInteresedIn(codePoint)); + LOG.exiting(RuleExtractor.class.getName(), "hasNoInteresedIn", result); + return result; + } + + @Override + public Rule create() { + LOG.entering(RuleExtractor.class.getName(), "createRule"); + final Rule result; + if (elements == null) { + throw new IllegalStateException("no elements"); + } else { + result = Rule.of(name.create(), elements.create()); + } + LOG.exiting(RuleExtractor.class.getName(), "createRule", result); + return result; + } + + @Override + public RuleExtractor append(final int codePoint) { + LOG.entering(RuleExtractor.class.getName(), "append"); + final RuleExtractor result; + if (commentary == null) { + result = processAsNonCommentary(codePoint); + } else { + result = processAsCommentray(codePoint); + } + LOG.exiting(RuleExtractor.class.getName(), "append", result); + return result; + } + + private RuleExtractor processAsNonCommentary(final int codePoint) { + LOG.entering(RuleExtractor.class.getName(), "processAsNonComentary"); + RuleExtractor result; + if (codePoint == 0x3B) { + result = + new RuleExtractor(name, elements, ExtractorEndsWithNewLine.of(CommentaryExtractor.startCommentary())); + } else if (elements == null) { + result = processAsRuleName(codePoint); + } else { + result = new RuleExtractor(name, elements.append(codePoint), commentary); + } + LOG.exiting(RuleExtractor.class.getName(), "processAsNonComentary"); + return result; + } + + private RuleExtractor processAsRuleName(final int codePoint) { + LOG.entering(RuleExtractor.class.getName(), "processAsRuleName"); + RuleExtractor result; + if (codePoint == 0x3D) { + result = + new RuleExtractor(name, ExtractorEndsWithNewLine.of(ElementsExtractor.startElements()), commentary); + } else if (Character.isWhitespace(codePoint)) { + result = this; + } else { + result = new RuleExtractor(name.append(codePoint), elements, commentary); + } + LOG.exiting(RuleExtractor.class.getName(), "processAsRuleName", result); + return result; + } + + private RuleExtractor processAsCommentray(final int codePoint) { + LOG.entering(RuleExtractor.class.getName(), "processAsCommentray", codePoint); + final RuleExtractor result = new RuleExtractor(name, elements, commentary.append(codePoint)); + LOG.exiting(RuleExtractor.class.getName(), "processAsCommentray", result); + return result; + } +} diff --git a/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/RuleNameExtractor.java b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/RuleNameExtractor.java new file mode 100644 index 00000000..0573caa6 --- /dev/null +++ b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/RuleNameExtractor.java @@ -0,0 +1,69 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.reader; + +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.RuleName; +import java.util.logging.Logger; + +final class RuleNameExtractor implements Extractor { + + private static final Logger LOG = Logger.getLogger(RuleNameExtractor.class.getName()); + + public static RuleNameExtractor of(final int codePoint) { + return new RuleNameExtractor(codePoint); + } + + private final StringBuilder name; + + private RuleNameExtractor(final int codePoint) { + this(new StringBuilder().appendCodePoint(codePoint)); + } + + private RuleNameExtractor(final StringBuilder name) { + this.name = name; + } + + @Override + public RuleNameExtractor append(final int codePoint) { + LOG.entering(RuleNameExtractor.class.getName(), "append", codePoint); + final RuleNameExtractor result; + if (Character.isWhitespace(codePoint)) { + result = this; + } else { + result = new RuleNameExtractor(name.appendCodePoint(codePoint)); + } + LOG.exiting(RuleNameExtractor.class.getName(), "append", result); + return result; + } + + @Override + public RuleName create() { + return RuleName.of(name.toString()); + } + + @Override + public String toString() { + return "RuleNameTokens{" + "name=" + name + '}'; + } +} diff --git a/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/RuleReferenceExtractor.java b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/RuleReferenceExtractor.java new file mode 100644 index 00000000..2aa14f51 --- /dev/null +++ b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/RuleReferenceExtractor.java @@ -0,0 +1,59 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.reader; + +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.Element; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.RuleReference; + +final class RuleReferenceExtractor implements ExtractorWithEndpositionDetection { + + public static ExtractorWithEndpositionDetection of(final int codePoint) { + return new RuleReferenceExtractor(codePoint); + } + + private final RuleNameExtractor name; + + private RuleReferenceExtractor(final int codePoint) { + this(RuleNameExtractor.of(codePoint)); + } + + private RuleReferenceExtractor(final RuleNameExtractor name) { + this.name = name; + } + + @Override + public boolean hasNoInteresedIn(final int codePoint) { + return codePoint == UsefulCodepoints.EQUALS_SIGN || Character.isWhitespace(codePoint); + } + + @Override + public ExtractorWithEndpositionDetection append(final int codePoint) { + return new RuleReferenceExtractor(name.append(codePoint)); + } + + @Override + public Element create() { + return RuleReference.of(name.create()); + } +} diff --git a/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/SequenceGroupElementExtractor.java b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/SequenceGroupElementExtractor.java new file mode 100644 index 00000000..ab476c80 --- /dev/null +++ b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/SequenceGroupElementExtractor.java @@ -0,0 +1,79 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.reader; + +import static io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.reader.UsefulCodepoints.RIGHT_PARENTHESIS; + +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.Element; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.SequenceGroup; + +final class SequenceGroupElementExtractor implements ExtractorWithEndpositionDetection { + + public static SequenceGroupElementExtractor startSequenceGroup() { + return new SequenceGroupElementExtractor(); + } + + private final Extractor element; + private final boolean rightParenthesis; + + private SequenceGroupElementExtractor() { + this(null, false); + } + + private SequenceGroupElementExtractor(final Extractor element, final boolean rightParenthesis) { + this.element = element; + this.rightParenthesis = rightParenthesis; + } + + @Override + public boolean hasNoInteresedIn(final int codePoint) { + return rightParenthesis; + } + + @Override + public ExtractorWithEndpositionDetection append(final int codePoint) { + final ExtractorWithEndpositionDetection result; + if (element == null && Character.isWhitespace(codePoint)) { + result = this; + } else if (element == null) { + result = + new SequenceGroupElementExtractor( + ElementsExtractor.startElements().append(codePoint), + rightParenthesis + ); + } else { + if (codePoint == RIGHT_PARENTHESIS) { + result = new SequenceGroupElementExtractor(element, true); + } else { + result = new SequenceGroupElementExtractor(element.append(codePoint), rightParenthesis); + } + } + return result; + } + + @Override + public Element create() { + return SequenceGroup.of(element.create()); + } +} diff --git a/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/StringElementExtractor.java b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/StringElementExtractor.java new file mode 100644 index 00000000..8949e61b --- /dev/null +++ b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/StringElementExtractor.java @@ -0,0 +1,59 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.reader; + +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.Element; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.StringElement; + +final class StringElementExtractor implements ExtractorWithEndpositionDetection { + + static ExtractorWithEndpositionDetection startNewSting() { + return new StringElementExtractor(); + } + + private final StringBuilder value; + + private StringElementExtractor() { + this(new StringBuilder()); + } + + private StringElementExtractor(final StringBuilder value) { + this.value = value; + } + + @Override + public boolean hasNoInteresedIn(final int codePoint) { + return codePoint == UsefulCodepoints.QUOTATION_MARK; + } + + @Override + public ExtractorWithEndpositionDetection append(final int codePoint) { + return new StringElementExtractor(value.appendCodePoint(codePoint)); + } + + @Override + public Element create() { + return StringElement.of(value.toString()); + } +} diff --git a/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/TextABNF.java b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/TextABNF.java new file mode 100644 index 00000000..45f1eb25 --- /dev/null +++ b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/TextABNF.java @@ -0,0 +1,79 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.reader; + +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.Rule; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.RuleList; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +public final class TextABNF implements ABNF { + + private static final Logger LOG = Logger.getLogger(TextABNF.class.getName()); + + public static TextABNF of(final String rules) { + return new TextABNF(rules); + } + + private final String rules; + + private TextABNF(final String rules) { + this.rules = rules; + } + + @Override + public RuleList rules() { + LOG.entering(TextABNF.class.getName(), "rules"); + final List extractedRules = new ArrayList<>(); + RuleExtractor ruleTokens = null; + for (int i = 0, length = rules.length(); i < length; i++) { + final int currentCodePoint = rules.codePointAt(i); + if (ruleTokens == null) { + if (Character.isLetter(currentCodePoint)) { + LOG.log(Level.FINER, "try to create first rule."); + ruleTokens = RuleExtractor.startNewRule(currentCodePoint); + } + } else { + if (ruleTokens.hasNoInteresedIn(currentCodePoint)) { + LOG.log(Level.FINER, "finished creating a rule."); + extractedRules.add(ruleTokens.create()); + if (Character.isLetter(currentCodePoint)) { + LOG.log(Level.FINER, "try to create another rule."); + ruleTokens = RuleExtractor.startNewRule(currentCodePoint); + } + } else { + ruleTokens = ruleTokens.append(currentCodePoint); + } + } + } + if (ruleTokens != null) { + extractedRules.add(ruleTokens.create()); + } + final RuleList result = RuleList.of(extractedRules); + LOG.exiting(TextABNF.class.getName(), "rules", result); + return result; + } +} diff --git a/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/UsefulCodepoints.java b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/UsefulCodepoints.java new file mode 100644 index 00000000..93a7cf45 --- /dev/null +++ b/vocabulary-format-assertion/src/main/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/UsefulCodepoints.java @@ -0,0 +1,38 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.reader; + +final class UsefulCodepoints { + + static final int QUOTATION_MARK = 0x22; + static final int LEFT_PARENTHESIS = 0x28; + static final int RIGHT_PARENTHESIS = 0x29; + static final int ASTERISK = 0x2A; + static final int SOLIDUS = 0x2F; + static final int EQUALS_SIGN = 0x3D; + static final int LEFT_SQUARE_BRACKET = 0x5B; + static final int RIGHT_SQUARE_BRACKET = 0x5D; + + private UsefulCodepoints() {} +} diff --git a/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/RuleTest.java b/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/RuleTest.java new file mode 100644 index 00000000..8a1d89e7 --- /dev/null +++ b/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/RuleTest.java @@ -0,0 +1,48 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.RuleName; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.RuleReference; +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.Test; + +class RuleTest { + + @Test + void equalsContract() { + EqualsVerifier.forClass(Rule.class).verify(); + } + + @Test + void should_know_his_name() { + final Rule rule = Rule.of(RuleName.of("date"), RuleReference.of(RuleName.of("DIGIT"))); + + assertThat(rule.hasRuleName(RuleName.of("date")), is(true)); + assertThat(rule.hasRuleName(RuleName.of("iso-date-time")), is(false)); + } +} diff --git a/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/AlternativeTest.java b/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/AlternativeTest.java new file mode 100644 index 00000000..060ee140 --- /dev/null +++ b/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/AlternativeTest.java @@ -0,0 +1,50 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.both; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.nullValue; + +import java.util.List; +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.Test; + +class AlternativeTest { + + @Test + void equalsContract() { + EqualsVerifier.forClass(Alternative.class).verify(); + } + + @Test + void should_be_created_an_equals_instance() { + assertThat( + Alternative.of(List.of(StringElement.of("a"), StringElement.of("b"))), + both(is(Alternative.of(StringElement.of("a"), StringElement.of("b")))).and(not(nullValue())) + ); + } +} diff --git a/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/ConcatedStringTest.java b/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/ConcatedStringTest.java new file mode 100644 index 00000000..c3214c3c --- /dev/null +++ b/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/ConcatedStringTest.java @@ -0,0 +1,35 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element; + +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.Test; + +class ConcatedStringTest { + + @Test + void equalsContract() { + EqualsVerifier.forClass(ConcatedString.class).verify(); + } +} diff --git a/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/ConcatenationTest.java b/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/ConcatenationTest.java new file mode 100644 index 00000000..03a1aaf7 --- /dev/null +++ b/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/ConcatenationTest.java @@ -0,0 +1,50 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.both; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.nullValue; + +import java.util.List; +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.Test; + +class ConcatenationTest { + + @Test + void equalsContract() { + EqualsVerifier.forClass(Concatenation.class).verify(); + } + + @Test + void should_be_created_an_equals_instance() { + assertThat( + Concatenation.of(List.of(StringElement.of("a"), StringElement.of("b"))), + both(is(Concatenation.of(StringElement.of("a"), StringElement.of("b")))).and(not(nullValue())) + ); + } +} diff --git a/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/NumericCharacterTest.java b/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/NumericCharacterTest.java new file mode 100644 index 00000000..7091e061 --- /dev/null +++ b/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/NumericCharacterTest.java @@ -0,0 +1,35 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element; + +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.Test; + +class NumericCharacterTest { + + @Test + void equalsContract() { + EqualsVerifier.forClass(NumericCharacter.class).withOnlyTheseFields("value").verify(); + } +} diff --git a/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/OptionalSequenceTest.java b/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/OptionalSequenceTest.java new file mode 100644 index 00000000..50f975ee --- /dev/null +++ b/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/OptionalSequenceTest.java @@ -0,0 +1,35 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element; + +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.Test; + +class OptionalSequenceTest { + + @Test + void equalsContract() { + EqualsVerifier.forClass(OptionalSequence.class).verify(); + } +} diff --git a/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/RuleNameTest.java b/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/RuleNameTest.java new file mode 100644 index 00000000..cea9c3ca --- /dev/null +++ b/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/RuleNameTest.java @@ -0,0 +1,35 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element; + +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.Test; + +class RuleNameTest { + + @Test + void equalsContract() { + EqualsVerifier.forClass(RuleName.class).verify(); + } +} diff --git a/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/SequenceGroupTest.java b/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/SequenceGroupTest.java new file mode 100644 index 00000000..97ab3fc7 --- /dev/null +++ b/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/SequenceGroupTest.java @@ -0,0 +1,35 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element; + +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.Test; + +class SequenceGroupTest { + + @Test + void equalsContract() { + EqualsVerifier.forClass(SequenceGroup.class).verify(); + } +} diff --git a/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/SpecificRepetitionTest.java b/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/SpecificRepetitionTest.java new file mode 100644 index 00000000..33b892f9 --- /dev/null +++ b/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/SpecificRepetitionTest.java @@ -0,0 +1,35 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element; + +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.Test; + +class SpecificRepetitionTest { + + @Test + void equalsContract() { + EqualsVerifier.forClass(SpecificRepetition.class).verify(); + } +} diff --git a/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/StringElementTest.java b/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/StringElementTest.java new file mode 100644 index 00000000..bfcd8341 --- /dev/null +++ b/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/StringElementTest.java @@ -0,0 +1,35 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element; + +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.Test; + +class StringElementTest { + + @Test + void equalsContract() { + EqualsVerifier.forClass(StringElement.class).verify(); + } +} diff --git a/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/ValueRangeAlternativesTest.java b/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/ValueRangeAlternativesTest.java new file mode 100644 index 00000000..a13c77b3 --- /dev/null +++ b/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/ValueRangeAlternativesTest.java @@ -0,0 +1,51 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.nullValue; + +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.Test; + +class ValueRangeAlternativesTest { + + @Test + void equalsContract() { + EqualsVerifier.forClass(ValueRangeAlternatives.class).verify(); + } + + @Test + void should_create_a_new_value_range() { + assertThat( + ValueRangeAlternatives.of( + NumericCharacter.of(NumericCharacter.BASE.BINARY, 0), + NumericCharacter.of(NumericCharacter.BASE.BINARY, 1) + ), + is(not(nullValue())) + ); + } +} diff --git a/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/VariableRepetitionTest.java b/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/VariableRepetitionTest.java new file mode 100644 index 00000000..0ec99407 --- /dev/null +++ b/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/element/VariableRepetitionTest.java @@ -0,0 +1,46 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.Test; + +class VariableRepetitionTest { + + @Test + void equalsContract() { + EqualsVerifier.forClass(VariableRepetition.class).verify(); + } + + @Test + void should_create_an_exactly() { + assertThat( + VariableRepetition.ofExactly(RuleReference.of(RuleName.of("test")), 2), + is(VariableRepetition.ofBetween(RuleReference.of(RuleName.of("test")), 2, 2)) + ); + } +} diff --git a/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/ElementsExtractorTest.java b/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/ElementsExtractorTest.java new file mode 100644 index 00000000..9483771a --- /dev/null +++ b/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/ElementsExtractorTest.java @@ -0,0 +1,199 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.reader; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.both; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.nullValue; + +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.Alternative; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.Concatenation; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.NumericCharacter; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.OptionalSequence; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.RuleName; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.RuleReference; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.SequenceGroup; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.SpecificRepetition; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.StringElement; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.VariableRepetition; +import org.hamcrest.Matcher; +import org.junit.jupiter.api.Test; + +class ElementsExtractorTest { + + @Test + void should_create_concated_chars() { + assertThat( + new ExtractableTestString("%d97 %d98 %d99\r\n") + .extractWith( + codepoint -> ExtractorEndsWithNewLine.of(ElementsExtractor.startElements().append(codepoint)), + 0x41 + ), + is( + Concatenation.of( + NumericCharacter.of(NumericCharacter.BASE.DECIMAL, 97), + NumericCharacter.of(NumericCharacter.BASE.DECIMAL, 98), + NumericCharacter.of(NumericCharacter.BASE.DECIMAL, 99) + ) + ) + ); + } + + @Test + void should_create_concated_strings() { + assertThat( + new ExtractableTestString("\"a\" \"b\" \"c\"\r\n") + .extractWith( + codepoint -> ExtractorEndsWithNewLine.of(ElementsExtractor.startElements().append(codepoint)), + 0x41 + ), + is(Concatenation.of(StringElement.of("a"), StringElement.of("b"), StringElement.of("c"))) + ); + } + + @Test + void should_create_concated_rule() { + assertThat( + new ExtractableTestString("foo bar foo\r\n") + .extractWith( + codepoint -> ExtractorEndsWithNewLine.of(ElementsExtractor.startElements().append(codepoint)), + 0x41 + ), + is( + Concatenation.of( + RuleReference.of(RuleName.of("foo")), + RuleReference.of(RuleName.of("bar")), + RuleReference.of(RuleName.of("foo")) + ) + ) + ); + } + + @Test + void should_create_alternatives() { + assertThat( + new ExtractableTestString("fu / bar\r\n") + .extractWith( + codepoint -> ExtractorEndsWithNewLine.of(ElementsExtractor.startElements().append(codepoint)), + 0x41 + ), + is(Alternative.of(RuleReference.of(RuleName.of("fu")), RuleReference.of(RuleName.of("bar")))) + ); + } + + @Test + void should_create_sequence_group() { + assertThat( + new ExtractableTestString("(foo / bar)\r\n") + .extractWith( + codepoint -> ExtractorEndsWithNewLine.of(ElementsExtractor.startElements().append(codepoint)), + 0x41 + ), + (Matcher) both( + is( + SequenceGroup.of( + Alternative.of(RuleReference.of(RuleName.of("foo")), RuleReference.of(RuleName.of("bar"))) + ) + ) + ) + .and(is(not(nullValue()))) + ); + } + + @Test + void should_create_default_repetition() { + assertThat( + new ExtractableTestString("*foo\r\n") + .extractWith( + codepoint -> ExtractorEndsWithNewLine.of(ElementsExtractor.startElements().append(codepoint)), + 0x41 + ), + (Matcher) both(is(VariableRepetition.of(RuleReference.of(RuleName.of("foo"))))).and(is(not(nullValue()))) + ); + } + + @Test + void should_create_at_least_repetition() { + assertThat( + new ExtractableTestString("1*foo\r\n") + .extractWith( + codepoint -> ExtractorEndsWithNewLine.of(ElementsExtractor.startElements().append(codepoint)), + 0x41 + ), + (Matcher) both(is(VariableRepetition.ofAtLeast(RuleReference.of(RuleName.of("foo")), 1))) + .and(is(not(nullValue()))) + ); + } + + @Test + void should_create_at_most_repetition() { + assertThat( + new ExtractableTestString("*1foo\r\n") + .extractWith( + codepoint -> ExtractorEndsWithNewLine.of(ElementsExtractor.startElements().append(codepoint)), + 0x41 + ), + (Matcher) both(is(VariableRepetition.ofAtMost(RuleReference.of(RuleName.of("foo")), 1))) + .and(is(not(nullValue()))) + ); + } + + @Test + void should_create_between_repetition() { + assertThat( + new ExtractableTestString("1*2foo\r\n") + .extractWith( + codepoint -> ExtractorEndsWithNewLine.of(ElementsExtractor.startElements().append(codepoint)), + 0x41 + ), + is(VariableRepetition.ofBetween(RuleReference.of(RuleName.of("foo")), 1, 2)) + ); + } + + @Test + void should_create_specific_repetition() { + assertThat( + new ExtractableTestString("2foo\r\n") + .extractWith( + codepoint -> ExtractorEndsWithNewLine.of(ElementsExtractor.startElements().append(codepoint)), + 0x41 + ), + (Matcher) both(is(SpecificRepetition.of(RuleReference.of(RuleName.of("foo")), 2))).and(is(not(nullValue()))) + ); + } + + @Test + void should_create_optional_sequence() { + assertThat( + new ExtractableTestString("[foo]\r\n") + .extractWith( + codepoint -> ExtractorEndsWithNewLine.of(ElementsExtractor.startElements().append(codepoint)), + 0x41 + ), + (Matcher) both(is(OptionalSequence.of(RuleReference.of(RuleName.of("foo"))))).and(is(not(nullValue()))) + ); + } +} diff --git a/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/ExtractableTestString.java b/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/ExtractableTestString.java new file mode 100644 index 00000000..01dde532 --- /dev/null +++ b/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/ExtractableTestString.java @@ -0,0 +1,56 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.reader; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +import java.util.Objects; +import java.util.function.IntFunction; + +final class ExtractableTestString { + + private final String testString; + + public ExtractableTestString(final String testString) { + this.testString = Objects.requireNonNull(testString); + } + + public T extractWith( + final IntFunction> extratorGenerator, + final int endCodePoint + ) { + ExtractorWithEndpositionDetection tokens = null; + for (int i = 0; i < testString.length(); i++) { + if (tokens == null) { + tokens = extratorGenerator.apply(testString.codePointAt(i)); + } else { + tokens = tokens.append(testString.codePointAt(i)); + } + } + assert tokens != null; + assertThat(tokens.hasNoInteresedIn(endCodePoint), is(true)); + return tokens.create(); + } +} diff --git a/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/RuleExtractorTest.java b/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/RuleExtractorTest.java new file mode 100644 index 00000000..d52858c9 --- /dev/null +++ b/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/RuleExtractorTest.java @@ -0,0 +1,111 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.reader; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.Rule; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.Alternative; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.Concatenation; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.RuleName; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.RuleReference; +import org.junit.jupiter.api.Test; + +class RuleExtractorTest { + + @Test + void should_create_rule_from_oneline_without_commentary() { + //Note: a rule MUST end with crlf!! see rfc5234 + final String ruleStr = "rule = rulename defined-as elements c-nl\r\n"; + + assertThat( + new ExtractableTestString(ruleStr).extractWith(codePoint -> RuleExtractor.startNewRule(codePoint), 65), + is( + Rule.of( + RuleName.of("rule"), + Concatenation.of( + RuleReference.of(RuleName.of("rulename")), + RuleReference.of(RuleName.of("defined-as")), + RuleReference.of(RuleName.of("elements")), + RuleReference.of(RuleName.of("c-nl")) + ) + ) + ) + ); + } + + @Test + void should_create_rule_from_multiline_without_commentray() { + //Note: a rule MUST end with crlf!! see rfc5234. lf is already set by the formatting :) + final String ruleStr = + """ + element = rulename / group / option /\r + char-val / num-val / prose-val\r + """; + + assertThat( + new ExtractableTestString(ruleStr).extractWith(codePoint -> RuleExtractor.startNewRule(codePoint), 65), + is( + Rule.of( + RuleName.of("element"), + Alternative.of( + RuleReference.of(RuleName.of("rulename")), + RuleReference.of(RuleName.of("group")), + RuleReference.of(RuleName.of("option")), + RuleReference.of(RuleName.of("char-val")), + RuleReference.of(RuleName.of("num-val")), + RuleReference.of(RuleName.of("prose-val")) + ) + ) + ) + ); + } + + @Test + void should_create_rule_from_string_with_commentary() { + //Note: a rule MUST end with crlf!! see rfc5234. lf is already set by the formatting :) + final String ruleStr = + """ + rule = rulename defined-as elements c-nl\r + ; continues if next line starts\r + ; with white space\r + """; + + assertThat( + new ExtractableTestString(ruleStr).extractWith(codePoint -> RuleExtractor.startNewRule(codePoint), 65), + is( + Rule.of( + RuleName.of("rule"), + Concatenation.of( + RuleReference.of(RuleName.of("rulename")), + RuleReference.of(RuleName.of("defined-as")), + RuleReference.of(RuleName.of("elements")), + RuleReference.of(RuleName.of("c-nl")) + ) + ) + ) + ); + } +} diff --git a/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/TextABNFTest.java b/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/TextABNFTest.java new file mode 100644 index 00000000..ac9d83ea --- /dev/null +++ b/vocabulary-format-assertion/src/test/java/io/github/sebastiantoepfer/jsonschema/vocabulary/format/assertion/abnf/reader/TextABNFTest.java @@ -0,0 +1,103 @@ +/* + * The MIT License + * + * Copyright 2023 sebastian. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.reader; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.Rule; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.RuleList; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.Alternative; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.Concatenation; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.RuleName; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.RuleReference; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.SequenceGroup; +import io.github.sebastiantoepfer.jsonschema.vocabulary.format.assertion.abnf.element.VariableRepetition; +import org.junit.jupiter.api.Test; + +class TextABNFTest { + + @Test + void should_create_abnf_rules_from_string() { + //Note: a rule MUST end with crlf!! see rfc5234. lf is already set by the formatting :) + assertThat( + TextABNF + // .of( + // """ + // rulelist = 1*( rule / (*c-wsp c-nl) )\r + // concatenation = repetition *(1*c-wsp repetition)\r + // repetition = [repeat] element\r + // """ + // ) + .of( + """ + rulelist = 1*( rule / (*c-wsp c-nl) )\r + """ + ) + .rules(), + is( + RuleList.of( + Rule.of( + RuleName.of("rulelist"), + VariableRepetition.ofAtLeast( + SequenceGroup.of( + Alternative.of( + RuleReference.of(RuleName.of("rule")), + SequenceGroup.of( + Concatenation.of( + VariableRepetition.of(RuleReference.of(RuleName.of("c-wsp"))), + RuleReference.of(RuleName.of("c-nl")) + ) + ) + ) + ), + 1 + ) + // ), + // Rule.of( + // RuleName.of("concatenation"), + // Concatenation.of( + // RuleReference.of(RuleName.of("repetition")), + // VariableRepetition.of( + // SequenceGroup.of( + // Concatenation.of( + // VariableRepetition.ofAtLeast(RuleReference.of(RuleName.of("c-wsp")), 1), + // RuleReference.of(RuleName.of("repetition")) + // ) + // ) + // ) + // ) + // ), + // Rule.of( + // RuleName.of("repetition"), + // Concatenation.of( + // OptionalSequence.of(RuleReference.of(RuleName.of("repeat"))), + // RuleReference.of(RuleName.of("element")) + // ) + ) + ) + ) + ); + } +}