4
4
import com .google .gson .JsonNull ;
5
5
6
6
import java .util .Map ;
7
+ import java .util .concurrent .atomic .AtomicInteger ;
7
8
8
9
/**
9
10
* A transformer is used to transform data from one layout to another
10
11
*/
11
12
public abstract class JsonTransformer <JE , JA extends Iterable <JE >, JO extends JE > implements Transformer {
12
13
13
14
static final String OBJ_DESTRUCT_KEY = "*" ;
14
- static final String FUNCTION_PREFIX = "$$ " ;
15
+ static final String NULL_VALUE = "#null " ;
15
16
16
17
private final JsonAdapter <JE , JA , JO > adapter ;
17
18
protected final JE definition ;
18
19
19
20
private final JsonTransformerFunction <JE > JSON_TRANSFORMER ;
20
- private final TransformerFunctions <JE , JA , JO > transformerFunctions ;
21
+ private final TransformerFunctionsAdapter <JE , JA , JO > transformerFunctions ;
21
22
22
23
public JsonTransformer (
23
- final TransformerFunctions <JE , JA , JO > transformerFunctions ,
24
24
final JsonAdapter <JE , JA , JO > adapter ,
25
- final JE definition ) {
26
- this .transformerFunctions = transformerFunctions ;
25
+ final JE definition ,
26
+ final TransformerFunctionsAdapter <JE , JA , JO > functionsAdapter ) {
27
+ this .transformerFunctions = functionsAdapter ;
27
28
this .adapter = adapter ;
28
29
this .definition = definition ;
29
30
this .JSON_TRANSFORMER = this ::fromJsonElement ;
@@ -34,18 +35,18 @@ public Object transform(Object payload, Map<String, Object> additionalContext, b
34
35
return JsonNull .INSTANCE ;
35
36
}
36
37
var resolver = adapter .createPayloadResolver (payload , additionalContext , false );
37
- return fromJsonElement (definition , resolver , allowReturningStreams );
38
+ return fromJsonElement ("$" , definition , resolver , allowReturningStreams );
38
39
}
39
40
40
- protected Object fromJsonPrimitive (JE definition , co .nlighten .jsontransform .ParameterResolver resolver , boolean allowReturningStreams ) {
41
+ protected Object fromJsonPrimitive (String path , JE definition , co .nlighten .jsontransform .ParameterResolver resolver , boolean allowReturningStreams ) {
41
42
if (!adapter .isJsonString (definition ))
42
43
return definition ;
43
44
try {
44
45
var val = adapter .getAsString (definition );
45
46
// test for inline function (e.g. $$function:...)
46
- var match = transformerFunctions .matchInline (val , resolver , JSON_TRANSFORMER );
47
+ var match = transformerFunctions .matchInline (path , val , resolver , JSON_TRANSFORMER );
47
48
if (match != null ) {
48
- var matchResult = match .getResult ();
49
+ var matchResult = match .result ();
49
50
if (matchResult instanceof JsonElementStreamer streamer ) {
50
51
return allowReturningStreams ? streamer : streamer .toJsonArray ();
51
52
}
@@ -61,10 +62,10 @@ protected Object fromJsonPrimitive(JE definition, co.nlighten.jsontransform.Para
61
62
}
62
63
63
64
64
- protected Object fromJsonObject (JO definition , co .nlighten .jsontransform .ParameterResolver resolver , boolean allowReturningStreams ) {
65
- var match = transformerFunctions .matchObject (definition , resolver , JSON_TRANSFORMER );
65
+ protected Object fromJsonObject (String path , JO definition , co .nlighten .jsontransform .ParameterResolver resolver , boolean allowReturningStreams ) {
66
+ var match = transformerFunctions .matchObject (path , definition , resolver , JSON_TRANSFORMER );
66
67
if (match != null ) {
67
- var res = match .getResult ();
68
+ var res = match .result ();
68
69
return res instanceof JsonElementStreamer s
69
70
? (allowReturningStreams ? s : s .toJsonArray ())
70
71
: adapter .wrap (res );
@@ -73,7 +74,7 @@ protected Object fromJsonObject(JO definition, co.nlighten.jsontransform.Paramet
73
74
var result = adapter .jObject .create ();
74
75
if (adapter .jObject .has (definition , OBJ_DESTRUCT_KEY )) {
75
76
var val = adapter .jObject .get (definition , OBJ_DESTRUCT_KEY );
76
- var res = (JE ) fromJsonElement (val , resolver , false );
77
+ var res = (JE ) fromJsonElement (path + "[ \" * \" ]" , val , resolver , false );
77
78
if (res != null ) {
78
79
var isArray = adapter .jArray .is (val );
79
80
if (isArray && adapter .jArray .is (res )) {
@@ -98,13 +99,15 @@ protected Object fromJsonObject(JO definition, co.nlighten.jsontransform.Paramet
98
99
if (kv .getKey ().equals (OBJ_DESTRUCT_KEY )) continue ;
99
100
var localKey = kv .getKey ();
100
101
var localValue = kv .getValue ();
101
- if (adapter .isJsonString (localValue ) && adapter .getAsString (localValue ).equals ("#null" )) {
102
+ if (adapter .isJsonString (localValue ) && adapter .getAsString (localValue ).equals (NULL_VALUE )) {
102
103
// don't define key if #null was used
103
104
// might already exist, so try removing it
104
105
adapter .jObject .remove (result , localKey );
105
106
continue ;
106
107
}
107
- var value = (JE ) fromJsonElement (localValue , resolver , false );
108
+ var value = (JE ) fromJsonElement (
109
+ path + JsonTransformerUtils .toObjectFieldPath (adapter , localKey ),
110
+ localValue , resolver , false );
108
111
if (!adapter .isNull (value ) || adapter .jObject .has (result , localKey ) /* we allow overriding with null*/ ) {
109
112
adapter .jObject .add (result , localKey , value );
110
113
}
@@ -113,20 +116,21 @@ protected Object fromJsonObject(JO definition, co.nlighten.jsontransform.Paramet
113
116
return result ;
114
117
}
115
118
116
- protected Object fromJsonElement (JE definition , ParameterResolver resolver , boolean allowReturningStreams ) {
119
+ protected Object fromJsonElement (String path , JE definition , ParameterResolver resolver , boolean allowReturningStreams ) {
117
120
if (adapter .isNull (definition ))
118
121
return adapter .jsonNull ();
119
122
if (adapter .jArray .is (definition )) {
120
123
var result = adapter .jArray .create ();
124
+ var index = new AtomicInteger (0 );
121
125
adapter .jArray .stream ((JA )definition )
122
- .map (d -> (JE )fromJsonElement (d , resolver , false ))
126
+ .map (d -> (JE )fromJsonElement (path + "[" + index . getAndIncrement () + "]" , d , resolver , false ))
123
127
.forEachOrdered (item -> adapter .jArray .add (result , item ));
124
128
return result ;
125
129
}
126
130
if (adapter .jObject .is (definition )) {
127
- return fromJsonObject ((JO )definition , resolver , allowReturningStreams );
131
+ return fromJsonObject (path , (JO )definition , resolver , allowReturningStreams );
128
132
}
129
- return fromJsonPrimitive (definition , resolver , allowReturningStreams );
133
+ return fromJsonPrimitive (path , definition , resolver , allowReturningStreams );
130
134
}
131
135
132
136
public JE getDefinition () {
0 commit comments