1818import graphql .schema .CoercingParseValueException ;
1919import graphql .schema .CoercingSerializeException ;
2020import graphql .schema .GraphQLScalarType ;
21+ import graphql .util .FpKit ;
2122
23+ import java .math .BigDecimal ;
24+ import java .math .BigInteger ;
25+ import java .util .ArrayList ;
2226import java .util .Collections ;
2327import java .util .LinkedHashMap ;
2428import java .util .List ;
2529import java .util .Map ;
2630import java .util .stream .Collectors ;
2731
32+ import static graphql .language .ObjectField .newObjectField ;
2833import static graphql .scalars .util .Kit .typeName ;
2934
3035/**
@@ -46,14 +51,16 @@ public Object parseValue(Object input) throws CoercingParseValueException {
4651
4752 @ Override
4853 public Object parseLiteral (Object input ) throws CoercingParseLiteralException {
54+ // on purpose - object scalars can be null
55+ //noinspection ConstantConditions
4956 return parseLiteral (input , Collections .emptyMap ());
5057 }
5158
5259 @ Override
5360 public Object parseLiteral (Object input , Map <String , Object > variables ) throws CoercingParseLiteralException {
5461 if (!(input instanceof Value )) {
5562 throw new CoercingParseLiteralException (
56- "Expected AST type 'StringValue ' but was '" + typeName (input ) + "'."
63+ "Expected AST type 'Value ' but was '" + typeName (input ) + "'."
5764 );
5865 }
5966 if (input instanceof NullValue ) {
@@ -95,6 +102,64 @@ public Object parseLiteral(Object input, Map<String, Object> variables) throws C
95102 }
96103 return Assert .assertShouldNeverHappen ("We have covered all Value types" );
97104 }
105+
106+ @ Override
107+ public Value <?> valueToLiteral (Object input ) {
108+ if (input == null ) {
109+ return NullValue .newNullValue ().build ();
110+ }
111+ if (input instanceof String ) {
112+ return new StringValue ((String ) input );
113+ }
114+ if (input instanceof Float ) {
115+ return new FloatValue (BigDecimal .valueOf ((Float ) input ));
116+ }
117+ if (input instanceof Double ) {
118+ return new FloatValue (BigDecimal .valueOf ((Double ) input ));
119+ }
120+ if (input instanceof BigDecimal ) {
121+ return new FloatValue ((BigDecimal ) input );
122+ }
123+ if (input instanceof BigInteger ) {
124+ return new IntValue ((BigInteger ) input );
125+ }
126+ if (input instanceof Number ) {
127+ long l = ((Number ) input ).longValue ();
128+ return new IntValue (BigInteger .valueOf (l ));
129+ }
130+ if (input instanceof Boolean ) {
131+ return new BooleanValue ((Boolean ) input );
132+ }
133+ if (FpKit .isIterable (input )) {
134+ return handleIterable (FpKit .toIterable (input ));
135+ }
136+ if (input instanceof Map ) {
137+ return handleMap ((Map <?, ?>) input );
138+ }
139+ throw new UnsupportedOperationException ("The ObjectScalar cant handle values of type : " + input .getClass ());
140+ }
141+
142+ private Value <?> handleMap (Map <?, ?> map ) {
143+ ObjectValue .Builder builder = ObjectValue .newObjectValue ();
144+ for (Map .Entry <?, ?> entry : map .entrySet ()) {
145+ String name = String .valueOf (entry .getKey ());
146+ Value <?> value = valueToLiteral (entry .getValue ());
147+
148+ builder .objectField (
149+ newObjectField ().name (name ).value (value ).build ()
150+ );
151+ }
152+ return builder .build ();
153+ }
154+
155+ @ SuppressWarnings ("rawtypes" )
156+ private Value <?> handleIterable (Iterable <?> input ) {
157+ List <Value > values = new ArrayList <>();
158+ for (Object val : input ) {
159+ values .add (valueToLiteral (val ));
160+ }
161+ return ArrayValue .newArrayValue ().values (values ).build ();
162+ }
98163 };
99164
100165 public static GraphQLScalarType INSTANCE = GraphQLScalarType .newScalar ()
0 commit comments