From 7ad838df9952fddd3bb3fadec3807833f242c51d Mon Sep 17 00:00:00 2001 From: John power Date: Tue, 29 Sep 2020 08:46:15 -0400 Subject: [PATCH 1/8] fix schema wiring --- .../FieldValidatorDataFetcher.java | 79 +++++++++++++++++++ .../schemawiring/ValidationSchemaWiring.java | 44 ++++------- 2 files changed, 94 insertions(+), 29 deletions(-) create mode 100644 src/main/java/graphql/validation/schemawiring/FieldValidatorDataFetcher.java diff --git a/src/main/java/graphql/validation/schemawiring/FieldValidatorDataFetcher.java b/src/main/java/graphql/validation/schemawiring/FieldValidatorDataFetcher.java new file mode 100644 index 0000000..a02836a --- /dev/null +++ b/src/main/java/graphql/validation/schemawiring/FieldValidatorDataFetcher.java @@ -0,0 +1,79 @@ +package graphql.validation.schemawiring; + +import graphql.GraphQLError; +import graphql.schema.*; +import graphql.validation.interpolation.MessageInterpolator; +import graphql.validation.rules.OnValidationErrorStrategy; +import graphql.validation.rules.TargetedValidationRules; +import graphql.validation.rules.ValidationRule; +import graphql.validation.rules.ValidationRules; +import graphql.validation.util.Util; + +import java.util.List; +import java.util.Locale; + +public class FieldValidatorDataFetcher implements DataFetcher { + private final OnValidationErrorStrategy errorStrategy; + private final MessageInterpolator messageInterpolator; + private final DataFetcher defaultDataFetcher; + private final Locale defaultLocale; + private final ValidationRules validationRules; + private TargetedValidationRules applicableRules; + + public FieldValidatorDataFetcher(OnValidationErrorStrategy errorStrategy, + MessageInterpolator messageInterpolator, + DataFetcher defaultDataFetcher, + Locale defaultLocale, + ValidationRules validationRules) { + this.errorStrategy = errorStrategy; + this.messageInterpolator = messageInterpolator; + this.defaultDataFetcher = defaultDataFetcher; + this.defaultLocale = defaultLocale; + this.validationRules = validationRules; + this.applicableRules = null; + } + + @Override + public Object get(DataFetchingEnvironment environment) throws Exception { + if (!wereApplicableRulesFetched()) { + fetchApplicableRules(environment); + } + + // When no validation is performed, this data fetcher is a pass-through + if (applicableRules.isEmpty()) { + return defaultDataFetcher.get(environment); + } + + List errors = applicableRules.runValidationRules(environment, messageInterpolator, defaultLocale); + if (!errors.isEmpty()) { + if (!errorStrategy.shouldContinue(errors, environment)) { + return errorStrategy.onErrorValue(errors, environment); + } + } + + Object returnValue = defaultDataFetcher.get(environment); + if (errors.isEmpty()) { + return returnValue; + } + return Util.mkDFRFromFetchedResult(errors, returnValue); + } + + private void fetchApplicableRules(DataFetchingEnvironment environment) { + final GraphQLFieldDefinition field = environment.getFieldDefinition(); + final GraphQLFieldsContainer container = asContainer(environment); + + applicableRules = validationRules.buildRulesFor(field, container); + } + + private GraphQLFieldsContainer asContainer(DataFetchingEnvironment environment) { + final GraphQLType parent = environment.getParentType(); + if (parent == null) { + return null; + } + return (GraphQLFieldsContainer) environment.getParentType(); + } + + private boolean wereApplicableRulesFetched() { + return applicableRules != null; + } +} diff --git a/src/main/java/graphql/validation/schemawiring/ValidationSchemaWiring.java b/src/main/java/graphql/validation/schemawiring/ValidationSchemaWiring.java index 26d9c97..36cf6ba 100644 --- a/src/main/java/graphql/validation/schemawiring/ValidationSchemaWiring.java +++ b/src/main/java/graphql/validation/schemawiring/ValidationSchemaWiring.java @@ -1,6 +1,5 @@ package graphql.validation.schemawiring; -import graphql.GraphQLError; import graphql.PublicApi; import graphql.schema.DataFetcher; import graphql.schema.GraphQLFieldDefinition; @@ -11,17 +10,15 @@ import graphql.validation.rules.OnValidationErrorStrategy; import graphql.validation.rules.TargetedValidationRules; import graphql.validation.rules.ValidationRules; -import graphql.validation.util.Util; -import java.util.List; import java.util.Locale; /** - * A {@link graphql.schema.idl.SchemaDirectiveWiring} that can be used to inject validation rules into the data fetchers + * A {@link SchemaDirectiveWiring} that can be used to inject validation rules into the data fetchers * when the graphql schema is being built. It will use the validation rules and ask each one of they apply to the field and or its * arguments. *

- * If there are rules that apply then it will it will change the {@link graphql.schema.DataFetcher} of that field so that rules get run + * If there are rules that apply then it will it will change the {@link DataFetcher} of that field so that rules get run * BEFORE the original field fetch is run. */ @PublicApi @@ -38,40 +35,29 @@ public GraphQLFieldDefinition onField(SchemaDirectiveWiringEnvironment currentDF = env.getCodeRegistry().getDataFetcher(fieldsContainer, fieldDefinition); + final DataFetcher newDF = buildValidatingDataFetcher(errorStrategy, messageInterpolator, currentDF, locale); env.getCodeRegistry().dataFetcher(fieldsContainer, fieldDefinition, newDF); return fieldDefinition; } - private DataFetcher buildValidatingDataFetcher(TargetedValidationRules rules, OnValidationErrorStrategy errorStrategy, MessageInterpolator messageInterpolator, DataFetcher currentDF, final Locale defaultLocale) { - // ok we have some rules that need to be applied to this field and its arguments - return environment -> { - List errors = rules.runValidationRules(environment, messageInterpolator, defaultLocale); - if (!errors.isEmpty()) { - // should we continue? - if (!errorStrategy.shouldContinue(errors, environment)) { - return errorStrategy.onErrorValue(errors, environment); - } - } - // we have no validation errors or they said continue so call the underlying data fetcher - Object returnValue = currentDF.get(environment); - if (errors.isEmpty()) { - return returnValue; - } - return Util.mkDFRFromFetchedResult(errors, returnValue); - }; + private DataFetcher buildValidatingDataFetcher(OnValidationErrorStrategy errorStrategy, + MessageInterpolator messageInterpolator, + DataFetcher currentDF, + final Locale defaultLocale) { + return new FieldValidatorDataFetcher( + errorStrategy, + messageInterpolator, + currentDF, + defaultLocale, + ruleCandidates + ); } } From 1dda6c2afb8618cd5846bf26609dda35e094b0ca Mon Sep 17 00:00:00 2001 From: sunny pelletier Date: Tue, 1 Jun 2021 10:57:41 -0400 Subject: [PATCH 2/8] bump version of hibernate validator --- build.gradle | 2 +- .../ResourceBundleMessageInterpolator.java | 21 ++++++------------- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/build.gradle b/build.gradle index 87e2a9c..6291c08 100644 --- a/build.gradle +++ b/build.gradle @@ -42,7 +42,7 @@ dependencies { compile "com.graphql-java:graphql-java:16.2" compile 'org.slf4j:slf4j-api:1.7.30' compile "jakarta.validation:jakarta.validation-api:2.0.2" - compile "org.hibernate.validator:hibernate-validator:6.1.7.Final" + compile "org.hibernate.validator:hibernate-validator:6.2.0.Final" compile "jakarta.el:jakarta.el-api:3.0.3" compile "org.glassfish:jakarta.el:3.0.3" diff --git a/src/main/java/graphql/validation/interpolation/ResourceBundleMessageInterpolator.java b/src/main/java/graphql/validation/interpolation/ResourceBundleMessageInterpolator.java index 76d83d3..785ec00 100644 --- a/src/main/java/graphql/validation/interpolation/ResourceBundleMessageInterpolator.java +++ b/src/main/java/graphql/validation/interpolation/ResourceBundleMessageInterpolator.java @@ -7,33 +7,24 @@ import graphql.schema.GraphQLDirective; import graphql.validation.el.StandardELVariables; import graphql.validation.rules.ValidationEnvironment; -import javax.validation.Path; import org.hibernate.validator.internal.engine.MessageInterpolatorContext; import org.hibernate.validator.internal.metadata.core.ConstraintHelper; import org.hibernate.validator.internal.metadata.descriptor.ConstraintDescriptorImpl; import org.hibernate.validator.internal.metadata.descriptor.ConstraintDescriptorImpl.ConstraintType; import org.hibernate.validator.internal.metadata.location.ConstraintLocation.ConstraintLocationKind; import org.hibernate.validator.internal.util.annotation.ConstraintAnnotationDescriptor; +import org.hibernate.validator.messageinterpolation.ExpressionLanguageFeatureLevel; import org.hibernate.validator.resourceloading.PlatformResourceBundleLocator; import org.hibernate.validator.spi.resourceloading.ResourceBundleLocator; import javax.validation.Constraint; +import javax.validation.Path; import javax.validation.Payload; import java.lang.annotation.Retention; import java.lang.annotation.Target; -import java.util.LinkedHashMap; -import java.util.Locale; -import java.util.Map; -import java.util.MissingResourceException; -import java.util.Optional; -import java.util.ResourceBundle; - -import static java.lang.annotation.ElementType.ANNOTATION_TYPE; -import static java.lang.annotation.ElementType.CONSTRUCTOR; -import static java.lang.annotation.ElementType.FIELD; -import static java.lang.annotation.ElementType.METHOD; -import static java.lang.annotation.ElementType.PARAMETER; -import static java.lang.annotation.ElementType.TYPE_USE; +import java.util.*; + +import static java.lang.annotation.ElementType.*; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** @@ -161,7 +152,7 @@ private MessageInterpolatorContext buildHibernateContext(Map mes return new MessageInterpolatorContext( constraintDescriptor, validatedValue, rootBeanType, - propertyPath, messageParams, expressionVariables); + propertyPath, messageParams, expressionVariables, ExpressionLanguageFeatureLevel.DEFAULT, true); } private org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator hibernateInterpolator() { From 3757c23e138f4c181fc019bd224877331c6b061c Mon Sep 17 00:00:00 2001 From: sunny pelletier Date: Tue, 1 Jun 2021 10:59:45 -0400 Subject: [PATCH 3/8] fix imports --- .../interpolation/ResourceBundleMessageInterpolator.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/graphql/validation/interpolation/ResourceBundleMessageInterpolator.java b/src/main/java/graphql/validation/interpolation/ResourceBundleMessageInterpolator.java index 785ec00..80ee372 100644 --- a/src/main/java/graphql/validation/interpolation/ResourceBundleMessageInterpolator.java +++ b/src/main/java/graphql/validation/interpolation/ResourceBundleMessageInterpolator.java @@ -22,7 +22,12 @@ import javax.validation.Payload; import java.lang.annotation.Retention; import java.lang.annotation.Target; -import java.util.*; +import java.util.LinkedHashMap; +import java.util.Locale; +import java.util.Map; +import java.util.MissingResourceException; +import java.util.Optional; +import java.util.ResourceBundle; import static java.lang.annotation.ElementType.*; import static java.lang.annotation.RetentionPolicy.RUNTIME; From 01edca814c76681c7100e42671ce9eb1997d4592 Mon Sep 17 00:00:00 2001 From: sunny pelletier Date: Tue, 1 Jun 2021 11:00:42 -0400 Subject: [PATCH 4/8] refix imports --- .../interpolation/ResourceBundleMessageInterpolator.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/graphql/validation/interpolation/ResourceBundleMessageInterpolator.java b/src/main/java/graphql/validation/interpolation/ResourceBundleMessageInterpolator.java index 80ee372..33ce026 100644 --- a/src/main/java/graphql/validation/interpolation/ResourceBundleMessageInterpolator.java +++ b/src/main/java/graphql/validation/interpolation/ResourceBundleMessageInterpolator.java @@ -29,7 +29,12 @@ import java.util.Optional; import java.util.ResourceBundle; -import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.ElementType.ANNOTATION_TYPE; +import static java.lang.annotation.ElementType.CONSTRUCTOR; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.ElementType.TYPE_USE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** From 5b76fe680f491a52dab7277b9c1b25e5c9b4acff Mon Sep 17 00:00:00 2001 From: Sunny Pelletier Date: Tue, 6 Jul 2021 14:09:11 -0400 Subject: [PATCH 5/8] update dependency versions --- build.gradle | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index 6291c08..e90e294 100644 --- a/build.gradle +++ b/build.gradle @@ -41,12 +41,12 @@ repositories { dependencies { compile "com.graphql-java:graphql-java:16.2" compile 'org.slf4j:slf4j-api:1.7.30' - compile "jakarta.validation:jakarta.validation-api:2.0.2" + compile "jakarta.validation:jakarta.validation-api:3.0.0" compile "org.hibernate.validator:hibernate-validator:6.2.0.Final" - compile "jakarta.el:jakarta.el-api:3.0.3" - compile "org.glassfish:jakarta.el:3.0.3" + compile "jakarta.el:jakarta.el-api:4.0.0" + compile "org.glassfish:jakarta.el:4.0.0" - testCompile 'org.slf4j:slf4j-simple:1.7.30' + testCompile 'org.slf4j:slf4j-simple:1.7.31' testCompile 'org.spockframework:spock-core:1.3-groovy-2.5' testCompile 'org.codehaus.groovy:groovy-all:2.5.14' } From ae252a0eda9485e4eed17b8ce597b28a7c2ed695 Mon Sep 17 00:00:00 2001 From: Sunny Pelletier Date: Tue, 6 Jul 2021 14:15:50 -0400 Subject: [PATCH 6/8] upgrade jakarta context --- build.gradle | 2 +- .../java/graphql/validation/el/BetterMapELResolver.java | 4 ++-- src/main/java/graphql/validation/el/ELSupport.java | 6 +----- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/build.gradle b/build.gradle index e90e294..2f1e80f 100644 --- a/build.gradle +++ b/build.gradle @@ -41,7 +41,7 @@ repositories { dependencies { compile "com.graphql-java:graphql-java:16.2" compile 'org.slf4j:slf4j-api:1.7.30' - compile "jakarta.validation:jakarta.validation-api:3.0.0" + compile "jakarta.validation:jakarta.validation-api:2.0.2" compile "org.hibernate.validator:hibernate-validator:6.2.0.Final" compile "jakarta.el:jakarta.el-api:4.0.0" compile "org.glassfish:jakarta.el:4.0.0" diff --git a/src/main/java/graphql/validation/el/BetterMapELResolver.java b/src/main/java/graphql/validation/el/BetterMapELResolver.java index eb10b2e..59d6b88 100644 --- a/src/main/java/graphql/validation/el/BetterMapELResolver.java +++ b/src/main/java/graphql/validation/el/BetterMapELResolver.java @@ -1,9 +1,9 @@ package graphql.validation.el; import graphql.Internal; +import jakarta.el.ELContext; +import jakarta.el.MapELResolver; -import javax.el.ELContext; -import javax.el.MapELResolver; import java.util.Arrays; import java.util.List; import java.util.Map; diff --git a/src/main/java/graphql/validation/el/ELSupport.java b/src/main/java/graphql/validation/el/ELSupport.java index c11d5cf..cb5fde9 100644 --- a/src/main/java/graphql/validation/el/ELSupport.java +++ b/src/main/java/graphql/validation/el/ELSupport.java @@ -1,13 +1,9 @@ package graphql.validation.el; import graphql.Internal; +import jakarta.el.*; import org.hibernate.validator.internal.engine.messageinterpolation.FormatterWrapper; -import javax.el.ELContext; -import javax.el.ELManager; -import javax.el.ExpressionFactory; -import javax.el.StandardELContext; -import javax.el.ValueExpression; import java.lang.reflect.Method; import java.util.Locale; import java.util.Map; From 2e912e84c7739e9e774b88ad46e38465858e8a8c Mon Sep 17 00:00:00 2001 From: Sunny Pelletier Date: Tue, 6 Jul 2021 14:25:08 -0400 Subject: [PATCH 7/8] remove useless dupplication of APIs --- build.gradle | 3 --- .../ResourceBundleMessageInterpolator.java | 16 +++------------- 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/build.gradle b/build.gradle index 2f1e80f..8cd0cca 100644 --- a/build.gradle +++ b/build.gradle @@ -40,10 +40,7 @@ repositories { dependencies { compile "com.graphql-java:graphql-java:16.2" - compile 'org.slf4j:slf4j-api:1.7.30' - compile "jakarta.validation:jakarta.validation-api:2.0.2" compile "org.hibernate.validator:hibernate-validator:6.2.0.Final" - compile "jakarta.el:jakarta.el-api:4.0.0" compile "org.glassfish:jakarta.el:4.0.0" testCompile 'org.slf4j:slf4j-simple:1.7.31' diff --git a/src/main/java/graphql/validation/interpolation/ResourceBundleMessageInterpolator.java b/src/main/java/graphql/validation/interpolation/ResourceBundleMessageInterpolator.java index 33ce026..785ec00 100644 --- a/src/main/java/graphql/validation/interpolation/ResourceBundleMessageInterpolator.java +++ b/src/main/java/graphql/validation/interpolation/ResourceBundleMessageInterpolator.java @@ -22,19 +22,9 @@ import javax.validation.Payload; import java.lang.annotation.Retention; import java.lang.annotation.Target; -import java.util.LinkedHashMap; -import java.util.Locale; -import java.util.Map; -import java.util.MissingResourceException; -import java.util.Optional; -import java.util.ResourceBundle; - -import static java.lang.annotation.ElementType.ANNOTATION_TYPE; -import static java.lang.annotation.ElementType.CONSTRUCTOR; -import static java.lang.annotation.ElementType.FIELD; -import static java.lang.annotation.ElementType.METHOD; -import static java.lang.annotation.ElementType.PARAMETER; -import static java.lang.annotation.ElementType.TYPE_USE; +import java.util.*; + +import static java.lang.annotation.ElementType.*; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** From f1130f29afc607c85814c13ccce8cae524f62eb6 Mon Sep 17 00:00:00 2001 From: Sunny Pelletier Date: Tue, 6 Jul 2021 14:29:53 -0400 Subject: [PATCH 8/8] change editor config --- .../java/graphql/validation/el/ELSupport.java | 9 ++++--- .../ResourceBundleMessageInterpolator.java | 26 ++++++++++++------- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/main/java/graphql/validation/el/ELSupport.java b/src/main/java/graphql/validation/el/ELSupport.java index cb5fde9..1571bae 100644 --- a/src/main/java/graphql/validation/el/ELSupport.java +++ b/src/main/java/graphql/validation/el/ELSupport.java @@ -1,12 +1,15 @@ package graphql.validation.el; import graphql.Internal; -import jakarta.el.*; -import org.hibernate.validator.internal.engine.messageinterpolation.FormatterWrapper; - +import jakarta.el.ELContext; +import jakarta.el.ELManager; +import jakarta.el.ExpressionFactory; +import jakarta.el.StandardELContext; +import jakarta.el.ValueExpression; import java.lang.reflect.Method; import java.util.Locale; import java.util.Map; +import org.hibernate.validator.internal.engine.messageinterpolation.FormatterWrapper; @Internal @SuppressWarnings("unused") diff --git a/src/main/java/graphql/validation/interpolation/ResourceBundleMessageInterpolator.java b/src/main/java/graphql/validation/interpolation/ResourceBundleMessageInterpolator.java index 785ec00..8a1ac8a 100644 --- a/src/main/java/graphql/validation/interpolation/ResourceBundleMessageInterpolator.java +++ b/src/main/java/graphql/validation/interpolation/ResourceBundleMessageInterpolator.java @@ -7,6 +7,17 @@ import graphql.schema.GraphQLDirective; import graphql.validation.el.StandardELVariables; import graphql.validation.rules.ValidationEnvironment; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; +import java.util.LinkedHashMap; +import java.util.Locale; +import java.util.Map; +import java.util.MissingResourceException; +import java.util.Optional; +import java.util.ResourceBundle; +import javax.validation.Constraint; +import javax.validation.Path; +import javax.validation.Payload; import org.hibernate.validator.internal.engine.MessageInterpolatorContext; import org.hibernate.validator.internal.metadata.core.ConstraintHelper; import org.hibernate.validator.internal.metadata.descriptor.ConstraintDescriptorImpl; @@ -16,15 +27,12 @@ import org.hibernate.validator.messageinterpolation.ExpressionLanguageFeatureLevel; import org.hibernate.validator.resourceloading.PlatformResourceBundleLocator; import org.hibernate.validator.spi.resourceloading.ResourceBundleLocator; - -import javax.validation.Constraint; -import javax.validation.Path; -import javax.validation.Payload; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; -import java.util.*; - -import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.ElementType.ANNOTATION_TYPE; +import static java.lang.annotation.ElementType.CONSTRUCTOR; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.ElementType.TYPE_USE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /**