From 0ecda8d550479191b8957549afbf0cce15d138c6 Mon Sep 17 00:00:00 2001 From: Andy Lowry Date: Tue, 21 Aug 2018 11:54:58 -0400 Subject: [PATCH 1/8] [#189] Changes to p2 site generation * split -r option into separate options (-K and -J) for staging repos for KZOP and JOvl * make direct imports non-optional * add direct import for javax.mail.internet * exclude JOvl from KZOP artifact (else we could ned up with two versions in the update site) * don't export the .gen package from JOvl, and mark its import in KZOP optional (would be better to not import it, but not sure how to specify that) * exclude artifacts only used by the JOvl gen package --- kaizen-openapi-parser/p2/README.md | 29 ++++-- kaizen-openapi-parser/p2/build.sh | 44 +++++--- kaizen-openapi-parser/p2/pom.xml | 155 +++++++++++++++++------------ 3 files changed, 143 insertions(+), 85 deletions(-) diff --git a/kaizen-openapi-parser/p2/README.md b/kaizen-openapi-parser/p2/README.md index 30ff0e7f..6a05c339 100644 --- a/kaizen-openapi-parser/p2/README.md +++ b/kaizen-openapi-parser/p2/README.md @@ -30,23 +30,32 @@ Here is the usage message for the script: ``` Usage: ./build.sh -Builds a p2 repo for KZOP, including JsonOverlay and other dependencies, and +Builds a p2 repository for KZOP, including JsonOverlay and other dependencies, and optionally publishes as an update site. Options: (* marks required option) * -k or --kzop-version - specify full version number of KZOP to package * -j or --jovl-version - specify full version number of JsonOverlay to package - -r or --repo - specify maven repo URL where indicated versions are available, if - they are not in maven central. Defaults to http://localhost:8000 - This script will attempt to stage the indicated versions to your - lcoal maven repo cache prior to building the bundle. - Hint: start a web server that delivers files from your .m2.repository - directory, e.g. using "python -m SimpleHTTPServer" - or "python3 -m http.server" + -K or --kzop-repo - specify maven repo URL where indicated KXOP version is + available, if is not in maven central + -J or --jovl-repo - specify maven repo URL where indicated JsonOverlay + version is available, if is not in maven central -p or --publish - publish the newly built update site * -b or --build-scripts - speicfy location of RepreZen build scripts, including the "publish" script. This is required only if "-p" is specified -h or --help - print this message and do nothing else + +Note on repos: Both ---kzop-repo and --jovl-repo default to +http://localhost:8000, so if you already have the needed versions in +your local maven repo cache, you can set up a simple HTTP server to +serve those files and go with these defaults. But you can also explicitly +specify, e.g., staging repository URLs. + +To use the defualt repo, you can use either of the following to launch +a local web server, after positioning yourself in the root of your +local maven cacche (typically .m2/repository in your home directory): + * python -m SimpleHTTPServer + * python3 -m http.server ``` To build without publishing, use a command like this, with @@ -80,6 +89,10 @@ yet released to central), you can follow this procedure: the root URL serving your local repo, which defaults to `http://localhost:8000`. +Alterantively, you can use the `--kzop-repo` (`-K`) and/or +`--jovl-repo` (`-J`) options to specify URLs for staging repositories +that contain the needed versions. + ## Publishing If you use the `-p` option, the script will publish the newly-built diff --git a/kaizen-openapi-parser/p2/build.sh b/kaizen-openapi-parser/p2/build.sh index 3093068f..f3594017 100755 --- a/kaizen-openapi-parser/p2/build.sh +++ b/kaizen-openapi-parser/p2/build.sh @@ -1,13 +1,14 @@ #!/bin/bash -e unset JOVL_VERSION KZOP_VERSION BUILD_SCRIPT_DIR -REPO="http://localhost:8000" +KZOP_REPO="http://localhost:8000" +JOVL_REPO="http://localhost:8000" PUBLISH=false HELP=false function getargs() { - longopts="jovl-version:,kzop-version:,repo:,publish,build-scripts:,help" - shortopts="j:k:r:pb:h" + longopts="jovl-version:,kzop-version:,kzop-repo:,jovl-repo:,publish,build-scripts:,help" + shortopts="j:k:K:J:pb:h" progname=$(basename "$0") OPTS=$(getopt -n "$progname" -o "$shortopts" --long "$longopts" -- "$@") if [[ $? -ne 0 ]] ; then @@ -20,8 +21,10 @@ function getargs() { KZOP_VERSION="$2"; shift 2 ;; -j|--jovl-version) JOVL_VERSION="$2"; shift 2 ;; - -r:--repo) - LOCAL_REPO="$2"; shift 2 ;; + -K|--kzop-repo) + KZOP_REPO="$2"; shift 2 ;; + -J|--jovl-repo) + JOVL_REPO="$2"; shift 2 ;; -p|--publish) PUBLISH=true ; shift ;; -b|--build-scripts) @@ -62,17 +65,26 @@ function usage() { Options: (* marks required option) * -k or --kzop-version - specify full version number of KZOP to package * -j or --jovl-version - specify full version number of JsonOverlay to package - -r or --repo - specify maven repo URL where indicated versions are available, if - they are not in maven central. Defaults to http://localhost:8000 - This script will attempt to stage the indicated versions to your - lcoal maven repo cache prior to building the bundle. - Hint: start a web server that delivers files from your .m2.repository - directory, e.g. using "python -m SimpleHTTPServer" - or "python3 -m http.server" + -K or --kzop-repo - specify maven repo URL where indicated KXOP version is + available, if is not in maven central + -J or --jovl-repo - specify maven repo URL where indicated JsonOverlay + version is available, if is not in maven central -p or --publish - publish the newly built update site * -b or --build-scripts - speicfy location of RepreZen build scripts, including the "publish" script. This is required only if "-p" is specified -h or --help - print this message and do nothing else + + Note on repos: Both ---kzop-repo and --jovl-repo default to + http://localhost:8000, so if you already have the needed versions in + your local maven repo cache, you can set up a simple HTTP server to + serve those files and go with these defaults. But you can also explicitly + specify, e.g., staging repository URLs. + + To use the defualt repo, you can use either of the following to launch + a local web server, after positioning yourself in the root of your + local maven cacche (typically .m2/repository in your home directory): + * python -m SimpleHTTPServer + * python3 -m http.server END_OF_USAGE } @@ -85,14 +97,16 @@ function main() { } function retrieveArtifacts() { - mvn dependency:get -DrepoUrl="$REPO" \ + mvn dependency:get -DrepoUrl="$KZOP_REPO" \ -Dartifact="com.reprezen.kaizen:openapi-parser:$KZOP_VERSION" - mvn dependency:get -DrepoUrl="$REPO" \ + mvn dependency:get -DrepoUrl="$JOVL_REPO" \ -Dartifact="com.reprezen.jsonoverlay:jsonoverlay:$JOVL_VERSION" } function buildSite() { - mvn clean p2:site -Dkzop-version="$KZOP_VERSION" -Djovl-version="$JOVL_VERSION" + mvn clean p2:site \ + -Dkzop-version="$KZOP_VERSION" -Dkzop-repo="$KZOP_REPO" \ + -Djovl-version="$JOVL_VERSION" -Djovl-repo="$JOVL_REPO" } function publishSite() { diff --git a/kaizen-openapi-parser/p2/pom.xml b/kaizen-openapi-parser/p2/pom.xml index ad5ccb12..42aad181 100644 --- a/kaizen-openapi-parser/p2/pom.xml +++ b/kaizen-openapi-parser/p2/pom.xml @@ -1,66 +1,97 @@ + - 4.0.0 - com.reprezen.kaizen - com.reprezen.kaizen.openapi-parser.osgi - 0.0.1-SNAPSHOT - pom - - http://localhost:8000 - + 4.0.0 + com.reprezen.kaizen + com.reprezen.kaizen.openapi-parser.osgi + 0.0.1-SNAPSHOT + pom + + http://localhost:8000 + http://localhost:8000 + - - - - org.reficio - p2-maven-plugin - 1.1.2-SNAPSHOT - - - default-cli - - - - com.reprezen.kaizen:openapi-parser:${kzop-version} - - *;resolution=optional - - com.reprezen.kaizen.oasparser, - com.reprezen.kaizen.oasparser.model3, - com.reprezen.kaizen.oasparser.ovl3, - com.reprezen.kaizen.oasparser.val - - - - - com.reprezen.jsonoverlay:jsonoverlay:${jovl-version} - - - com.reprezen.jsonoverlay, - com.reprezen.jsonoverlay.gen - - - - - false - - - - - - - - - - reficio - http://repo.reficio.org/maven/ - - + + + + org.reficio + p2-maven-plugin + 1.1.2-SNAPSHOT + + + default-cli + + + + com.reprezen.kaizen:openapi-parser:${kzop-version} + + true + + + javax.mail.internet, + com.reprezen.jsonoverlay.gen;resolution:=optional, + * + + + com.reprezen.kaizen.oasparser, + com.reprezen.kaizen.oasparser.model3, + com.reprezen.kaizen.oasparser.ovl3, + com.reprezen.kaizen.oasparser.val + + + + + com.reprezen.jsonoverlay:jsonoverlay + + + + com.reprezen.jsonoverlay:jsonoverlay:${jovl-version} + + true + + + * + + + com.reprezen.jsonoverlay + + + + + commons-cli + com.github.javaparser + org.eclipse.xtend + + + + false + + + + + + + + + + reficio + http://repo.reficio.org/maven/ + + - - - local-cache - ${local-repo} - default - - + + + kzop-repo + ${kzop-repo} + default + + + jovl-repo + ${jovl-repo} + default + + From 5dc109b4f2c7abf6dc4e3b9c7d4c129d7e45d8c6 Mon Sep 17 00:00:00 2001 From: Andy Lowry Date: Wed, 22 Aug 2018 10:49:33 -0400 Subject: [PATCH 2/8] [#189] New replacement for Messages class The old one is still there, where it's always been. The new implementation is in the val.msg package. The new implemnetation has these improvements: * No longer includes inline messages, but messages are identified by enum values, and it's easy to navigate to the enum definition, where the default message appears. * Properties files can be used to provide localized messages, either for a specific two-part language tag (e.g. "en-US") or by a language id ("en") as a fallback. * Multiple enum classes can easily be defined for different sets of messages, and they can all be used as needed in the application This makes it slightly more complicated to compose a new message, but the resulting code is much more concise, and with an easy click-through to the default message, this gets around the main issue I've had with the eclipse org.eclipse.osgi.util.NLS class. --- .../oasparser/val/BaseValidationMessages.java | 19 +++ .../kaizen/oasparser/val/JsonTypeChecker.java | 10 +- .../kaizen/oasparser/val/msg/Messages.java | 36 ++++++ .../oasparser/val/msg/MessagesHelper.java | 114 ++++++++++++++++++ 4 files changed, 176 insertions(+), 3 deletions(-) create mode 100644 kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/BaseValidationMessages.java create mode 100644 kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/msg/Messages.java create mode 100644 kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/msg/MessagesHelper.java diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/BaseValidationMessages.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/BaseValidationMessages.java new file mode 100644 index 00000000..0e94c985 --- /dev/null +++ b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/BaseValidationMessages.java @@ -0,0 +1,19 @@ +package com.reprezen.kaizen.oasparser.val; + +import com.reprezen.kaizen.oasparser.val.msg.Messages; + +public enum BaseValidationMessages implements Messages { + WrongTypeJson("Incorrect JSON Node type %1; allowed types: %2") // + ; + private String formatString; + + BaseValidationMessages(String formatString) { + this.formatString = formatString; + } + + @Override + public String getFormatString() { + return formatString; + } + +} diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/JsonTypeChecker.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/JsonTypeChecker.java index 2e3e3876..76702749 100755 --- a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/JsonTypeChecker.java +++ b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/JsonTypeChecker.java @@ -10,10 +10,12 @@ *******************************************************************************/ package com.reprezen.kaizen.oasparser.val; -import static com.reprezen.kaizen.oasparser.val.Messages.m; +import static com.reprezen.kaizen.oasparser.val.BaseValidationMessages.WrongTypeJson; import java.util.Arrays; import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; @@ -37,6 +39,7 @@ import com.reprezen.jsonoverlay.PrimitiveOverlay; import com.reprezen.jsonoverlay.PropertiesOverlay; import com.reprezen.jsonoverlay.StringOverlay; +import com.reprezen.kaizen.oasparser.val.msg.Messages; public class JsonTypeChecker { @@ -49,8 +52,9 @@ public static void checkJsonType(Overlay value, ValidationResults results) { return; } } - results.addError(m.msg("WrongTypeJson|Property bound to incompatible JSON Node type", json.getNodeType(), - allowedJsonTypes), value); + List allowed = allowedJsonTypes.stream().map(type -> type.getSimpleName()) + .collect(Collectors.toList()); + results.addError(Messages.msg(WrongTypeJson, json.getClass().getSimpleName(), allowed), value); } } diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/msg/Messages.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/msg/Messages.java new file mode 100644 index 00000000..37ebad60 --- /dev/null +++ b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/msg/Messages.java @@ -0,0 +1,36 @@ +package com.reprezen.kaizen.oasparser.val.msg; + +import java.util.Locale; +import java.util.Properties; + +public interface Messages { + public String getFormatString(); + + public String name(); + + public default String getFormatString(Locale locale) { + Properties localeStrings = locale != null ? getFormatStrings(locale) : null; + String formatString = localeStrings != null ? localeStrings.getProperty(name()) : null; + return formatString != null ? formatString : getFormatString(); + } + + public default Properties getFormatStrings(Locale locale) { + return MessagesHelper.loadLocalizations(this.getClass(), locale); + } + + public default String msg(Object... args) { + return msg(Locale.getDefault(), args); + } + + public default String msgNoLocale(Object... args) { + return msg((Locale) null, args); + } + + public default String msg(Locale locale, Object... args) { + return MessagesHelper.format(locale, this, args); + } + + public static String msg(Messages instance, Object... args) { + return instance.msg(args); + } +} diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/msg/MessagesHelper.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/msg/MessagesHelper.java new file mode 100644 index 00000000..4dac756e --- /dev/null +++ b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/msg/MessagesHelper.java @@ -0,0 +1,114 @@ +package com.reprezen.kaizen.oasparser.val.msg; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Properties; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class MessagesHelper { + private static final Pattern placeholderPattern = Pattern.compile("%(\\d+)|%\\{(\\d+)\\}"); + + /** + * Interpolate arguments into the message format string for the given message. + *

+ * If a non-null locale is provided, an attempt is made to load a properties + * file for the Message class of which this message is an instance, and the + * property named by this message's name is used as the format string. If that + * fails, or if the locale is null, the message object's default format string + * is used. + *

+ * The format string contains embedded place holders indicating where arguments + * are to be substituted. Each place holder takes the form %n or + * %{n}, where n is an integer from 1 to the number of + * arguments. The second form allows interpolation at a site immediately + * followed by other digits. + *

+ * To prevent a percent sign from triggering interpolation, double it: + * %%. For example, "%%1 %%{2}" will always produce + * "%1 %{2}". + *

+ * The result is obtained by replacing each placeholder with the corresponding + * argument's {@link #toString()} value (except that null arguments are rendered + * as empty strings). + * + * @param message + * @param args + * @return message with interpolated arguments + */ + public static String format(Locale locale, Messages message, Object... args) { + String formatString = message.getFormatString(locale); + Object[] sortArgs = sortArgs(formatString, args); + String printfString = Stream.of(formatString.split("%%")) + .map(part -> placeholderPattern.matcher(part).replaceAll("%s")) // + .collect(Collectors.joining("%%")); + return String.format(printfString, sortArgs); + } + + private static Object[] sortArgs(String format, Object[] args) { + List sites = findInterpolationSites(format); + sites.stream().forEach(site -> { + if (site < 1 || site > args.length) { + String msg = String.format("Interpolation position must be from 1 to %d: %%%d", args.length, site); + throw new IndexOutOfBoundsException(msg); + } + }); + return sites.stream().map(i -> args[i - 1] != null ? args[i - 1] : "").toArray(); + } + + private static List findInterpolationSites(String format) { + List sites = new ArrayList<>(); + String[] parts = format.split("%%"); + for (String part : parts) { + Matcher m = placeholderPattern.matcher(part); + while (m.find()) { + boolean braces = m.group(1) == null; + String digits = m.group(braces ? 2 : 1); + int index = digits.isEmpty() ? 0 : Integer.valueOf(digits); + sites.add(index); + } + } + return sites; + } + + private static Map, Map> localizationsByClass = new HashMap<>(); + + public static Properties loadLocalizations(Class msgClass, Locale locale) { + if (!localizationsByClass.containsKey(msgClass)) { + localizationsByClass.put(msgClass, new HashMap<>()); + } + Map localizations = localizationsByClass.get(msgClass); + // try locale-specified variant tag first, then fall back to just the language + // code + for (String tag : Arrays.asList(locale.toLanguageTag(), locale.getLanguage())) { + if (!localizations.containsKey(tag)) { + URL resource = msgClass.getResource(String.format("localizations/%s/messages.properties", tag)); + Properties props = null; + if (resource != null) { + props = new Properties(); + try (InputStream in = resource.openStream()) { + props.load(in); + } catch (IOException e) { + props = null; + } + } + // if no props loaded, set null value in localizations so we don't keep trying + localizations.put(tag, props); + } + Properties result = localizations.get(tag); + if (result != null) { + return result; + } + } + return null; + } +} From e45927b75acc79f788d6d3429f63e65c29e5be69 Mon Sep 17 00:00:00 2001 From: Andy Lowry Date: Wed, 22 Aug 2018 12:22:19 -0400 Subject: [PATCH 3/8] [#189] Exclude guava from the update site --- kaizen-openapi-parser/p2/pom.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kaizen-openapi-parser/p2/pom.xml b/kaizen-openapi-parser/p2/pom.xml index 42aad181..44300495 100644 --- a/kaizen-openapi-parser/p2/pom.xml +++ b/kaizen-openapi-parser/p2/pom.xml @@ -43,6 +43,7 @@ com.reprezen.jsonoverlay:jsonoverlay + com.google.guava @@ -63,6 +64,7 @@ which is generally not done at runtime --> commons-cli com.github.javaparser + com.google.guava org.eclipse.xtend From 4428b5c7433f93e797ba11a4c816224a211e6d25 Mon Sep 17 00:00:00 2001 From: Andy Lowry Date: Wed, 22 Aug 2018 13:31:06 -0400 Subject: [PATCH 4/8] [#189] Upgraded existing validations to new msg scheme In the process, improved some message texts, and more importantly, created place holders in the messasge texts for message parameters, rather than just appending the paramters in a list after the message, as had been done earlier. (It was never intended to stay that way!) --- .../oasparser/val/BaseValidationMessages.java | 15 ++++++- .../kaizen/oasparser/val/JsonTypeChecker.java | 14 +++--- .../kaizen/oasparser/val/Messages.java | 30 ------------- .../oasparser/val/ReferencesChecker.java | 7 ++- .../kaizen/oasparser/val/ValidatorBase.java | 44 +++++++++---------- .../kaizen/oasparser/val/msg/Messages.java | 6 +++ .../oasparser/val3/ExampleValidator.java | 11 +++-- .../oasparser/val3/HeaderValidator.java | 8 ++-- .../kaizen/oasparser/val3/LinkValidator.java | 34 +++++--------- .../oasparser/val3/MediaTypeValidator.java | 8 ++-- .../oasparser/val3/OpenApi3Messages.java | 37 ++++++++++++++++ .../oasparser/val3/ParameterValidator.java | 18 +++----- .../oasparser/val3/SchemaValidator.java | 13 +++--- .../val3/SecurityRequirementValidator.java | 6 +-- 14 files changed, 131 insertions(+), 120 deletions(-) delete mode 100755 kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/Messages.java create mode 100644 kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/OpenApi3Messages.java diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/BaseValidationMessages.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/BaseValidationMessages.java index 0e94c985..4ad56551 100644 --- a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/BaseValidationMessages.java +++ b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/BaseValidationMessages.java @@ -3,8 +3,19 @@ import com.reprezen.kaizen.oasparser.val.msg.Messages; public enum BaseValidationMessages implements Messages { - WrongTypeJson("Incorrect JSON Node type %1; allowed types: %2") // - ; + WrongTypeJson("Incorrect JSON value type: %1; allowed types: %2"), // + BadRef("Reference '%1' could not be resolved: %2"), // + PatternMatchFail("Value '%1' does not match required pattern '%2'"), // + BadPattern("Pattern is not a valid Java Regular Expression but may be valid in ECMA 262: %1"), // + BadUrl("Invalid URL '%1': %2"), // + BadEmail("Invalid email address '%1': %2"), // + NumberConstraint("Value %1 must be %2"), // + EmptyList("List may not be empty"), // + DuplicateValue("Value at '%2' appeared already: %1"), // + MissingField("Required field '%1' is missing"), // + WrongTypeFormat("OpenAPI-defined format '%1' requires type '%3' but appears with missing or invalid type %2"), // + WrongTypeValue("Value is incompatible with schema type"); + private String formatString; BaseValidationMessages(String formatString) { diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/JsonTypeChecker.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/JsonTypeChecker.java index 76702749..bd538b75 100755 --- a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/JsonTypeChecker.java +++ b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/JsonTypeChecker.java @@ -11,10 +11,10 @@ package com.reprezen.kaizen.oasparser.val; import static com.reprezen.kaizen.oasparser.val.BaseValidationMessages.WrongTypeJson; +import static com.reprezen.kaizen.oasparser.val.msg.Messages.msg; import java.util.Arrays; import java.util.Collection; -import java.util.List; import java.util.stream.Collectors; import com.fasterxml.jackson.databind.JsonNode; @@ -39,7 +39,6 @@ import com.reprezen.jsonoverlay.PrimitiveOverlay; import com.reprezen.jsonoverlay.PropertiesOverlay; import com.reprezen.jsonoverlay.StringOverlay; -import com.reprezen.kaizen.oasparser.val.msg.Messages; public class JsonTypeChecker { @@ -52,12 +51,17 @@ public static void checkJsonType(Overlay value, ValidationResults results) { return; } } - List allowed = allowedJsonTypes.stream().map(type -> type.getSimpleName()) - .collect(Collectors.toList()); - results.addError(Messages.msg(WrongTypeJson, json.getClass().getSimpleName(), allowed), value); + String allowed = allowedJsonTypes.stream().map(type -> getJsonValueType(type)) + .collect(Collectors.joining(", ")); + results.addError(msg(WrongTypeJson, getJsonValueType(json.getClass()), allowed), value); } } + private static String getJsonValueType(Class node) { + String type = node.getSimpleName(); + return type.endsWith("Node") ? type.substring(0, type.length() - 4) : type; + } + private static Multimap, Class> allowedJsonTypes = null; private static Collection> getAllowedJsonTypes(Overlay value) { diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/Messages.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/Messages.java deleted file mode 100755 index be33e42a..00000000 --- a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/Messages.java +++ /dev/null @@ -1,30 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2017 ModelSolv, Inc. and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * ModelSolv, Inc. - initial API and implementation and/or initial documentation - *******************************************************************************/ -package com.reprezen.kaizen.oasparser.val; - -import java.util.Arrays; - -public class Messages { - public static Messages m = new Messages(); - - public String msg(String text, Object... args) { - int pos = text.indexOf('|'); - if (pos >= 0) { - String nls = nls(text.substring(0, pos)); - text = nls != null ? nls : text.substring(pos + 1); - } - return String.format("%s %s", text, Arrays.asList(args)); - } - - public String nls(String text) { - return null; - } -} diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/ReferencesChecker.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/ReferencesChecker.java index 081a6870..250ffe1b 100755 --- a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/ReferencesChecker.java +++ b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/ReferencesChecker.java @@ -10,7 +10,8 @@ *******************************************************************************/ package com.reprezen.kaizen.oasparser.val; -import static com.reprezen.kaizen.oasparser.val.Messages.m; +import static com.reprezen.kaizen.oasparser.val.BaseValidationMessages.BadRef; +import static com.reprezen.kaizen.oasparser.val.msg.Messages.msg; import com.reprezen.jsonoverlay.ListOverlay; import com.reprezen.jsonoverlay.MapOverlay; @@ -51,9 +52,7 @@ public static void checkReferences(PropertiesOverlay props, ValidationResults public static void checkReference(Reference ref, ValidationResults results, Overlay context) { if (ref.isInvalid()) { - results.addError( - m.msg("BadRef|JSON reference node was not resolved", ref.getRefString(), ref.getInvalidReason()), - context); + results.addError(msg(BadRef, ref.getRefString(), ref.getInvalidReason()), context); } } } diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/ValidatorBase.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/ValidatorBase.java index 0e52ed60..e2603681 100755 --- a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/ValidatorBase.java +++ b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/ValidatorBase.java @@ -1,6 +1,14 @@ package com.reprezen.kaizen.oasparser.val; -import static com.reprezen.kaizen.oasparser.val.Messages.m; +import static com.reprezen.kaizen.oasparser.val.BaseValidationMessages.BadEmail; +import static com.reprezen.kaizen.oasparser.val.BaseValidationMessages.BadPattern; +import static com.reprezen.kaizen.oasparser.val.BaseValidationMessages.BadUrl; +import static com.reprezen.kaizen.oasparser.val.BaseValidationMessages.DuplicateValue; +import static com.reprezen.kaizen.oasparser.val.BaseValidationMessages.EmptyList; +import static com.reprezen.kaizen.oasparser.val.BaseValidationMessages.MissingField; +import static com.reprezen.kaizen.oasparser.val.BaseValidationMessages.NumberConstraint; +import static com.reprezen.kaizen.oasparser.val.BaseValidationMessages.PatternMatchFail; +import static com.reprezen.kaizen.oasparser.val.msg.Messages.msg; import java.net.MalformedURLException; import java.net.URL; @@ -66,9 +74,7 @@ public final Overlay validateStringField(String name, boolean required, void checkPattern(Overlay field, Pattern pattern) { if (!pattern.matcher(field.get()).matches()) { - results.addError( - m.msg("PatternMatchFail|String value does not match required pattern", field.get(), pattern), - field); + results.addError(msg(PatternMatchFail, field.get(), pattern), field); } } @@ -81,9 +87,7 @@ private void checkRegex(Overlay field) { try { Pattern.compile(regex); } catch (PatternSyntaxException e) { - results.addWarning( - m.msg("BadPattern|Pattern is not a valid Java Regular Expression but may be valid ECMA 262", regex), - field); + results.addWarning(msg(BadPattern, regex), field); } } @@ -126,7 +130,7 @@ private void checkUrl(Overlay overlay, boolean allowVars) { try { new URL(url); } catch (MalformedURLException e) { - results.addError(m.msg("BadUrl|Invalid URL", origUrl, e.toString()), overlay); + results.addError(msg(BadUrl, origUrl, e.toString()), overlay); } } @@ -166,7 +170,7 @@ private void checkEmail(Overlay overlay) { addr.setAddress(email); addr.validate(); } catch (AddressException e) { - results.addError(m.msg("BadEmail|Invalid email address", email, e.toString()), overlay); + results.addError(msg(BadEmail, email, e.toString()), overlay); } } @@ -185,7 +189,7 @@ public Overlay validateNumericField(String name, boolean required, Funct if (field != null && field.isPresent() && test != null) { Number n = field.get(); if (!test.apply(n)) { - results.addError(m.msg("ReqPositive|Value must be " + desc, n), field); + results.addError(msg(NumberConstraint, desc, n), field); } } return field; @@ -228,7 +232,7 @@ private void checkListNotEmpty(Overlay> list, boolean nonEmpty) { ListOverlay listOverlay = Overlay.getListOverlay(list); if (list != null && !list.isPresent()) { if (nonEmpty && listOverlay.size() == 0) { - results.addError(m.msg("EmptyList|List may not be empty"), list); + results.addError(msg(EmptyList), list); } } } @@ -241,8 +245,7 @@ private void checkListUnique(Overlay> list, boolean unique) { for (int i = 0; i < listOverlay.size(); i++) { X item = listOverlay.get(i); if (seen.contains(item)) { - results.addError(m.msg("DuplicateValue|Value appeared already", item, i), - Overlay.of(listOverlay, i)); + results.addError(msg(DuplicateValue, item, i), Overlay.of(listOverlay, i)); } else { seen.add(item); } @@ -271,7 +274,7 @@ private void checkMapNotEmpty(Overlay> list, boolean nonEmpty MapOverlay mapOverlay = Overlay.getMapOverlay(list); if (list != null && !list.isPresent()) { if (nonEmpty && mapOverlay.size() == 0) { - results.addError(m.msg("EmptyList|List may not be empty"), list); + results.addError(msg(EmptyList), list); } } } @@ -284,8 +287,7 @@ private void checkMapUnique(Overlay> map, boolean unique) { for (String key : mapOverlay.keySet()) { X value = mapOverlay.get(key); if (seen.contains(value)) { - results.addError(m.msg("DuplicateValue|Value appeared already", value, key), - Overlay.of(mapOverlay, key)); + results.addError(msg(DuplicateValue, value, key), Overlay.of(mapOverlay, key)); } else { seen.add(value); } @@ -295,7 +297,7 @@ private void checkMapUnique(Overlay> map, boolean unique) { void checkMissing(Overlay field, boolean required) { if (required && (field == null || !field.isPresent())) { - results.addError(m.msg("MissingField|required field is missing", field.getPathInParent()), value); + results.addError(msg(MissingField, field.getPathInParent()), value); } } @@ -331,10 +333,7 @@ public Overlay validateFormatField(String name, boolean required, String } if (normalType != null) { if (type == null || !type.equals(normalType)) { - results.addWarning( - m.msg("WrongTypeFormat|OpenAPI-defined format used with nonstandard or missing type", field, - type, normalType), - field); + results.addWarning(msg(BaseValidationMessages.WrongTypeFormat, field, type, normalType), field); } } } @@ -366,8 +365,7 @@ public void checkDefault(Overlay overlay, String type) { break; } if (!ok) { - results.addError(m.msg("WrongTypeValue|Value is incompatible with schema type", type, defaultValue), - overlay); + results.addError(msg(BaseValidationMessages.WrongTypeValue, type, defaultValue), overlay); } } } diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/msg/Messages.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/msg/Messages.java index 37ebad60..3a70ad89 100644 --- a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/msg/Messages.java +++ b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/msg/Messages.java @@ -4,6 +4,12 @@ import java.util.Properties; public interface Messages { + + // TODO: add a method to test a localization file for missing and invalid + // property names (compare all the property keys to the enum value names). This + // should be easily executed by a main method in the enum class. It would be + // great to also flag localized messages whose list of placeholder positions + // does not match that of the default message. public String getFormatString(); public String name(); diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/ExampleValidator.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/ExampleValidator.java index 22d20d38..d2d6258a 100644 --- a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/ExampleValidator.java +++ b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/ExampleValidator.java @@ -14,7 +14,9 @@ import static com.reprezen.kaizen.oasparser.ovl3.ExampleImpl.F_externalValue; import static com.reprezen.kaizen.oasparser.ovl3.ExampleImpl.F_summary; import static com.reprezen.kaizen.oasparser.ovl3.ExampleImpl.F_value; -import static com.reprezen.kaizen.oasparser.val.Messages.m; +import static com.reprezen.kaizen.oasparser.val.msg.Messages.msg; +import static com.reprezen.kaizen.oasparser.val3.OpenApi3Messages.ExampleNoValue; +import static com.reprezen.kaizen.oasparser.val3.OpenApi3Messages.ExmplTwoValues; import com.reprezen.jsonoverlay.Overlay; import com.reprezen.kaizen.oasparser.model3.Example; @@ -39,14 +41,11 @@ private void checkExactlyOneValue(Overlay valueField, Overlay ex boolean valuePresent = valueField != null & valueField.isPresent(); boolean externalPresent = externalField != null && externalField.isPresent(); if (valuePresent && externalPresent) { - results.addError( - m.msg("ExmplTwoValues|Example may not specify both a direct value and an external value URL"), - value); + results.addError(msg(ExmplTwoValues), value); } else if (!valuePresent && !externalPresent) { // the specification doesn't actually state that a value is required, but the // object seems pointless without one, so we'll go with a warning - results.addWarning(m.msg("ExmplNoValue|Example specifies neither a direct value nor an external value URL"), - value); + results.addWarning(msg(ExampleNoValue), value); } } } diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/HeaderValidator.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/HeaderValidator.java index 4331c8d6..0a110dcc 100755 --- a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/HeaderValidator.java +++ b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/HeaderValidator.java @@ -19,7 +19,9 @@ import static com.reprezen.kaizen.oasparser.ovl3.HeaderImpl.F_explode; import static com.reprezen.kaizen.oasparser.ovl3.HeaderImpl.F_schema; import static com.reprezen.kaizen.oasparser.ovl3.HeaderImpl.F_style; -import static com.reprezen.kaizen.oasparser.val.Messages.m; +import static com.reprezen.kaizen.oasparser.val.msg.Messages.msg; +import static com.reprezen.kaizen.oasparser.val3.OpenApi3Messages.IgnContType; +import static com.reprezen.kaizen.oasparser.val3.OpenApi3Messages.NonQryAllowRsvd; import com.reprezen.kaizen.oasparser.model3.Example; import com.reprezen.kaizen.oasparser.model3.Header; @@ -54,13 +56,13 @@ private void checkAllowReserved(Header header) { // TODO Q: Shouldn't "allowReserved" be disallowed for headers, as are "name" // and "in"? if (header.isAllowReserved()) { - results.addWarning(m.msg("NonQryAllowRsvd|AllowReserved is ignored for non-query parameter"), value); + results.addWarning(msg(NonQryAllowRsvd, value.getPathInParent(), "header"), value); } } private void checkContentType() { if (value.getPathInParent().equalsIgnoreCase("Content-Type")) { - results.addWarning(m.msg("IgnContType|Content-Type headers are ignored"), value); + results.addWarning(msg(IgnContType), value); } } } diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/LinkValidator.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/LinkValidator.java index bf03a021..04ba3ce8 100755 --- a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/LinkValidator.java +++ b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/LinkValidator.java @@ -12,7 +12,11 @@ import static com.reprezen.kaizen.oasparser.ovl3.LinkImpl.F_description; import static com.reprezen.kaizen.oasparser.ovl3.LinkImpl.F_requestBody; -import static com.reprezen.kaizen.oasparser.val.Messages.m; +import static com.reprezen.kaizen.oasparser.val.msg.Messages.msg; +import static com.reprezen.kaizen.oasparser.val3.OpenApi3Messages.NoOpIdNoOpRefInLink; +import static com.reprezen.kaizen.oasparser.val3.OpenApi3Messages.OpIdAndOpRefInLink; +import static com.reprezen.kaizen.oasparser.val3.OpenApi3Messages.OpIdNotFound; +import static com.reprezen.kaizen.oasparser.val3.OpenApi3Messages.OpPathNotFound; import java.util.Collection; import java.util.Map; @@ -52,32 +56,22 @@ private Operation checkValidOperation(Link link) { String operationRef = link.getOperationRef(); Operation op = null; if (opId == null && operationRef == null) { - results.addError( - m.msg("NoOpIdNoOpRefInLink|Link must contain eitehr 'operationRef' or 'operationId' properties"), - value); + results.addError(msg(NoOpIdNoOpRefInLink), value); } else if (opId != null && operationRef != null) { - results.addError( - m.msg("OpIdAndOpRefInLink|Link may not contain both 'operationRef' and 'operationId' properties"), - value); + results.addError(msg(OpIdAndOpRefInLink), value); } if (opId != null) { op = findOperationById(Overlay.of(link).getModel(), opId); if (op == null) { - results.addError( - m.msg("OpIdNotFound|OperationId in Link does not identify an operation in the containing model", - opId), - value); + results.addError(msg(OpIdNotFound, opId), value); } } String relativePath = getRelativePath(operationRef, results); if (relativePath != null) { op = findOperationByPath(Overlay.of(link).getModel(), relativePath, results); if (op == null) { - results.addError(m.msg( - "OpPathNotFound|Relative OperationRef in Link does not identify a GET operation in the containing model", - operationRef), value); + results.addError(msg(OpPathNotFound, operationRef), value); } - // } return op; } @@ -92,13 +86,9 @@ private void checkParameters(Link link, Operation op) { for (String paramName : params.keySet()) { int count = opParamCounts.get(paramName); if (count == 0) { - results.addError(m.msg("BadLinkParam|Link parameter does not appear in linked operation", paramName), - Overlay.of(params, paramName)); + results.addError(msg(OpenApi3Messages.BadLinkParam, paramName), Overlay.of(params, paramName)); } else if (count > 1) { - results.addWarning( - m.msg("AmbigLinkParam|Link parameter name appears more than once in linked operation", - paramName), - Overlay.of(params, paramName)); + results.addWarning(msg(OpenApi3Messages.AmbigLinkParam, paramName), Overlay.of(params, paramName)); } } } @@ -122,7 +112,7 @@ private Operation findOperationByPath(OpenApi3 model, String relativePath, Valid private String getRelativePath(String operationRef, ValidationResults results) { // TODO Q: will braces be pct-encoded as required for URIs? if (operationRef != null) { - results.addWarning(m.msg("OperationRefUnSupp|Link.operationRef is not yet supported"), value); + results.addWarning(msg(OpenApi3Messages.OperationRefUnSupp), value); } return null; } diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/MediaTypeValidator.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/MediaTypeValidator.java index 92d88ec4..806e8550 100755 --- a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/MediaTypeValidator.java +++ b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/MediaTypeValidator.java @@ -14,7 +14,8 @@ import static com.reprezen.kaizen.oasparser.ovl3.MediaTypeImpl.F_example; import static com.reprezen.kaizen.oasparser.ovl3.MediaTypeImpl.F_examples; import static com.reprezen.kaizen.oasparser.ovl3.MediaTypeImpl.F_schema; -import static com.reprezen.kaizen.oasparser.val.Messages.m; +import static com.reprezen.kaizen.oasparser.val.msg.Messages.msg; +import static com.reprezen.kaizen.oasparser.val3.OpenApi3Messages.EncPropNotSchemaProp; import java.util.Map; import java.util.Set; @@ -52,9 +53,8 @@ void checkEncodingPropsAreProps(MediaType mediaType, ValidationResults results) Map encProps = mediaType.getEncodingProperties(); for (String encodingPropertyName : encProps.keySet()) { if (!propNames.contains(encodingPropertyName)) { - results.addError(m.msg( - "EncPropNotSchemaProp|Encoding property does not name a schema property for the media type", - encodingPropertyName), Overlay.of(encProps, encodingPropertyName)); + results.addError(msg(EncPropNotSchemaProp, encodingPropertyName), + Overlay.of(encProps, encodingPropertyName)); } } } diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/OpenApi3Messages.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/OpenApi3Messages.java new file mode 100644 index 00000000..074356af --- /dev/null +++ b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/OpenApi3Messages.java @@ -0,0 +1,37 @@ +package com.reprezen.kaizen.oasparser.val3; + +import com.reprezen.kaizen.oasparser.val.msg.Messages; + +public enum OpenApi3Messages implements Messages { + ExmplTwoValues("Example may not specify both a direct value and an external value URL"), // + ExampleNoValue("Example specifies neither a direct value nor an external value URL"), // + NonQryAllowRsvd("AllowReserved is ignored for non-query parameter '%1 [%2]'"), // + IgnContType("Content-Type headers are ignored"), // + NoOpIdNoOpRefInLink("Link must contain eitehr 'operationRef' or 'operationId' properties"), // + OpIdAndOpRefInLink("Link may not contain both 'operationRef' and 'operationId' properties"), // + OpIdNotFound("OperationId in Link does not identify an operation in the containing model"), // + OpPathNotFound("Relative OperationRef in Link does not identify a GET operation in the containing model"), // + BadLinkParam("Link parameter does not appear in linked operation"), // + AmbigLinkParam("Link parameter name appears more than once in linked operation"), // + OperationRefUnSupp("Link.operationRef is not yet supported"), // + EncPropNotSchemaProp("Encoding property '%1' does not name a schema property for the media type"), // + MissingPathTplt("No template for path parameter '%1' in path string"), // + NoPath("Could not locate path for parameter '%1'"), // + PathParamReq("Path param '%1' must have 'required' property set true"), // + DiscNotProp("The discriminator '%1' is not a property of this schema"), // + DiscNotReq("The discriminator property '%1' must be required in this schema"), // + ROnlyAndWOnly("Schema cannot be both ReadOnly and WriteOnly"), // + UnkSecScheme("Security scheme not defined in model: %1"); + + private String formatString; + + private OpenApi3Messages(String formatString) { + this.formatString = formatString; + } + + @Override + public String getFormatString() { + return formatString; + } + +} diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/ParameterValidator.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/ParameterValidator.java index fdc5ef98..2b2938c7 100755 --- a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/ParameterValidator.java +++ b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/ParameterValidator.java @@ -21,7 +21,9 @@ import static com.reprezen.kaizen.oasparser.ovl3.ParameterImpl.F_name; import static com.reprezen.kaizen.oasparser.ovl3.ParameterImpl.F_schema; import static com.reprezen.kaizen.oasparser.ovl3.ParameterImpl.F_style; -import static com.reprezen.kaizen.oasparser.val.Messages.m; +import static com.reprezen.kaizen.oasparser.val.msg.Messages.msg; +import static com.reprezen.kaizen.oasparser.val3.OpenApi3Messages.NoPath; +import static com.reprezen.kaizen.oasparser.val3.OpenApi3Messages.PathParamReq; import java.util.Map; @@ -64,13 +66,10 @@ private void checkPathParam(Parameter parameter) { String path = getPathString(parameter); if (path != null) { if (!path.matches(".*/\\{" + parameter.getName() + "\\}(/.*)?")) { - results.addError(m.msg("MissingPathTplt|No template for path parameter in path string", - parameter.getName(), path), value); + results.addError(msg(OpenApi3Messages.MissingPathTplt, parameter.getName(), path), value); } } else { - results.addWarning( - m.msg("NoPath|Could not locate path for parameter", parameter.getName(), parameter.getIn()), - value); + results.addWarning(msg(NoPath, parameter.getName(), parameter.getIn()), value); } } } @@ -78,17 +77,14 @@ private void checkPathParam(Parameter parameter) { private void checkRequired(Parameter parameter) { if ("path".equals(parameter.getIn())) { if (parameter.getRequired() != Boolean.TRUE) { - results.addError( - m.msg("PathParamReq|Path param must have 'required' property set true", parameter.getName()), - value); + results.addError(msg(PathParamReq, parameter.getName()), value); } } } private void checkAllowReserved(Parameter parameter) { if (parameter.isAllowReserved() && !"query".equals(parameter.getIn())) { - results.addWarning(m.msg("NonQryAllowRsvd|AllowReserved is ignored for non-query parameter", - parameter.getName(), parameter.getIn()), value); + results.addWarning(msg(OpenApi3Messages.NonQryAllowRsvd, parameter.getName(), parameter.getIn()), value); } } diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/SchemaValidator.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/SchemaValidator.java index f57b4f9c..edab44bd 100755 --- a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/SchemaValidator.java +++ b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/SchemaValidator.java @@ -42,7 +42,9 @@ import static com.reprezen.kaizen.oasparser.ovl3.SchemaImpl.F_type; import static com.reprezen.kaizen.oasparser.ovl3.SchemaImpl.F_uniqueItems; import static com.reprezen.kaizen.oasparser.ovl3.SchemaImpl.F_xml; -import static com.reprezen.kaizen.oasparser.val.Messages.m; +import static com.reprezen.kaizen.oasparser.val.msg.Messages.msg; +import static com.reprezen.kaizen.oasparser.val3.OpenApi3Messages.DiscNotProp; +import static com.reprezen.kaizen.oasparser.val3.OpenApi3Messages.ROnlyAndWOnly; import com.reprezen.jsonoverlay.Overlay; import com.reprezen.kaizen.oasparser.model3.ExternalDocs; @@ -98,20 +100,17 @@ private void checkDiscriminator(Schema schema, Overlay context) { String discriminator = schema.getDiscriminator(); if (discriminator != null) { if (!schema.getProperties().keySet().contains(discriminator)) { - results.addError(m.msg("DiscNotProp|The discriminator is not a property of this schema", discriminator), - context); + results.addError(msg(DiscNotProp, discriminator), context); } if (!schema.getRequiredFields().contains(discriminator)) { - results.addError( - m.msg("DiscNotReq|The discriminator property is not required in this schema", discriminator), - context); + results.addError(msg(OpenApi3Messages.DiscNotReq, discriminator), context); } } } private void checkReadWrite(Schema schema) { if (schema.isReadOnly() && schema.isWriteOnly()) { - results.addError(m.msg("ROnlyAndWOnly|Schema cannot be both ReadOnly and WriteOnly"), value); + results.addError(msg(ROnlyAndWOnly), value); } } } diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/SecurityRequirementValidator.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/SecurityRequirementValidator.java index 2e81444a..e683daa5 100755 --- a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/SecurityRequirementValidator.java +++ b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/SecurityRequirementValidator.java @@ -11,7 +11,8 @@ package com.reprezen.kaizen.oasparser.val3; import static com.reprezen.kaizen.oasparser.ovl3.SecurityRequirementImpl.F_requirements; -import static com.reprezen.kaizen.oasparser.val.Messages.m; +import static com.reprezen.kaizen.oasparser.val.msg.Messages.msg; +import static com.reprezen.kaizen.oasparser.val3.OpenApi3Messages.UnkSecScheme; import java.util.Map; import java.util.Set; @@ -38,8 +39,7 @@ public void checkAllSchemesDefined(Overlay> requi MapOverlay mapOverlay = Overlay.getMapOverlay(requirements); for (String name : mapOverlay.keySet()) { if (!definedSchemes.contains(name)) { - results.addError(m.msg("UnkSecScheme|Security scheme not defined in model", name), - Overlay.of(mapOverlay, name)); + results.addError(msg(UnkSecScheme, name), Overlay.of(mapOverlay, name)); } } From 94f16905a952a41ccbc265816c774c93e81d0085 Mon Sep 17 00:00:00 2001 From: Andy Lowry Date: Wed, 22 Aug 2018 13:42:15 -0400 Subject: [PATCH 5/8] Revert "[#189] Upgraded existing validations to new msg scheme" This reverts commit 4428b5c7433f93e797ba11a4c816224a211e6d25. This change was intended for a separate branch --- .../oasparser/val/BaseValidationMessages.java | 15 +------ .../kaizen/oasparser/val/JsonTypeChecker.java | 14 +++--- .../kaizen/oasparser/val/Messages.java | 30 +++++++++++++ .../oasparser/val/ReferencesChecker.java | 7 +-- .../kaizen/oasparser/val/ValidatorBase.java | 44 ++++++++++--------- .../kaizen/oasparser/val/msg/Messages.java | 6 --- .../oasparser/val3/ExampleValidator.java | 11 ++--- .../oasparser/val3/HeaderValidator.java | 8 ++-- .../kaizen/oasparser/val3/LinkValidator.java | 34 +++++++++----- .../oasparser/val3/MediaTypeValidator.java | 8 ++-- .../oasparser/val3/OpenApi3Messages.java | 37 ---------------- .../oasparser/val3/ParameterValidator.java | 18 +++++--- .../oasparser/val3/SchemaValidator.java | 13 +++--- .../val3/SecurityRequirementValidator.java | 6 +-- 14 files changed, 120 insertions(+), 131 deletions(-) create mode 100755 kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/Messages.java delete mode 100644 kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/OpenApi3Messages.java diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/BaseValidationMessages.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/BaseValidationMessages.java index 4ad56551..0e94c985 100644 --- a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/BaseValidationMessages.java +++ b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/BaseValidationMessages.java @@ -3,19 +3,8 @@ import com.reprezen.kaizen.oasparser.val.msg.Messages; public enum BaseValidationMessages implements Messages { - WrongTypeJson("Incorrect JSON value type: %1; allowed types: %2"), // - BadRef("Reference '%1' could not be resolved: %2"), // - PatternMatchFail("Value '%1' does not match required pattern '%2'"), // - BadPattern("Pattern is not a valid Java Regular Expression but may be valid in ECMA 262: %1"), // - BadUrl("Invalid URL '%1': %2"), // - BadEmail("Invalid email address '%1': %2"), // - NumberConstraint("Value %1 must be %2"), // - EmptyList("List may not be empty"), // - DuplicateValue("Value at '%2' appeared already: %1"), // - MissingField("Required field '%1' is missing"), // - WrongTypeFormat("OpenAPI-defined format '%1' requires type '%3' but appears with missing or invalid type %2"), // - WrongTypeValue("Value is incompatible with schema type"); - + WrongTypeJson("Incorrect JSON Node type %1; allowed types: %2") // + ; private String formatString; BaseValidationMessages(String formatString) { diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/JsonTypeChecker.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/JsonTypeChecker.java index bd538b75..76702749 100755 --- a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/JsonTypeChecker.java +++ b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/JsonTypeChecker.java @@ -11,10 +11,10 @@ package com.reprezen.kaizen.oasparser.val; import static com.reprezen.kaizen.oasparser.val.BaseValidationMessages.WrongTypeJson; -import static com.reprezen.kaizen.oasparser.val.msg.Messages.msg; import java.util.Arrays; import java.util.Collection; +import java.util.List; import java.util.stream.Collectors; import com.fasterxml.jackson.databind.JsonNode; @@ -39,6 +39,7 @@ import com.reprezen.jsonoverlay.PrimitiveOverlay; import com.reprezen.jsonoverlay.PropertiesOverlay; import com.reprezen.jsonoverlay.StringOverlay; +import com.reprezen.kaizen.oasparser.val.msg.Messages; public class JsonTypeChecker { @@ -51,17 +52,12 @@ public static void checkJsonType(Overlay value, ValidationResults results) { return; } } - String allowed = allowedJsonTypes.stream().map(type -> getJsonValueType(type)) - .collect(Collectors.joining(", ")); - results.addError(msg(WrongTypeJson, getJsonValueType(json.getClass()), allowed), value); + List allowed = allowedJsonTypes.stream().map(type -> type.getSimpleName()) + .collect(Collectors.toList()); + results.addError(Messages.msg(WrongTypeJson, json.getClass().getSimpleName(), allowed), value); } } - private static String getJsonValueType(Class node) { - String type = node.getSimpleName(); - return type.endsWith("Node") ? type.substring(0, type.length() - 4) : type; - } - private static Multimap, Class> allowedJsonTypes = null; private static Collection> getAllowedJsonTypes(Overlay value) { diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/Messages.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/Messages.java new file mode 100755 index 00000000..be33e42a --- /dev/null +++ b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/Messages.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2017 ModelSolv, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * ModelSolv, Inc. - initial API and implementation and/or initial documentation + *******************************************************************************/ +package com.reprezen.kaizen.oasparser.val; + +import java.util.Arrays; + +public class Messages { + public static Messages m = new Messages(); + + public String msg(String text, Object... args) { + int pos = text.indexOf('|'); + if (pos >= 0) { + String nls = nls(text.substring(0, pos)); + text = nls != null ? nls : text.substring(pos + 1); + } + return String.format("%s %s", text, Arrays.asList(args)); + } + + public String nls(String text) { + return null; + } +} diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/ReferencesChecker.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/ReferencesChecker.java index 250ffe1b..081a6870 100755 --- a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/ReferencesChecker.java +++ b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/ReferencesChecker.java @@ -10,8 +10,7 @@ *******************************************************************************/ package com.reprezen.kaizen.oasparser.val; -import static com.reprezen.kaizen.oasparser.val.BaseValidationMessages.BadRef; -import static com.reprezen.kaizen.oasparser.val.msg.Messages.msg; +import static com.reprezen.kaizen.oasparser.val.Messages.m; import com.reprezen.jsonoverlay.ListOverlay; import com.reprezen.jsonoverlay.MapOverlay; @@ -52,7 +51,9 @@ public static void checkReferences(PropertiesOverlay props, ValidationResults public static void checkReference(Reference ref, ValidationResults results, Overlay context) { if (ref.isInvalid()) { - results.addError(msg(BadRef, ref.getRefString(), ref.getInvalidReason()), context); + results.addError( + m.msg("BadRef|JSON reference node was not resolved", ref.getRefString(), ref.getInvalidReason()), + context); } } } diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/ValidatorBase.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/ValidatorBase.java index e2603681..0e52ed60 100755 --- a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/ValidatorBase.java +++ b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/ValidatorBase.java @@ -1,14 +1,6 @@ package com.reprezen.kaizen.oasparser.val; -import static com.reprezen.kaizen.oasparser.val.BaseValidationMessages.BadEmail; -import static com.reprezen.kaizen.oasparser.val.BaseValidationMessages.BadPattern; -import static com.reprezen.kaizen.oasparser.val.BaseValidationMessages.BadUrl; -import static com.reprezen.kaizen.oasparser.val.BaseValidationMessages.DuplicateValue; -import static com.reprezen.kaizen.oasparser.val.BaseValidationMessages.EmptyList; -import static com.reprezen.kaizen.oasparser.val.BaseValidationMessages.MissingField; -import static com.reprezen.kaizen.oasparser.val.BaseValidationMessages.NumberConstraint; -import static com.reprezen.kaizen.oasparser.val.BaseValidationMessages.PatternMatchFail; -import static com.reprezen.kaizen.oasparser.val.msg.Messages.msg; +import static com.reprezen.kaizen.oasparser.val.Messages.m; import java.net.MalformedURLException; import java.net.URL; @@ -74,7 +66,9 @@ public final Overlay validateStringField(String name, boolean required, void checkPattern(Overlay field, Pattern pattern) { if (!pattern.matcher(field.get()).matches()) { - results.addError(msg(PatternMatchFail, field.get(), pattern), field); + results.addError( + m.msg("PatternMatchFail|String value does not match required pattern", field.get(), pattern), + field); } } @@ -87,7 +81,9 @@ private void checkRegex(Overlay field) { try { Pattern.compile(regex); } catch (PatternSyntaxException e) { - results.addWarning(msg(BadPattern, regex), field); + results.addWarning( + m.msg("BadPattern|Pattern is not a valid Java Regular Expression but may be valid ECMA 262", regex), + field); } } @@ -130,7 +126,7 @@ private void checkUrl(Overlay overlay, boolean allowVars) { try { new URL(url); } catch (MalformedURLException e) { - results.addError(msg(BadUrl, origUrl, e.toString()), overlay); + results.addError(m.msg("BadUrl|Invalid URL", origUrl, e.toString()), overlay); } } @@ -170,7 +166,7 @@ private void checkEmail(Overlay overlay) { addr.setAddress(email); addr.validate(); } catch (AddressException e) { - results.addError(msg(BadEmail, email, e.toString()), overlay); + results.addError(m.msg("BadEmail|Invalid email address", email, e.toString()), overlay); } } @@ -189,7 +185,7 @@ public Overlay validateNumericField(String name, boolean required, Funct if (field != null && field.isPresent() && test != null) { Number n = field.get(); if (!test.apply(n)) { - results.addError(msg(NumberConstraint, desc, n), field); + results.addError(m.msg("ReqPositive|Value must be " + desc, n), field); } } return field; @@ -232,7 +228,7 @@ private void checkListNotEmpty(Overlay> list, boolean nonEmpty) { ListOverlay listOverlay = Overlay.getListOverlay(list); if (list != null && !list.isPresent()) { if (nonEmpty && listOverlay.size() == 0) { - results.addError(msg(EmptyList), list); + results.addError(m.msg("EmptyList|List may not be empty"), list); } } } @@ -245,7 +241,8 @@ private void checkListUnique(Overlay> list, boolean unique) { for (int i = 0; i < listOverlay.size(); i++) { X item = listOverlay.get(i); if (seen.contains(item)) { - results.addError(msg(DuplicateValue, item, i), Overlay.of(listOverlay, i)); + results.addError(m.msg("DuplicateValue|Value appeared already", item, i), + Overlay.of(listOverlay, i)); } else { seen.add(item); } @@ -274,7 +271,7 @@ private void checkMapNotEmpty(Overlay> list, boolean nonEmpty MapOverlay mapOverlay = Overlay.getMapOverlay(list); if (list != null && !list.isPresent()) { if (nonEmpty && mapOverlay.size() == 0) { - results.addError(msg(EmptyList), list); + results.addError(m.msg("EmptyList|List may not be empty"), list); } } } @@ -287,7 +284,8 @@ private void checkMapUnique(Overlay> map, boolean unique) { for (String key : mapOverlay.keySet()) { X value = mapOverlay.get(key); if (seen.contains(value)) { - results.addError(msg(DuplicateValue, value, key), Overlay.of(mapOverlay, key)); + results.addError(m.msg("DuplicateValue|Value appeared already", value, key), + Overlay.of(mapOverlay, key)); } else { seen.add(value); } @@ -297,7 +295,7 @@ private void checkMapUnique(Overlay> map, boolean unique) { void checkMissing(Overlay field, boolean required) { if (required && (field == null || !field.isPresent())) { - results.addError(msg(MissingField, field.getPathInParent()), value); + results.addError(m.msg("MissingField|required field is missing", field.getPathInParent()), value); } } @@ -333,7 +331,10 @@ public Overlay validateFormatField(String name, boolean required, String } if (normalType != null) { if (type == null || !type.equals(normalType)) { - results.addWarning(msg(BaseValidationMessages.WrongTypeFormat, field, type, normalType), field); + results.addWarning( + m.msg("WrongTypeFormat|OpenAPI-defined format used with nonstandard or missing type", field, + type, normalType), + field); } } } @@ -365,7 +366,8 @@ public void checkDefault(Overlay overlay, String type) { break; } if (!ok) { - results.addError(msg(BaseValidationMessages.WrongTypeValue, type, defaultValue), overlay); + results.addError(m.msg("WrongTypeValue|Value is incompatible with schema type", type, defaultValue), + overlay); } } } diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/msg/Messages.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/msg/Messages.java index 3a70ad89..37ebad60 100644 --- a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/msg/Messages.java +++ b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/msg/Messages.java @@ -4,12 +4,6 @@ import java.util.Properties; public interface Messages { - - // TODO: add a method to test a localization file for missing and invalid - // property names (compare all the property keys to the enum value names). This - // should be easily executed by a main method in the enum class. It would be - // great to also flag localized messages whose list of placeholder positions - // does not match that of the default message. public String getFormatString(); public String name(); diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/ExampleValidator.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/ExampleValidator.java index d2d6258a..22d20d38 100644 --- a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/ExampleValidator.java +++ b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/ExampleValidator.java @@ -14,9 +14,7 @@ import static com.reprezen.kaizen.oasparser.ovl3.ExampleImpl.F_externalValue; import static com.reprezen.kaizen.oasparser.ovl3.ExampleImpl.F_summary; import static com.reprezen.kaizen.oasparser.ovl3.ExampleImpl.F_value; -import static com.reprezen.kaizen.oasparser.val.msg.Messages.msg; -import static com.reprezen.kaizen.oasparser.val3.OpenApi3Messages.ExampleNoValue; -import static com.reprezen.kaizen.oasparser.val3.OpenApi3Messages.ExmplTwoValues; +import static com.reprezen.kaizen.oasparser.val.Messages.m; import com.reprezen.jsonoverlay.Overlay; import com.reprezen.kaizen.oasparser.model3.Example; @@ -41,11 +39,14 @@ private void checkExactlyOneValue(Overlay valueField, Overlay ex boolean valuePresent = valueField != null & valueField.isPresent(); boolean externalPresent = externalField != null && externalField.isPresent(); if (valuePresent && externalPresent) { - results.addError(msg(ExmplTwoValues), value); + results.addError( + m.msg("ExmplTwoValues|Example may not specify both a direct value and an external value URL"), + value); } else if (!valuePresent && !externalPresent) { // the specification doesn't actually state that a value is required, but the // object seems pointless without one, so we'll go with a warning - results.addWarning(msg(ExampleNoValue), value); + results.addWarning(m.msg("ExmplNoValue|Example specifies neither a direct value nor an external value URL"), + value); } } } diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/HeaderValidator.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/HeaderValidator.java index 0a110dcc..4331c8d6 100755 --- a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/HeaderValidator.java +++ b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/HeaderValidator.java @@ -19,9 +19,7 @@ import static com.reprezen.kaizen.oasparser.ovl3.HeaderImpl.F_explode; import static com.reprezen.kaizen.oasparser.ovl3.HeaderImpl.F_schema; import static com.reprezen.kaizen.oasparser.ovl3.HeaderImpl.F_style; -import static com.reprezen.kaizen.oasparser.val.msg.Messages.msg; -import static com.reprezen.kaizen.oasparser.val3.OpenApi3Messages.IgnContType; -import static com.reprezen.kaizen.oasparser.val3.OpenApi3Messages.NonQryAllowRsvd; +import static com.reprezen.kaizen.oasparser.val.Messages.m; import com.reprezen.kaizen.oasparser.model3.Example; import com.reprezen.kaizen.oasparser.model3.Header; @@ -56,13 +54,13 @@ private void checkAllowReserved(Header header) { // TODO Q: Shouldn't "allowReserved" be disallowed for headers, as are "name" // and "in"? if (header.isAllowReserved()) { - results.addWarning(msg(NonQryAllowRsvd, value.getPathInParent(), "header"), value); + results.addWarning(m.msg("NonQryAllowRsvd|AllowReserved is ignored for non-query parameter"), value); } } private void checkContentType() { if (value.getPathInParent().equalsIgnoreCase("Content-Type")) { - results.addWarning(msg(IgnContType), value); + results.addWarning(m.msg("IgnContType|Content-Type headers are ignored"), value); } } } diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/LinkValidator.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/LinkValidator.java index 04ba3ce8..bf03a021 100755 --- a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/LinkValidator.java +++ b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/LinkValidator.java @@ -12,11 +12,7 @@ import static com.reprezen.kaizen.oasparser.ovl3.LinkImpl.F_description; import static com.reprezen.kaizen.oasparser.ovl3.LinkImpl.F_requestBody; -import static com.reprezen.kaizen.oasparser.val.msg.Messages.msg; -import static com.reprezen.kaizen.oasparser.val3.OpenApi3Messages.NoOpIdNoOpRefInLink; -import static com.reprezen.kaizen.oasparser.val3.OpenApi3Messages.OpIdAndOpRefInLink; -import static com.reprezen.kaizen.oasparser.val3.OpenApi3Messages.OpIdNotFound; -import static com.reprezen.kaizen.oasparser.val3.OpenApi3Messages.OpPathNotFound; +import static com.reprezen.kaizen.oasparser.val.Messages.m; import java.util.Collection; import java.util.Map; @@ -56,22 +52,32 @@ private Operation checkValidOperation(Link link) { String operationRef = link.getOperationRef(); Operation op = null; if (opId == null && operationRef == null) { - results.addError(msg(NoOpIdNoOpRefInLink), value); + results.addError( + m.msg("NoOpIdNoOpRefInLink|Link must contain eitehr 'operationRef' or 'operationId' properties"), + value); } else if (opId != null && operationRef != null) { - results.addError(msg(OpIdAndOpRefInLink), value); + results.addError( + m.msg("OpIdAndOpRefInLink|Link may not contain both 'operationRef' and 'operationId' properties"), + value); } if (opId != null) { op = findOperationById(Overlay.of(link).getModel(), opId); if (op == null) { - results.addError(msg(OpIdNotFound, opId), value); + results.addError( + m.msg("OpIdNotFound|OperationId in Link does not identify an operation in the containing model", + opId), + value); } } String relativePath = getRelativePath(operationRef, results); if (relativePath != null) { op = findOperationByPath(Overlay.of(link).getModel(), relativePath, results); if (op == null) { - results.addError(msg(OpPathNotFound, operationRef), value); + results.addError(m.msg( + "OpPathNotFound|Relative OperationRef in Link does not identify a GET operation in the containing model", + operationRef), value); } + // } return op; } @@ -86,9 +92,13 @@ private void checkParameters(Link link, Operation op) { for (String paramName : params.keySet()) { int count = opParamCounts.get(paramName); if (count == 0) { - results.addError(msg(OpenApi3Messages.BadLinkParam, paramName), Overlay.of(params, paramName)); + results.addError(m.msg("BadLinkParam|Link parameter does not appear in linked operation", paramName), + Overlay.of(params, paramName)); } else if (count > 1) { - results.addWarning(msg(OpenApi3Messages.AmbigLinkParam, paramName), Overlay.of(params, paramName)); + results.addWarning( + m.msg("AmbigLinkParam|Link parameter name appears more than once in linked operation", + paramName), + Overlay.of(params, paramName)); } } } @@ -112,7 +122,7 @@ private Operation findOperationByPath(OpenApi3 model, String relativePath, Valid private String getRelativePath(String operationRef, ValidationResults results) { // TODO Q: will braces be pct-encoded as required for URIs? if (operationRef != null) { - results.addWarning(msg(OpenApi3Messages.OperationRefUnSupp), value); + results.addWarning(m.msg("OperationRefUnSupp|Link.operationRef is not yet supported"), value); } return null; } diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/MediaTypeValidator.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/MediaTypeValidator.java index 806e8550..92d88ec4 100755 --- a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/MediaTypeValidator.java +++ b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/MediaTypeValidator.java @@ -14,8 +14,7 @@ import static com.reprezen.kaizen.oasparser.ovl3.MediaTypeImpl.F_example; import static com.reprezen.kaizen.oasparser.ovl3.MediaTypeImpl.F_examples; import static com.reprezen.kaizen.oasparser.ovl3.MediaTypeImpl.F_schema; -import static com.reprezen.kaizen.oasparser.val.msg.Messages.msg; -import static com.reprezen.kaizen.oasparser.val3.OpenApi3Messages.EncPropNotSchemaProp; +import static com.reprezen.kaizen.oasparser.val.Messages.m; import java.util.Map; import java.util.Set; @@ -53,8 +52,9 @@ void checkEncodingPropsAreProps(MediaType mediaType, ValidationResults results) Map encProps = mediaType.getEncodingProperties(); for (String encodingPropertyName : encProps.keySet()) { if (!propNames.contains(encodingPropertyName)) { - results.addError(msg(EncPropNotSchemaProp, encodingPropertyName), - Overlay.of(encProps, encodingPropertyName)); + results.addError(m.msg( + "EncPropNotSchemaProp|Encoding property does not name a schema property for the media type", + encodingPropertyName), Overlay.of(encProps, encodingPropertyName)); } } } diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/OpenApi3Messages.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/OpenApi3Messages.java deleted file mode 100644 index 074356af..00000000 --- a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/OpenApi3Messages.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.reprezen.kaizen.oasparser.val3; - -import com.reprezen.kaizen.oasparser.val.msg.Messages; - -public enum OpenApi3Messages implements Messages { - ExmplTwoValues("Example may not specify both a direct value and an external value URL"), // - ExampleNoValue("Example specifies neither a direct value nor an external value URL"), // - NonQryAllowRsvd("AllowReserved is ignored for non-query parameter '%1 [%2]'"), // - IgnContType("Content-Type headers are ignored"), // - NoOpIdNoOpRefInLink("Link must contain eitehr 'operationRef' or 'operationId' properties"), // - OpIdAndOpRefInLink("Link may not contain both 'operationRef' and 'operationId' properties"), // - OpIdNotFound("OperationId in Link does not identify an operation in the containing model"), // - OpPathNotFound("Relative OperationRef in Link does not identify a GET operation in the containing model"), // - BadLinkParam("Link parameter does not appear in linked operation"), // - AmbigLinkParam("Link parameter name appears more than once in linked operation"), // - OperationRefUnSupp("Link.operationRef is not yet supported"), // - EncPropNotSchemaProp("Encoding property '%1' does not name a schema property for the media type"), // - MissingPathTplt("No template for path parameter '%1' in path string"), // - NoPath("Could not locate path for parameter '%1'"), // - PathParamReq("Path param '%1' must have 'required' property set true"), // - DiscNotProp("The discriminator '%1' is not a property of this schema"), // - DiscNotReq("The discriminator property '%1' must be required in this schema"), // - ROnlyAndWOnly("Schema cannot be both ReadOnly and WriteOnly"), // - UnkSecScheme("Security scheme not defined in model: %1"); - - private String formatString; - - private OpenApi3Messages(String formatString) { - this.formatString = formatString; - } - - @Override - public String getFormatString() { - return formatString; - } - -} diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/ParameterValidator.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/ParameterValidator.java index 2b2938c7..fdc5ef98 100755 --- a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/ParameterValidator.java +++ b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/ParameterValidator.java @@ -21,9 +21,7 @@ import static com.reprezen.kaizen.oasparser.ovl3.ParameterImpl.F_name; import static com.reprezen.kaizen.oasparser.ovl3.ParameterImpl.F_schema; import static com.reprezen.kaizen.oasparser.ovl3.ParameterImpl.F_style; -import static com.reprezen.kaizen.oasparser.val.msg.Messages.msg; -import static com.reprezen.kaizen.oasparser.val3.OpenApi3Messages.NoPath; -import static com.reprezen.kaizen.oasparser.val3.OpenApi3Messages.PathParamReq; +import static com.reprezen.kaizen.oasparser.val.Messages.m; import java.util.Map; @@ -66,10 +64,13 @@ private void checkPathParam(Parameter parameter) { String path = getPathString(parameter); if (path != null) { if (!path.matches(".*/\\{" + parameter.getName() + "\\}(/.*)?")) { - results.addError(msg(OpenApi3Messages.MissingPathTplt, parameter.getName(), path), value); + results.addError(m.msg("MissingPathTplt|No template for path parameter in path string", + parameter.getName(), path), value); } } else { - results.addWarning(msg(NoPath, parameter.getName(), parameter.getIn()), value); + results.addWarning( + m.msg("NoPath|Could not locate path for parameter", parameter.getName(), parameter.getIn()), + value); } } } @@ -77,14 +78,17 @@ private void checkPathParam(Parameter parameter) { private void checkRequired(Parameter parameter) { if ("path".equals(parameter.getIn())) { if (parameter.getRequired() != Boolean.TRUE) { - results.addError(msg(PathParamReq, parameter.getName()), value); + results.addError( + m.msg("PathParamReq|Path param must have 'required' property set true", parameter.getName()), + value); } } } private void checkAllowReserved(Parameter parameter) { if (parameter.isAllowReserved() && !"query".equals(parameter.getIn())) { - results.addWarning(msg(OpenApi3Messages.NonQryAllowRsvd, parameter.getName(), parameter.getIn()), value); + results.addWarning(m.msg("NonQryAllowRsvd|AllowReserved is ignored for non-query parameter", + parameter.getName(), parameter.getIn()), value); } } diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/SchemaValidator.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/SchemaValidator.java index edab44bd..f57b4f9c 100755 --- a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/SchemaValidator.java +++ b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/SchemaValidator.java @@ -42,9 +42,7 @@ import static com.reprezen.kaizen.oasparser.ovl3.SchemaImpl.F_type; import static com.reprezen.kaizen.oasparser.ovl3.SchemaImpl.F_uniqueItems; import static com.reprezen.kaizen.oasparser.ovl3.SchemaImpl.F_xml; -import static com.reprezen.kaizen.oasparser.val.msg.Messages.msg; -import static com.reprezen.kaizen.oasparser.val3.OpenApi3Messages.DiscNotProp; -import static com.reprezen.kaizen.oasparser.val3.OpenApi3Messages.ROnlyAndWOnly; +import static com.reprezen.kaizen.oasparser.val.Messages.m; import com.reprezen.jsonoverlay.Overlay; import com.reprezen.kaizen.oasparser.model3.ExternalDocs; @@ -100,17 +98,20 @@ private void checkDiscriminator(Schema schema, Overlay context) { String discriminator = schema.getDiscriminator(); if (discriminator != null) { if (!schema.getProperties().keySet().contains(discriminator)) { - results.addError(msg(DiscNotProp, discriminator), context); + results.addError(m.msg("DiscNotProp|The discriminator is not a property of this schema", discriminator), + context); } if (!schema.getRequiredFields().contains(discriminator)) { - results.addError(msg(OpenApi3Messages.DiscNotReq, discriminator), context); + results.addError( + m.msg("DiscNotReq|The discriminator property is not required in this schema", discriminator), + context); } } } private void checkReadWrite(Schema schema) { if (schema.isReadOnly() && schema.isWriteOnly()) { - results.addError(msg(ROnlyAndWOnly), value); + results.addError(m.msg("ROnlyAndWOnly|Schema cannot be both ReadOnly and WriteOnly"), value); } } } diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/SecurityRequirementValidator.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/SecurityRequirementValidator.java index e683daa5..2e81444a 100755 --- a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/SecurityRequirementValidator.java +++ b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/SecurityRequirementValidator.java @@ -11,8 +11,7 @@ package com.reprezen.kaizen.oasparser.val3; import static com.reprezen.kaizen.oasparser.ovl3.SecurityRequirementImpl.F_requirements; -import static com.reprezen.kaizen.oasparser.val.msg.Messages.msg; -import static com.reprezen.kaizen.oasparser.val3.OpenApi3Messages.UnkSecScheme; +import static com.reprezen.kaizen.oasparser.val.Messages.m; import java.util.Map; import java.util.Set; @@ -39,7 +38,8 @@ public void checkAllSchemesDefined(Overlay> requi MapOverlay mapOverlay = Overlay.getMapOverlay(requirements); for (String name : mapOverlay.keySet()) { if (!definedSchemes.contains(name)) { - results.addError(msg(UnkSecScheme, name), Overlay.of(mapOverlay, name)); + results.addError(m.msg("UnkSecScheme|Security scheme not defined in model", name), + Overlay.of(mapOverlay, name)); } } From 3d8fda59a039b09598a6393260c5369b3027765e Mon Sep 17 00:00:00 2001 From: Andy Lowry Date: Wed, 22 Aug 2018 13:42:46 -0400 Subject: [PATCH 6/8] Revert "[#189] New replacement for Messages class" This reverts commit 5dc109b4f2c7abf6dc4e3b9c7d4c129d7e45d8c6. This change was intended for a different branch --- .../oasparser/val/BaseValidationMessages.java | 19 --- .../kaizen/oasparser/val/JsonTypeChecker.java | 10 +- .../kaizen/oasparser/val/msg/Messages.java | 36 ------ .../oasparser/val/msg/MessagesHelper.java | 114 ------------------ 4 files changed, 3 insertions(+), 176 deletions(-) delete mode 100644 kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/BaseValidationMessages.java delete mode 100644 kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/msg/Messages.java delete mode 100644 kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/msg/MessagesHelper.java diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/BaseValidationMessages.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/BaseValidationMessages.java deleted file mode 100644 index 0e94c985..00000000 --- a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/BaseValidationMessages.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.reprezen.kaizen.oasparser.val; - -import com.reprezen.kaizen.oasparser.val.msg.Messages; - -public enum BaseValidationMessages implements Messages { - WrongTypeJson("Incorrect JSON Node type %1; allowed types: %2") // - ; - private String formatString; - - BaseValidationMessages(String formatString) { - this.formatString = formatString; - } - - @Override - public String getFormatString() { - return formatString; - } - -} diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/JsonTypeChecker.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/JsonTypeChecker.java index 76702749..2e3e3876 100755 --- a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/JsonTypeChecker.java +++ b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/JsonTypeChecker.java @@ -10,12 +10,10 @@ *******************************************************************************/ package com.reprezen.kaizen.oasparser.val; -import static com.reprezen.kaizen.oasparser.val.BaseValidationMessages.WrongTypeJson; +import static com.reprezen.kaizen.oasparser.val.Messages.m; import java.util.Arrays; import java.util.Collection; -import java.util.List; -import java.util.stream.Collectors; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; @@ -39,7 +37,6 @@ import com.reprezen.jsonoverlay.PrimitiveOverlay; import com.reprezen.jsonoverlay.PropertiesOverlay; import com.reprezen.jsonoverlay.StringOverlay; -import com.reprezen.kaizen.oasparser.val.msg.Messages; public class JsonTypeChecker { @@ -52,9 +49,8 @@ public static void checkJsonType(Overlay value, ValidationResults results) { return; } } - List allowed = allowedJsonTypes.stream().map(type -> type.getSimpleName()) - .collect(Collectors.toList()); - results.addError(Messages.msg(WrongTypeJson, json.getClass().getSimpleName(), allowed), value); + results.addError(m.msg("WrongTypeJson|Property bound to incompatible JSON Node type", json.getNodeType(), + allowedJsonTypes), value); } } diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/msg/Messages.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/msg/Messages.java deleted file mode 100644 index 37ebad60..00000000 --- a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/msg/Messages.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.reprezen.kaizen.oasparser.val.msg; - -import java.util.Locale; -import java.util.Properties; - -public interface Messages { - public String getFormatString(); - - public String name(); - - public default String getFormatString(Locale locale) { - Properties localeStrings = locale != null ? getFormatStrings(locale) : null; - String formatString = localeStrings != null ? localeStrings.getProperty(name()) : null; - return formatString != null ? formatString : getFormatString(); - } - - public default Properties getFormatStrings(Locale locale) { - return MessagesHelper.loadLocalizations(this.getClass(), locale); - } - - public default String msg(Object... args) { - return msg(Locale.getDefault(), args); - } - - public default String msgNoLocale(Object... args) { - return msg((Locale) null, args); - } - - public default String msg(Locale locale, Object... args) { - return MessagesHelper.format(locale, this, args); - } - - public static String msg(Messages instance, Object... args) { - return instance.msg(args); - } -} diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/msg/MessagesHelper.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/msg/MessagesHelper.java deleted file mode 100644 index 4dac756e..00000000 --- a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/msg/MessagesHelper.java +++ /dev/null @@ -1,114 +0,0 @@ -package com.reprezen.kaizen.oasparser.val.msg; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Properties; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -public class MessagesHelper { - private static final Pattern placeholderPattern = Pattern.compile("%(\\d+)|%\\{(\\d+)\\}"); - - /** - * Interpolate arguments into the message format string for the given message. - *

- * If a non-null locale is provided, an attempt is made to load a properties - * file for the Message class of which this message is an instance, and the - * property named by this message's name is used as the format string. If that - * fails, or if the locale is null, the message object's default format string - * is used. - *

- * The format string contains embedded place holders indicating where arguments - * are to be substituted. Each place holder takes the form %n or - * %{n}, where n is an integer from 1 to the number of - * arguments. The second form allows interpolation at a site immediately - * followed by other digits. - *

- * To prevent a percent sign from triggering interpolation, double it: - * %%. For example, "%%1 %%{2}" will always produce - * "%1 %{2}". - *

- * The result is obtained by replacing each placeholder with the corresponding - * argument's {@link #toString()} value (except that null arguments are rendered - * as empty strings). - * - * @param message - * @param args - * @return message with interpolated arguments - */ - public static String format(Locale locale, Messages message, Object... args) { - String formatString = message.getFormatString(locale); - Object[] sortArgs = sortArgs(formatString, args); - String printfString = Stream.of(formatString.split("%%")) - .map(part -> placeholderPattern.matcher(part).replaceAll("%s")) // - .collect(Collectors.joining("%%")); - return String.format(printfString, sortArgs); - } - - private static Object[] sortArgs(String format, Object[] args) { - List sites = findInterpolationSites(format); - sites.stream().forEach(site -> { - if (site < 1 || site > args.length) { - String msg = String.format("Interpolation position must be from 1 to %d: %%%d", args.length, site); - throw new IndexOutOfBoundsException(msg); - } - }); - return sites.stream().map(i -> args[i - 1] != null ? args[i - 1] : "").toArray(); - } - - private static List findInterpolationSites(String format) { - List sites = new ArrayList<>(); - String[] parts = format.split("%%"); - for (String part : parts) { - Matcher m = placeholderPattern.matcher(part); - while (m.find()) { - boolean braces = m.group(1) == null; - String digits = m.group(braces ? 2 : 1); - int index = digits.isEmpty() ? 0 : Integer.valueOf(digits); - sites.add(index); - } - } - return sites; - } - - private static Map, Map> localizationsByClass = new HashMap<>(); - - public static Properties loadLocalizations(Class msgClass, Locale locale) { - if (!localizationsByClass.containsKey(msgClass)) { - localizationsByClass.put(msgClass, new HashMap<>()); - } - Map localizations = localizationsByClass.get(msgClass); - // try locale-specified variant tag first, then fall back to just the language - // code - for (String tag : Arrays.asList(locale.toLanguageTag(), locale.getLanguage())) { - if (!localizations.containsKey(tag)) { - URL resource = msgClass.getResource(String.format("localizations/%s/messages.properties", tag)); - Properties props = null; - if (resource != null) { - props = new Properties(); - try (InputStream in = resource.openStream()) { - props.load(in); - } catch (IOException e) { - props = null; - } - } - // if no props loaded, set null value in localizations so we don't keep trying - localizations.put(tag, props); - } - Properties result = localizations.get(tag); - if (result != null) { - return result; - } - } - return null; - } -} From 6d229928dd4c6fe774bd1d8e14223ce9fcfcc17f Mon Sep 17 00:00:00 2001 From: Andy Lowry Date: Wed, 22 Aug 2018 14:22:46 -0400 Subject: [PATCH 7/8] [#189] add new package to exports for KZOP --- kaizen-openapi-parser/p2/pom.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kaizen-openapi-parser/p2/pom.xml b/kaizen-openapi-parser/p2/pom.xml index 44300495..a1098f8b 100644 --- a/kaizen-openapi-parser/p2/pom.xml +++ b/kaizen-openapi-parser/p2/pom.xml @@ -36,7 +36,8 @@ com.reprezen.kaizen.oasparser, com.reprezen.kaizen.oasparser.model3, com.reprezen.kaizen.oasparser.ovl3, - com.reprezen.kaizen.oasparser.val + com.reprezen.kaizen.oasparser.val, + com.reprezen.kaizen.oasparser.val.msg From b9704215944041a0caec1caf8d9d6fd8b51469f1 Mon Sep 17 00:00:00 2001 From: Andy Lowry Date: Wed, 22 Aug 2018 17:09:51 -0400 Subject: [PATCH 8/8] {#191] Removed uses of guava --- .../kaizen/oasparser/val/JsonTypeChecker.java | 28 +++++++++---------- .../kaizen/oasparser/val/NumericUtils.java | 5 ++-- .../oasparser/val/ValidationResults.java | 4 +-- .../kaizen/oasparser/val/ValidatorBase.java | 6 ++-- .../kaizen/oasparser/val3/LinkValidator.java | 4 +-- 5 files changed, 23 insertions(+), 24 deletions(-) diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/JsonTypeChecker.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/JsonTypeChecker.java index 2e3e3876..0492c5d2 100755 --- a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/JsonTypeChecker.java +++ b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/JsonTypeChecker.java @@ -14,6 +14,9 @@ import java.util.Arrays; import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; @@ -24,8 +27,6 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ShortNode; import com.fasterxml.jackson.databind.node.TextNode; -import com.google.common.collect.ArrayListMultimap; -import com.google.common.collect.Multimap; import com.reprezen.jsonoverlay.BooleanOverlay; import com.reprezen.jsonoverlay.IntegerOverlay; import com.reprezen.jsonoverlay.JsonOverlay; @@ -54,7 +55,7 @@ public static void checkJsonType(Overlay value, ValidationResults results) { } } - private static Multimap, Class> allowedJsonTypes = null; + private static Map, List>> allowedJsonTypes = null; private static Collection> getAllowedJsonTypes(Overlay value) { if (allowedJsonTypes == null) { @@ -66,17 +67,16 @@ private static Collection> getAllowedJsonTypes(Overlay } private static void createAllowedJsonTypes() { - Multimap, Class> types = ArrayListMultimap - ., Class>create(); - types.put(StringOverlay.class, TextNode.class); - types.put(BooleanOverlay.class, BooleanNode.class); - types.putAll(IntegerOverlay.class, Arrays.asList(IntNode.class, ShortNode.class, BigIntegerNode.class)); - types.put(NumberOverlay.class, NumericNode.class); - types.putAll(PrimitiveOverlay.class, Arrays.asList(TextNode.class, NumericNode.class, BooleanNode.class)); - types.put(ObjectOverlay.class, JsonNode.class); - types.put(MapOverlay.class, ObjectNode.class); - types.put(ListOverlay.class, ArrayNode.class); - types.put(PropertiesOverlay.class, ObjectNode.class); + Map, List>> types = new HashMap<>(); + types.put(StringOverlay.class, Arrays.asList(TextNode.class)); + types.put(BooleanOverlay.class, Arrays.asList(BooleanNode.class)); + types.put(IntegerOverlay.class, Arrays.asList(IntNode.class, ShortNode.class, BigIntegerNode.class)); + types.put(NumberOverlay.class, Arrays.asList(NumericNode.class)); + types.put(PrimitiveOverlay.class, Arrays.asList(TextNode.class, NumericNode.class, BooleanNode.class)); + types.put(ObjectOverlay.class, Arrays.asList(JsonNode.class)); + types.put(MapOverlay.class, Arrays.asList(ObjectNode.class)); + types.put(ListOverlay.class, Arrays.asList(ArrayNode.class)); + types.put(PropertiesOverlay.class, Arrays.asList(ObjectNode.class)); allowedJsonTypes = types; } } diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/NumericUtils.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/NumericUtils.java index afd61877..59e6ecc4 100755 --- a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/NumericUtils.java +++ b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/NumericUtils.java @@ -12,10 +12,9 @@ import java.math.BigDecimal; import java.math.BigInteger; +import java.util.HashMap; import java.util.Map; -import com.google.common.collect.Maps; - public class NumericUtils { public static boolean isNumeric(Object obj) { return NumericType.of(obj) != null; @@ -162,7 +161,7 @@ private NumericType(Class cls) { private void register(Class cls, NumericType type) { if (NumericType.types == null) - NumericType.types = Maps.newHashMap(); + NumericType.types = new HashMap<>(); types.put(cls, type); } diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/ValidationResults.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/ValidationResults.java index 195b8776..2a26a1f0 100755 --- a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/ValidationResults.java +++ b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/ValidationResults.java @@ -16,10 +16,10 @@ import static com.reprezen.kaizen.oasparser.val.ValidationResults.Severity.NONE; import static com.reprezen.kaizen.oasparser.val.ValidationResults.Severity.WARNING; +import java.util.ArrayList; import java.util.Collection; import java.util.List; -import com.google.common.collect.Lists; import com.reprezen.jsonoverlay.Overlay; import com.reprezen.jsonoverlay.PositionInfo; @@ -82,7 +82,7 @@ public boolean ge(Severity other) { } }; - List items = Lists.newArrayList(); + List items = new ArrayList<>(); public void addInfo(String msg, Overlay context) { items.add(new ValidationItem(INFO, msg, context)); diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/ValidatorBase.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/ValidatorBase.java index 0e52ed60..50b114fd 100755 --- a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/ValidatorBase.java +++ b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val/ValidatorBase.java @@ -4,6 +4,7 @@ import java.net.MalformedURLException; import java.net.URL; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -15,7 +16,6 @@ import javax.mail.internet.AddressException; import javax.mail.internet.InternetAddress; -import com.google.common.collect.Sets; import com.reprezen.jsonoverlay.ListOverlay; import com.reprezen.jsonoverlay.MapOverlay; import com.reprezen.jsonoverlay.Overlay; @@ -237,7 +237,7 @@ private void checkListNotEmpty(Overlay> list, boolean nonEmpty) { private void checkListUnique(Overlay> list, boolean unique) { if (unique) { ListOverlay listOverlay = Overlay.getListOverlay(list); - Set seen = Sets.newHashSet(); + Set seen = new HashSet<>(); for (int i = 0; i < listOverlay.size(); i++) { X item = listOverlay.get(i); if (seen.contains(item)) { @@ -280,7 +280,7 @@ private void checkMapNotEmpty(Overlay> list, boolean nonEmpty private void checkMapUnique(Overlay> map, boolean unique) { if (unique) { MapOverlay mapOverlay = Overlay.getMapOverlay(map); - Set seen = Sets.newHashSet(); + Set seen = new HashSet<>(); for (String key : mapOverlay.keySet()) { X value = mapOverlay.get(key); if (seen.contains(value)) { diff --git a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/LinkValidator.java b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/LinkValidator.java index bf03a021..09246134 100755 --- a/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/LinkValidator.java +++ b/kaizen-openapi-parser/src/main/java/com/reprezen/kaizen/oasparser/val3/LinkValidator.java @@ -15,9 +15,9 @@ import static com.reprezen.kaizen.oasparser.val.Messages.m; import java.util.Collection; +import java.util.HashMap; import java.util.Map; -import com.google.common.collect.Maps; import com.reprezen.jsonoverlay.Overlay; import com.reprezen.kaizen.oasparser.model3.Link; import com.reprezen.kaizen.oasparser.model3.OpenApi3; @@ -128,7 +128,7 @@ private String getRelativePath(String operationRef, ValidationResults results) { } private Map getParamNameCounts(Collection parameters) { - Map counts = Maps.newHashMap(); + Map counts = new HashMap<>(); for (Parameter parameter : parameters) { String name = parameter.getName(); if (counts.containsKey(name)) {