3535import java .nio .file .FileSystems ;
3636import java .nio .file .Files ;
3737import java .nio .file .Path ;
38+ import java .util .HashMap ;
3839import java .util .List ;
40+ import java .util .Map ;
3941import java .util .Objects ;
4042import java .util .UUID ;
4143
7375
7476import com .google .gson .Gson ;
7577import com .google .gson .GsonBuilder ;
78+ import com .google .gson .JsonElement ;
79+ import com .google .gson .JsonObject ;
80+ import com .google .gson .JsonParser ;
7681import com .google .gson .JsonSyntaxException ;
7782
7883/**
@@ -247,30 +252,42 @@ private static ICTFMetadataNode parseJsonToTree(String json) throws CTFException
247252 Gson gson = builder .create ();
248253
249254 String [] jsonBlocks = json .split ("\u001e " ); //$NON-NLS-1$
255+ Map <String , JsonObject > metadata = new HashMap <>();
256+
257+ // Second pass: expand string references and parse
250258 for (int i = 1 ; i < jsonBlocks .length ; i ++) {
259+ JsonElement element = JsonParser .parseString (jsonBlocks [i ]);
260+ if (element .isJsonObject ()) {
261+ JsonObject obj = element .getAsJsonObject ();
262+ expandAliases (obj , metadata );
263+ if (obj .has (JsonMetadataStrings .TYPE ) && obj .get (JsonMetadataStrings .TYPE ).getAsString ().equals (JsonMetadataStrings .FRAGMENT_FIELD_ALIAS )) {
264+ metadata .put (obj .get (JsonMetadataStrings .NAME ).getAsString (), obj .get (JsonMetadataStrings .FIELD_CLASS ).getAsJsonObject ());
265+ }
266+ }
267+
251268 ICTFMetadataNode fragment ;
252269 try {
253- fragment = Objects .requireNonNull (gson .fromJson (jsonBlocks [ i ] , CTFJsonMetadataNode .class ));
270+ fragment = Objects .requireNonNull (gson .fromJson (element , CTFJsonMetadataNode .class ));
254271 } catch (JsonSyntaxException e ) {
255272 throw new CTFException ("Trace cannot be parsed as CTF2" ); //$NON-NLS-1$
256273 }
257274
258275 String type = fragment .getType ();
259276 if (type .equals (JsonMetadataStrings .FRAGMENT_PREAMBLE )) {
260- fragment = Objects .requireNonNull (gson .fromJson (jsonBlocks [ i ] , JsonPreambleMetadataNode .class ));
277+ fragment = Objects .requireNonNull (gson .fromJson (element , JsonPreambleMetadataNode .class ));
261278 } else if (type .equals (JsonMetadataStrings .FRAGMENT_TRACE )) {
262- fragment = Objects .requireNonNull (gson .fromJson (jsonBlocks [ i ] , JsonTraceMetadataNode .class ));
279+ fragment = Objects .requireNonNull (gson .fromJson (element , JsonTraceMetadataNode .class ));
263280 } else if (type .equals (JsonMetadataStrings .FRAGMENT_CLOCK )) {
264- fragment = Objects .requireNonNull (gson .fromJson (jsonBlocks [ i ] , JsonClockMetadataNode .class ));
281+ fragment = Objects .requireNonNull (gson .fromJson (element , JsonClockMetadataNode .class ));
265282 } else if (type .equals (JsonMetadataStrings .FRAGMENT_EVENT_RECORD )) {
266- fragment = Objects .requireNonNull (gson .fromJson (jsonBlocks [ i ] , JsonEventRecordMetadataNode .class ));
283+ fragment = Objects .requireNonNull (gson .fromJson (element , JsonEventRecordMetadataNode .class ));
267284 } else if (type .equals (JsonMetadataStrings .FRAGMENT_DATA_STREAM )) {
268- fragment = Objects .requireNonNull (gson .fromJson (jsonBlocks [ i ] , JsonDataStreamMetadataNode .class ));
285+ fragment = Objects .requireNonNull (gson .fromJson (element , JsonDataStreamMetadataNode .class ));
269286 if (!jsonBlocks [i ].contains ("id:" )) { //$NON-NLS-1$
270287 ((JsonDataStreamMetadataNode ) fragment ).setId (-1 );
271288 }
272289 } else if (type .equals (JsonMetadataStrings .FRAGMENT_FIELD_ALIAS )) {
273- fragment = Objects .requireNonNull (gson .fromJson (jsonBlocks [ i ] , JsonFieldClassAliasMetadataNode .class ));
290+ fragment = Objects .requireNonNull (gson .fromJson (element , JsonFieldClassAliasMetadataNode .class ));
274291 }
275292
276293 ((CTFJsonMetadataNode ) fragment ).initialize ();
@@ -281,6 +298,23 @@ private static ICTFMetadataNode parseJsonToTree(String json) throws CTFException
281298 return root ;
282299 }
283300
301+ private static void expandAliases (JsonObject obj , Map <String , JsonObject > metadata ) {
302+ for (String key : obj .keySet ()) {
303+ JsonElement value = obj .get (key );
304+ if (value .isJsonPrimitive () && value .getAsJsonPrimitive ().isString () && metadata .containsKey (value .getAsString ())) {
305+ obj .add (key , metadata .get (value .getAsString ()));
306+ } else if (value .isJsonObject ()) {
307+ expandAliases (value .getAsJsonObject (), metadata );
308+ } else if (value .isJsonArray ()) {
309+ for (JsonElement elem : value .getAsJsonArray ()) {
310+ if (elem .isJsonObject ()) {
311+ expandAliases (elem .getAsJsonObject (), metadata );
312+ }
313+ }
314+ }
315+ }
316+ }
317+
284318 /**
285319 * Checks the version of the CTF trace by reading the first JSON fragment if
286320 * it is a CTF2 fragment it updates the major of the trace
0 commit comments