18
18
19
19
import org .slf4j .Logger ;
20
20
import org .slf4j .LoggerFactory ;
21
+ import org .apache .commons .lang3 .StringUtils ;
21
22
import org .json .*;
23
+ import org .springframework .beans .factory .annotation .Autowired ;
22
24
import org .springframework .stereotype .Component ;
23
25
24
- import com .fasterxml . jackson . core . JsonProcessingException ;
26
+ import com .ericsson . ei . jmespath . JmesPathInterface ;
25
27
import com .fasterxml .jackson .databind .JsonNode ;
26
28
import com .fasterxml .jackson .databind .ObjectMapper ;
27
29
import com .fasterxml .jackson .databind .node .ArrayNode ;
28
30
import com .github .wnameless .json .flattener .JsonFlattener ;
29
31
30
- import java .io .IOException ;
32
+ import lombok .Setter ;
33
+
31
34
import java .util .*;
32
35
33
36
@ Component
34
37
public class MergePrepare {
35
38
36
- static Logger log = (Logger ) LoggerFactory .getLogger (MergePrepare .class );
39
+ @ Setter
40
+ @ Autowired
41
+ JmesPathInterface jmesPathInterface ;
37
42
38
- public String getKeyFromRule (String mergeRule ){
39
- String ruleKey = "" ;
40
- try {
41
- JSONObject ruleJSONObject = new JSONObject (mergeRule );
42
- if (ruleJSONObject .keys ().hasNext ()){
43
- ruleKey = (String ) ruleJSONObject .keys ().next ();
44
- if (ruleJSONObject .get (ruleKey ).getClass () == JSONObject .class )
45
- ruleKey = new StringBuilder ().append (ruleKey ).
46
- append ('.' ).append (getKeyFromRule (ruleJSONObject .
47
- get (ruleKey ).toString ())).toString ();
48
- }
49
- }catch (Exception e ){
50
- log .info (e .getMessage (),e );
51
- }
52
- return ruleKey ;
53
- }
43
+ static Logger log = (Logger ) LoggerFactory .getLogger (MergePrepare .class );
54
44
55
45
public String getValueFromRule (String mergeRule ){
56
46
String ruleValue = "" ;
57
47
try {
58
48
JSONObject ruleJSONObject = new JSONObject (mergeRule );
59
49
if (ruleJSONObject .keys ().hasNext ()){
60
50
String ruleKey = (String ) ruleJSONObject .keys ().next ();
61
- if (ruleJSONObject .get (ruleKey ).getClass () == JSONObject .class )
62
- return getValueFromRule (ruleJSONObject .get (ruleKey ).toString ());
51
+ Object value = ruleJSONObject .get (ruleKey );
52
+ if (value .getClass () == JSONObject .class )
53
+ return getValueFromRule (value .toString ());
54
+ else if (value .getClass () == JSONArray .class ) {
55
+ return getValueFromRule (((JSONArray )value ).get (0 ).toString ());
56
+ }
63
57
return ruleJSONObject .getString (ruleKey );
64
58
}
65
- }catch (Exception e ){
66
- log .info (e .getMessage (),e );
67
- }
68
- return ruleValue ;
69
- }
70
-
71
- public String getMergePathOld (String originObject , String mergeRule ) {
72
- String mergePath = "" ;
73
- try {
74
- String ruleKey = "" ;
75
- try {
76
- JSONObject originJSONObject = new JSONObject (originObject );
77
- JSONObject ruleJSONObject = new JSONObject (mergeRule );
78
- if (ruleJSONObject .keys ().hasNext ()){
79
- ruleKey = (String ) ruleJSONObject .keys ().next ();
80
- }
81
- Iterator <String > originObjectKeys = originJSONObject .keys ();
82
- while (originObjectKeys .hasNext ()) {
83
- String originObjectKey = originObjectKeys .next ();
84
- if (originObjectKey .equals (ruleKey )){
85
- if (ruleJSONObject .get (ruleKey ).getClass ().
86
- equals (String .class )){
87
- if (ruleJSONObject .get (ruleKey ).
88
- equals (originJSONObject .get (originObjectKey ))){
89
- return originObjectKey ;
90
- }
91
- } else {
92
- return originObjectKey + '.' +
93
- getMergePathOld (originJSONObject .
94
- get (originObjectKey ).toString (),
95
- ruleJSONObject .get (ruleKey ).toString ());
96
- }
97
- } else {
98
- Object keyObject = originJSONObject .get (originObjectKey );
99
- // if (keyObject instanceof JSONObject) {
100
- mergePath = getMergePathOld (keyObject .toString (), mergeRule );
101
- if (!mergePath .isEmpty () && pathContainsMergeRule (mergePath , mergeRule )) {
102
- return originObjectKey + '.' + mergePath ;
103
- // }
104
- }
105
- }
106
- }
107
- } catch (JSONException JSONObjectException ){
108
- try {
109
- JSONArray originJSONArray = new JSONArray (originObject );
110
- int i ;
111
- for (i = 0 ; i < originJSONArray .length (); i ++) {
112
- mergePath = getMergePathOld (originJSONArray .get (i ).
113
- toString (), mergeRule );
114
- if (!mergePath .isEmpty ()) {
115
- return Integer .toString (i ) + '.' + mergePath ;
116
- }
117
- }
118
- ruleKey = (String ) getKeyFromRule (mergeRule .toString ());
119
- if (!ruleKey .isEmpty ()) {
120
- return Integer .toString (i ) + '.' + ruleKey ;
121
- }
122
- }catch (JSONException JSONArrayException ) {
123
- return mergePath ;
124
- }
59
+ } catch (JSONException e ) {
60
+ try {
61
+ JSONArray ruleJSONArray = new JSONArray (mergeRule );
62
+ return getValueFromRule (ruleJSONArray .getString (1 ));
63
+ } catch (Exception ne ) {
64
+ log .info (ne .getMessage (), ne );
125
65
}
126
66
} catch (Exception e ){
127
67
log .info (e .getMessage (),e );
128
68
}
129
- return mergePath ;
69
+ return ruleValue ;
130
70
}
131
71
132
72
public boolean pathContainsMergeRule (String path , String mergeRule ) {
@@ -186,6 +126,55 @@ public static String longestCommonSubstring(String s1, String s2)
186
126
return s1 .substring (start , (start + max ));
187
127
}
188
128
129
+ // TODO fix so that we do not need to pass both originObject and stringObject which are
130
+ // different representations of the same object.
131
+ public String getMergePathFromArrayMergeRules (String originObject , String mergeRule , String stringObject ) {
132
+ try {
133
+ JSONArray ruleJSONArray = new JSONArray (mergeRule );
134
+ String firstRule = ruleJSONArray .getString (0 );
135
+ String secondRule = ruleJSONArray .getString (1 );
136
+ String firstPath = getMergePath (originObject , firstRule );
137
+ String firstPathTrimmed = trimLastInPath (firstPath , "." );
138
+
139
+ if (propertyExist (stringObject , firstPathTrimmed , secondRule )) {
140
+ if (!firstPath .isEmpty ()) {
141
+ String firstPathNoIndexes = StringUtils .removePattern (firstPath , "(\\ .0|\\ .[1-9][0-9]*)" );
142
+ String [] firstPathSubstrings = firstPathNoIndexes .split ("\\ ." );
143
+ ArrayList <String > fp = new ArrayList (Arrays .asList (firstPathSubstrings ));
144
+ fp .remove (fp .size ()-1 );
145
+ firstPathTrimmed = StringUtils .join (fp ,":{" );
146
+ String secondRuleComplete = "{" + firstPathTrimmed + ":" + secondRule + "}" ;
147
+ for (int i = 1 ;i <fp .size ();i ++) {
148
+ secondRuleComplete += "}" ;
149
+ }
150
+
151
+ return getMergePath (originObject , secondRuleComplete );
152
+ } else {
153
+ return getMergePath (originObject , secondRule );
154
+ }
155
+ } else {
156
+ String flattenRule = JsonFlattener .flatten (secondRule );
157
+ String [] rulePair = flattenRule .split (":" );
158
+ String ruleKey = destringify (rulePair [0 ]);
159
+ if (firstPathTrimmed .isEmpty ()) {
160
+ return ruleKey ;
161
+ }
162
+ String finalPath = firstPathTrimmed + "." + ruleKey ;
163
+ return finalPath ;
164
+ }
165
+ } catch (Exception ne ) {
166
+ log .info (ne .getMessage (), ne );
167
+ }
168
+ return "" ;
169
+ }
170
+
171
+ public String trimLastInPath (String path , String delimiter ) {
172
+ String [] firstPathSubstrings = path .split ("\\ ." );
173
+ ArrayList <String > fp = new ArrayList (Arrays .asList (firstPathSubstrings ));
174
+ fp .remove (fp .size ()-1 );
175
+ return StringUtils .join (fp , delimiter );
176
+ }
177
+
189
178
public String getMergePath (String originObject , String mergeRule ){
190
179
String mergePath = "" ;
191
180
String stringObject = "" ;
@@ -194,9 +183,14 @@ public String getMergePath(String originObject, String mergeRule){
194
183
try {
195
184
objectJSONObject = new JSONObject (originObject );
196
185
stringObject = objectJSONObject .toString ();
197
- JSONObject ruleJSONObject = new JSONObject (mergeRule );
186
+ Object ruleJSONObject = new JSONObject (mergeRule );
187
+ //hack to remove quotes
198
188
stringRule = ruleJSONObject .toString ();
189
+ stringRule = stringRule .replaceAll ("\\ [\\ {" , "{" );
190
+ stringRule = stringRule .replaceAll ("\\ }\\ ]" , "}" );
199
191
} catch (JSONException e ) {
192
+ return getMergePathFromArrayMergeRules (originObject , mergeRule , stringObject );
193
+ } catch (Exception e ) {
200
194
log .info (e .getMessage (),e );
201
195
}
202
196
Map <String , Object > flattenJson = JsonFlattener .flattenAsMap (stringObject );
@@ -216,7 +210,6 @@ public String getMergePath(String originObject, String mergeRule){
216
210
if (ruleKeyFactors .length > 0 )
217
211
lastRuleFactor = ruleKeyFactors [ruleKeyFactors .length -1 ];
218
212
ArrayList <String > pathsWithValue = new ArrayList <String >();
219
- Map <String ,String []> commonRuleStrings = new HashMap <String ,String []>();
220
213
ArrayList <String > pathsContainingRule = new ArrayList <String >();
221
214
222
215
for (Map .Entry <String , Object > entry : flattenJson .entrySet ()) {
@@ -228,15 +221,12 @@ public String getMergePath(String originObject, String mergeRule){
228
221
229
222
int factorCount = 0 ;
230
223
for (String factor : ruleKeyFactors ) {
231
- // if (entryKey.endsWith(lastRuleFactor)) {
232
-
233
- if (entryKey .contains (factor )) {
234
- factorCount ++;
235
- }
236
- if (factorCount == ruleKeyFactors .length ) {
237
- pathsContainingRule .add (destringify (entryKey ));
238
- }
239
- // }
224
+ if (entryKey .contains (factor )) {
225
+ factorCount ++;
226
+ }
227
+ if (factorCount == ruleKeyFactors .length ) {
228
+ pathsContainingRule .add (destringify (entryKey ));
229
+ }
240
230
}
241
231
}
242
232
@@ -248,6 +238,8 @@ public String getMergePath(String originObject, String mergeRule){
248
238
// one of the alternatives.
249
239
String winingPath = "" ;
250
240
for (String path : pathsWithValue ) {
241
+ if (path .equals (ruleKey ))
242
+ return path ;
251
243
if (path .length () > winingPath .length ())
252
244
winingPath = path ;
253
245
}
@@ -272,7 +264,12 @@ public String getMergePath(String originObject, String mergeRule){
272
264
}
273
265
if (longestCommonString .endsWith ("." )) {
274
266
longestCommonString = longestCommonString .substring (0 , longestCommonString .length ()-1 );
275
- } else if (longestCommonString .startsWith ("." )) {
267
+ }
268
+ if (longestCommonString .matches (".*\\ .0" )) {
269
+ longestCommonString = longestCommonString .substring (0 , longestCommonString .length ()-2 );
270
+ int breakHere = 0 ;
271
+ }
272
+ if (longestCommonString .startsWith ("." )) {
276
273
longestCommonString = "" ;
277
274
}
278
275
mergePath = longestCommonString ;
@@ -302,34 +299,71 @@ public String getMergePath(String originObject, String mergeRule){
302
299
return mergePath ;
303
300
}
304
301
305
- public String addMissingLevels (String originObject , String objectToMerge ,
306
- String mergeRule , String mergePath ) {
307
- if (mergePath .isEmpty ()) {
308
- return objectToMerge ;
302
+ /**This method can not be generalized since it removes the last element in the path before
303
+ * doing the check.
304
+ * @param originObject
305
+ * @param path
306
+ * @param targetObject
307
+ * @return
308
+ */
309
+ public boolean propertyExist (String originObject , String path , String targetObject ) {
310
+ String fixedPath = path ;
311
+ if (path != null ) {
312
+ fixedPath = path .replaceAll ("(\\ .0|\\ .[1-9][0-9]*)" , "[$1]" );
313
+ fixedPath = fixedPath .replaceAll ("\\ [\\ ." , "[" );
309
314
}
310
315
316
+ try {
317
+ String firstKey = destringify (targetObject .split (":" )[0 ]);
318
+ JsonNode jsonResult = null ;
319
+ ObjectMapper objectMapper = new ObjectMapper ();
320
+ if (path .isEmpty ()) {
321
+ jsonResult = objectMapper .readTree (originObject );
322
+ } else {
323
+ jsonResult = jmesPathInterface .runRuleOnEvent (fixedPath , originObject );
324
+ }
325
+ JsonNode value = jsonResult .get (firstKey );
326
+ if (value == null )
327
+ return false ;
328
+ } catch (Exception e ) {
329
+ log .info (e .getMessage (),e );
330
+ }
331
+
332
+ return true ;
333
+ }
334
+
335
+ public String addMissingLevels (String originObject , String objectToMerge ,
336
+ String mergeRule , String mergePath ) {
337
+
311
338
JSONObject newObject = new JSONObject ();
312
339
try {
313
340
JSONArray mergePathArray = new JSONArray (mergePath .split ("\\ ." ));
314
341
JSONObject mergeObject = new JSONObject (objectToMerge );
315
- String ruleKey = (String ) mergePathArray .get (mergePathArray .length ()-1 );
316
- String ruleValue = getValueFromRule (mergeRule );
317
- mergeObject .put (ruleKey , ruleValue );
342
+ if (!mergePath .isEmpty ()) {
343
+ String ruleKey = (String ) mergePathArray .get (mergePathArray .length ()-1 );
344
+ String ruleValue = getValueFromRule (mergeRule );
345
+ mergeObject .put (ruleKey , ruleValue );
346
+ }
318
347
319
348
if (mergePathArray .length () == 1 )
320
349
return mergeObject .toString ();
321
350
322
351
for (int i = 1 ; i < mergePathArray .length (); i ++) {
323
352
int mergePathIndex = mergePathArray .length () - (1 + i );
324
353
String pathElement = mergePathArray .get (mergePathIndex ).toString ();
325
- if (isNumeric (pathElement )){
354
+ if (isNumeric (pathElement )) {
355
+ int index = Integer .parseInt (pathElement );
326
356
int arraySize = getOriginObjectArraySize (originObject , mergePathArray , mergePathIndex , pathElement );
327
357
JSONArray mergeArray = new JSONArray ();
328
- for (int k = 0 ; k < arraySize ; k ++) {
329
- if (k == Integer .parseInt (pathElement )){
330
- mergeArray .put (mergeObject );
331
- }else {
332
- mergeArray .put (new JSONObject ());
358
+ if (arraySize == 0 && index == 0 ){
359
+ mergeArray .put (mergeObject );
360
+ } else {
361
+ for (int k = 0 ; k < arraySize ; k ++) {
362
+ if (k == Integer .parseInt (pathElement )){
363
+ mergeArray .put (mergeObject );
364
+ }else {
365
+ mergeArray .put (new JSONObject ());
366
+ }
333
367
}
334
368
}
335
369
i ++;
0 commit comments