From 8bfa70900003495509a50a633e40ebedf4445c9c Mon Sep 17 00:00:00 2001 From: kuptservol Date: Thu, 23 Mar 2017 12:36:49 +0300 Subject: [PATCH 1/2] * add possibility to configure custom scalar types externally --- .../graphql/engine/GraphQLSchemaConfig.java | 21 +++++++++++++ .../engine/dfs/GraphQLMappingContext.java | 31 ++++++------------- .../engine/dfs/GraphQLTypeResolver.java | 14 +++++++++ .../type/resolver/DateTypeResolver.java | 31 +++++++++++++++++++ .../type/resolver/LocalDateTimeResolver.java | 30 ++++++++++++++++++ .../todoschema/objecttype/UserObjectType.java | 11 +++++-- 6 files changed, 114 insertions(+), 24 deletions(-) create mode 100644 src/main/java/com/oembedler/moon/graphql/engine/dfs/GraphQLTypeResolver.java create mode 100644 src/main/java/com/oembedler/moon/graphql/engine/type/resolver/DateTypeResolver.java create mode 100644 src/main/java/com/oembedler/moon/graphql/engine/type/resolver/LocalDateTimeResolver.java diff --git a/src/main/java/com/oembedler/moon/graphql/engine/GraphQLSchemaConfig.java b/src/main/java/com/oembedler/moon/graphql/engine/GraphQLSchemaConfig.java index ca067bf..0cd2611 100644 --- a/src/main/java/com/oembedler/moon/graphql/engine/GraphQLSchemaConfig.java +++ b/src/main/java/com/oembedler/moon/graphql/engine/GraphQLSchemaConfig.java @@ -19,8 +19,14 @@ package com.oembedler.moon.graphql.engine; +import com.oembedler.moon.graphql.engine.dfs.GraphQLTypeResolver; +import com.oembedler.moon.graphql.engine.type.resolver.DateTypeResolver; +import com.oembedler.moon.graphql.engine.type.resolver.LocalDateTimeResolver; import org.springframework.util.Assert; +import java.util.ArrayList; +import java.util.List; + /** * @author oEmbedler Inc. */ @@ -37,6 +43,12 @@ public class GraphQLSchemaConfig { private String schemaMutationObjectName = "Mutation"; private boolean dateAsTimestamp = true; private String dateFormat = "yyyy-MM-dd'T'HH:mm'Z'"; + private List graphQLTypeResolvers = new ArrayList<>(); + + { + graphQLTypeResolvers.add(new DateTypeResolver()); + graphQLTypeResolvers.add(new LocalDateTimeResolver()); + } // --- @@ -117,6 +129,15 @@ public void setDateFormat(String dateFormat) { this.dateFormat = dateFormat; } + public void addGraphQLTypeResolver(GraphQLTypeResolver graphQLTypeResolver) { + Assert.notNull(graphQLTypeResolver, "GraphQl resolver cannot be null!"); + this.graphQLTypeResolvers.add(graphQLTypeResolver); + } + + public List getGraphQLTypeResolvers() { + return graphQLTypeResolvers; + } + public boolean isDateAsTimestamp() { return dateAsTimestamp; } diff --git a/src/main/java/com/oembedler/moon/graphql/engine/dfs/GraphQLMappingContext.java b/src/main/java/com/oembedler/moon/graphql/engine/dfs/GraphQLMappingContext.java index 393df1a..4291738 100644 --- a/src/main/java/com/oembedler/moon/graphql/engine/dfs/GraphQLMappingContext.java +++ b/src/main/java/com/oembedler/moon/graphql/engine/dfs/GraphQLMappingContext.java @@ -20,14 +20,10 @@ package com.oembedler.moon.graphql.engine.dfs; import com.oembedler.moon.graphql.engine.GraphQLSchemaConfig; -import com.oembedler.moon.graphql.engine.type.GraphQLDateType; -import com.oembedler.moon.graphql.engine.type.GraphQLLocalDateTimeType; import graphql.schema.GraphQLScalarType; import org.springframework.util.Assert; import java.lang.reflect.Type; -import java.time.LocalDateTime; -import java.util.Date; /** * @author oEmbedler Inc. @@ -43,26 +39,17 @@ public GraphQLMappingContext(GraphQLSchemaConfig graphQLSchemaConfig) { public GraphQLScalarType getScalarGraphQLType(final Type cls) { GraphQLScalarType graphQLScalarType = MappingConstants.getScalarGraphQLType(cls); - if (Date.class.isAssignableFrom((Class) cls)) { - if (graphQLSchemaConfig.isDateAsTimestamp()) - graphQLScalarType = MappingConstants.graphQLTimestamp; - else - graphQLScalarType = getGraphQLDateType(); - } else if (LocalDateTime.class.isAssignableFrom((Class) cls)) { - if (graphQLSchemaConfig.isDateAsTimestamp()) - graphQLScalarType = MappingConstants.graphQLTimestamp; - else - graphQLScalarType = getGraphQLDateType(); - } - return graphQLScalarType; - } - private GraphQLScalarType getGraphQLDateType() { - return new GraphQLDateType("Date", "Date formatted according to defined format string", graphQLSchemaConfig.getDateFormat()); - } + if (graphQLScalarType == null) { + graphQLScalarType = graphQLSchemaConfig.getGraphQLTypeResolvers() + .stream() + .filter(resolver -> resolver.getType().isAssignableFrom((Class) cls)) + .findFirst() + .map(resolver -> resolver.resolve(graphQLSchemaConfig)) + .orElse(null); + } - private GraphQLScalarType getGraphQLLocalDateTimeType() { - return new GraphQLLocalDateTimeType("LocalDateTime", "LocalDateTime formatted according to defined format string", graphQLSchemaConfig.getDateFormat()); + return graphQLScalarType; } // --- diff --git a/src/main/java/com/oembedler/moon/graphql/engine/dfs/GraphQLTypeResolver.java b/src/main/java/com/oembedler/moon/graphql/engine/dfs/GraphQLTypeResolver.java new file mode 100644 index 0000000..2d94b06 --- /dev/null +++ b/src/main/java/com/oembedler/moon/graphql/engine/dfs/GraphQLTypeResolver.java @@ -0,0 +1,14 @@ +package com.oembedler.moon.graphql.engine.dfs; + +import com.oembedler.moon.graphql.engine.GraphQLSchemaConfig; +import graphql.schema.GraphQLScalarType; + +/** + * @author Sergey Kuptsov + * @since 23/03/2017 + */ +public interface GraphQLTypeResolver { + Class getType(); + + GraphQLScalarType resolve(GraphQLSchemaConfig graphQLSchemaConfig); +} diff --git a/src/main/java/com/oembedler/moon/graphql/engine/type/resolver/DateTypeResolver.java b/src/main/java/com/oembedler/moon/graphql/engine/type/resolver/DateTypeResolver.java new file mode 100644 index 0000000..0607d52 --- /dev/null +++ b/src/main/java/com/oembedler/moon/graphql/engine/type/resolver/DateTypeResolver.java @@ -0,0 +1,31 @@ +package com.oembedler.moon.graphql.engine.type.resolver; + +import com.oembedler.moon.graphql.engine.GraphQLSchemaConfig; +import com.oembedler.moon.graphql.engine.dfs.GraphQLTypeResolver; +import com.oembedler.moon.graphql.engine.dfs.MappingConstants; +import com.oembedler.moon.graphql.engine.type.GraphQLDateType; +import graphql.schema.GraphQLScalarType; + +import java.util.Date; + +/** + * @author Sergey Kuptsov + * @since 23/03/2017 + */ +public class DateTypeResolver implements GraphQLTypeResolver { + + @Override + public Class getType() { + return Date.class; + } + + @Override + public GraphQLScalarType resolve(GraphQLSchemaConfig graphQLSchemaConfig) { + if (graphQLSchemaConfig.isDateAsTimestamp()) + return MappingConstants.graphQLTimestamp; + else + return new GraphQLDateType("Date", "Date formatted according to defined format string", + graphQLSchemaConfig.getDateFormat()); + + } +} diff --git a/src/main/java/com/oembedler/moon/graphql/engine/type/resolver/LocalDateTimeResolver.java b/src/main/java/com/oembedler/moon/graphql/engine/type/resolver/LocalDateTimeResolver.java new file mode 100644 index 0000000..3925804 --- /dev/null +++ b/src/main/java/com/oembedler/moon/graphql/engine/type/resolver/LocalDateTimeResolver.java @@ -0,0 +1,30 @@ +package com.oembedler.moon.graphql.engine.type.resolver; + +import com.oembedler.moon.graphql.engine.GraphQLSchemaConfig; +import com.oembedler.moon.graphql.engine.dfs.GraphQLTypeResolver; +import com.oembedler.moon.graphql.engine.dfs.MappingConstants; +import com.oembedler.moon.graphql.engine.type.GraphQLLocalDateTimeType; +import graphql.schema.GraphQLScalarType; + +import java.time.LocalDateTime; + +/** + * @author Sergey Kuptsov + * @since 23/03/2017 + */ +public class LocalDateTimeResolver implements GraphQLTypeResolver { + @Override + public Class getType() { + return LocalDateTime.class; + } + + @Override + public GraphQLScalarType resolve(GraphQLSchemaConfig graphQLSchemaConfig) { + if (graphQLSchemaConfig.isDateAsTimestamp()) + return MappingConstants.graphQLTimestamp; + else { + return new GraphQLLocalDateTimeType("LocalDateTime", "LocalDateTime formatted according to defined format string", + graphQLSchemaConfig.getDateFormat()); + } + } +} diff --git a/src/test/java/com/oembedler/moon/graphql/test/todoschema/objecttype/UserObjectType.java b/src/test/java/com/oembedler/moon/graphql/test/todoschema/objecttype/UserObjectType.java index fbb220b..b81613a 100644 --- a/src/test/java/com/oembedler/moon/graphql/test/todoschema/objecttype/UserObjectType.java +++ b/src/test/java/com/oembedler/moon/graphql/test/todoschema/objecttype/UserObjectType.java @@ -20,11 +20,9 @@ package com.oembedler.moon.graphql.test.todoschema.objecttype; import com.google.common.collect.Lists; -import com.google.common.collect.Sets; import com.oembedler.moon.graphql.engine.stereotype.*; import com.oembedler.moon.graphql.test.GenericTodoSchemaParserTest; -import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Set; @@ -37,6 +35,7 @@ public class UserObjectType extends BaseObjectType { private String name; private ROLE role; + private Date created; @GraphQLIgnore private UserObjectType manager; @@ -70,6 +69,14 @@ public void setRole(ROLE role) { this.role = role; } + public Date getCreated() { + return created; + } + + public void setCreated(Date created) { + this.created = created; + } + @GraphQLField("manager") public UserObjectType getManager(UserObjectType employee, @GraphQLIn(value = "ids", defaultSpel = "T(java.util.Collections).EMPTY_SET") Set ids) { From d088d43fd4666898634b81621fae2fe188c9d9e8 Mon Sep 17 00:00:00 2001 From: kuptservol Date: Thu, 23 Mar 2017 13:11:08 +0300 Subject: [PATCH 2/2] * do not try to expose private final constants --- .../graphql/engine/dfs/GraphQLSchemaDfsTraversal.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/oembedler/moon/graphql/engine/dfs/GraphQLSchemaDfsTraversal.java b/src/main/java/com/oembedler/moon/graphql/engine/dfs/GraphQLSchemaDfsTraversal.java index ebda3f7..7637604 100644 --- a/src/main/java/com/oembedler/moon/graphql/engine/dfs/GraphQLSchemaDfsTraversal.java +++ b/src/main/java/com/oembedler/moon/graphql/engine/dfs/GraphQLSchemaDfsTraversal.java @@ -288,7 +288,7 @@ public GraphQLFieldDefinition getFieldDefinition(DfsContext dfsContext, Class .deprecate(resolvableTypeAccessor.getGraphQLDeprecationReason()) .description(resolvableTypeAccessor.getDescription()); - boolean isConstant = Modifier.isFinal(field.getModifiers()) && Modifier.isStatic(field.getModifiers()); + boolean isConstant = isPublicConstant(field); if (isConstant) { graphQLFieldDefinitionBuilder.staticValue(org.springframework.util.ReflectionUtils.getField(field, null)); } @@ -299,6 +299,13 @@ public GraphQLFieldDefinition getFieldDefinition(DfsContext dfsContext, Class return graphQLFieldDefinition; } + private boolean isPublicConstant(Field field) { + int modifiers = field.getModifiers(); + return Modifier.isFinal(modifiers) + && Modifier.isStatic(modifiers) + && !Modifier.isPrivate(modifiers); + } + public void addToFieldDefinitionResolverMap(DfsContext dfsContext, GraphQLFieldDefinition graphQLFieldDefinition, String complexitySpelExpression) { fieldDefinitionResolverMap.put(graphQLFieldDefinition, new GraphQLFieldDefinitionWrapper(graphQLFieldDefinition, complexitySpelExpression));