Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ This library provides extended validation of fields and field arguments for [gra
# Status

This code is currently under construction. It is fairly complete in providing powerful validation
but as it has NOT be consumed by a production like project then its API usefulness has not been tested
but as it has NOT been consumed by a production like project then its API usefulness has not been tested
and battle tested.

But the project welcomes all feedback and input on code design and validation requirements.
Expand All @@ -21,13 +21,13 @@ But the project welcomes all feedback and input on code design and validation re
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-java-extended-validation</artifactId>
<version>0.0.3</version>
<version>0.0.4</version>
<type>pom</type>
</dependency>
```

```groovy
compile 'com.graphql-java:graphql-java-extended-validation:0.0.3'
compile 'com.graphql-java:graphql-java-extended-validation:0.0.4'
```

Its currently available from JCenter repo and Maven central is pending.
Expand Down Expand Up @@ -409,7 +409,7 @@ The String must match the specified regular expression, which follows the Java r

- Example : `updateDriver( licencePlate : String @Patttern(regex : "[A-Z][A-Z][A-Z]-[0-9][0-9][0-9]") : DriverDetails`

- Applies to : `String`
- Applies to : `String`, `Lists`

- SDL : `directive @Pattern(regexp : String! =".*", message : String = "graphql.validation.Pattern.message") on ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,23 @@
import graphql.Scalars;
import graphql.schema.GraphQLDirective;
import graphql.schema.GraphQLInputType;
import graphql.schema.GraphQLList;
import graphql.schema.GraphQLType;
import graphql.validation.constraints.AbstractDirectiveConstraint;
import graphql.validation.constraints.Documentation;
import graphql.validation.rules.ValidationEnvironment;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static graphql.schema.GraphQLTypeUtil.isList;
import static graphql.schema.GraphQLTypeUtil.isScalar;
import static java.util.Collections.emptyList;

public class PatternConstraint extends AbstractDirectiveConstraint {
Expand All @@ -31,9 +38,9 @@ public Documentation getDocumentation() {

.description("The String must match the specified regular expression, which follows the Java regular expression conventions.")

.example("updateDriver( licencePlate : String @Patttern(regex : \"[A-Z][A-Z][A-Z]-[0-9][0-9][0-9]\") : DriverDetails")
.example("updateDriver( licencePlate : String @Pattern(regexp : \"[A-Z][A-Z][A-Z]-[0-9][0-9][0-9]\") : DriverDetails")

.applicableTypeNames(Scalars.GraphQLString.getName())
.applicableTypeNames(Scalars.GraphQLString.getName(), "Lists")

.directiveSDL("directive @Pattern(regexp : String! =\".*\", message : String = \"%s\") " +
"on ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION",
Expand All @@ -44,32 +51,45 @@ public Documentation getDocumentation() {
@Override
public boolean appliesToType(GraphQLInputType inputType) {
return isOneOfTheseTypes(inputType,
Scalars.GraphQLString
);
Scalars.GraphQLString) || isList(inputType);
}

@Override
protected List<GraphQLError> runConstraint(ValidationEnvironment validationEnvironment) {
Object validatedValue = validationEnvironment.getValidatedValue();
GraphQLInputType argumentType = validationEnvironment.getValidatedType();

if (validatedValue == null) {
return emptyList();
}
String strValue = String.valueOf(validatedValue);

GraphQLDirective directive = validationEnvironment.getContextObject(GraphQLDirective.class);
List<Object> validatedValues;

if (isList(argumentType)) {
validatedValues = (ArrayList)validatedValue;
} else {
validatedValues = Arrays.asList(validatedValue);
}

for (Object value : validatedValues) {
String strValue = String.valueOf(value);

String patternArg = getStrArg(directive, "regexp");
Pattern pattern = cachedPattern(patternArg);
GraphQLDirective directive = validationEnvironment.getContextObject(GraphQLDirective.class);

Matcher matcher = pattern.matcher(strValue);
if (!matcher.matches()) {
return mkError(validationEnvironment, directive, mkMessageParams(validatedValue, validationEnvironment,
"regexp", patternArg
));
String patternArg = getStrArg(directive, "regexp");
Pattern pattern = cachedPattern(patternArg);

Matcher matcher = pattern.matcher(strValue);
if (!matcher.matches()) {
return mkError(validationEnvironment, directive,
mkMessageParams(validatedValue, validationEnvironment, "regexp", patternArg));
}
}
return emptyList();
}



private Pattern cachedPattern(String patternArg) {
return SEEN_PATTERNS.computeIfAbsent(patternArg, Pattern::compile);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ class PatternConstraintTest extends BaseConstraintTestSupport {
fieldDeclaration | argVal | expectedMessage
'field( arg : String @Pattern(regexp:"[A-Z]*") ) : ID' | "ABCd" | 'Pattern;path=/arg;val:ABCd;\t'
'field( arg : String @Pattern(regexp:"[A-Z]*") ) : ID' | "ABC" | ''
'field( arg : [String] @Pattern(regexp:"[A-Z]*") ) : ID' | ["ABC"] | ''
'field( arg : [String] @Pattern(regexp:"[A-Z]*") ) : ID' | ["ABC", "ABCd"] | 'Pattern;path=/arg;val:[ABC, ABCd];\t'

// nulls are valid
'field( arg : String @Pattern(regexp:"[A-Z]*") ) : ID' | null | ''
Expand Down