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,46 @@ 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 ) &&
264+ obj .get (JsonMetadataStrings .TYPE ).getAsString ().equals (JsonMetadataStrings .FRAGMENT_FIELD_ALIAS )) {
265+ metadata .put (obj .get (JsonMetadataStrings .NAME ).getAsString (),
266+ obj .get (JsonMetadataStrings .FIELD_CLASS ).getAsJsonObject ());
267+ } else {
268+ CtfCoreLoggerUtil .logInfo ("Metadata error, type not found for element " + String .valueOf (obj )); //$NON-NLS-1$
269+ }
270+ }
271+
251272 ICTFMetadataNode fragment ;
252273 try {
253- fragment = Objects .requireNonNull (gson .fromJson (jsonBlocks [ i ] , CTFJsonMetadataNode .class ));
274+ fragment = Objects .requireNonNull (gson .fromJson (element , CTFJsonMetadataNode .class ));
254275 } catch (JsonSyntaxException e ) {
255276 throw new CTFException ("Trace cannot be parsed as CTF2" ); //$NON-NLS-1$
256277 }
257278
258279 String type = fragment .getType ();
259280 if (type .equals (JsonMetadataStrings .FRAGMENT_PREAMBLE )) {
260- fragment = Objects .requireNonNull (gson .fromJson (jsonBlocks [ i ] , JsonPreambleMetadataNode .class ));
281+ fragment = Objects .requireNonNull (gson .fromJson (element , JsonPreambleMetadataNode .class ));
261282 } else if (type .equals (JsonMetadataStrings .FRAGMENT_TRACE )) {
262- fragment = Objects .requireNonNull (gson .fromJson (jsonBlocks [ i ] , JsonTraceMetadataNode .class ));
283+ fragment = Objects .requireNonNull (gson .fromJson (element , JsonTraceMetadataNode .class ));
263284 } else if (type .equals (JsonMetadataStrings .FRAGMENT_CLOCK )) {
264- fragment = Objects .requireNonNull (gson .fromJson (jsonBlocks [ i ] , JsonClockMetadataNode .class ));
285+ fragment = Objects .requireNonNull (gson .fromJson (element , JsonClockMetadataNode .class ));
265286 } else if (type .equals (JsonMetadataStrings .FRAGMENT_EVENT_RECORD )) {
266- fragment = Objects .requireNonNull (gson .fromJson (jsonBlocks [ i ] , JsonEventRecordMetadataNode .class ));
287+ fragment = Objects .requireNonNull (gson .fromJson (element , JsonEventRecordMetadataNode .class ));
267288 } else if (type .equals (JsonMetadataStrings .FRAGMENT_DATA_STREAM )) {
268- fragment = Objects .requireNonNull (gson .fromJson (jsonBlocks [ i ] , JsonDataStreamMetadataNode .class ));
289+ fragment = Objects .requireNonNull (gson .fromJson (element , JsonDataStreamMetadataNode .class ));
269290 if (!jsonBlocks [i ].contains ("id:" )) { //$NON-NLS-1$
270291 ((JsonDataStreamMetadataNode ) fragment ).setId (-1 );
271292 }
272293 } else if (type .equals (JsonMetadataStrings .FRAGMENT_FIELD_ALIAS )) {
273- fragment = Objects .requireNonNull (gson .fromJson (jsonBlocks [ i ] , JsonFieldClassAliasMetadataNode .class ));
294+ fragment = Objects .requireNonNull (gson .fromJson (element , JsonFieldClassAliasMetadataNode .class ));
274295 }
275296
276297 ((CTFJsonMetadataNode ) fragment ).initialize ();
@@ -281,6 +302,23 @@ private static ICTFMetadataNode parseJsonToTree(String json) throws CTFException
281302 return root ;
282303 }
283304
305+ private static void expandAliases (JsonObject obj , Map <String , JsonObject > metadata ) {
306+ for (String key : obj .keySet ()) {
307+ JsonElement value = obj .get (key );
308+ if (value .isJsonPrimitive () && value .getAsJsonPrimitive ().isString () && metadata .containsKey (value .getAsString ())) {
309+ obj .add (key , metadata .get (value .getAsString ()));
310+ } else if (value .isJsonObject ()) {
311+ expandAliases (value .getAsJsonObject (), metadata );
312+ } else if (value .isJsonArray ()) {
313+ for (JsonElement elem : value .getAsJsonArray ()) {
314+ if (elem .isJsonObject ()) {
315+ expandAliases (elem .getAsJsonObject (), metadata );
316+ }
317+ }
318+ }
319+ }
320+ }
321+
284322 /**
285323 * Checks the version of the CTF trace by reading the first JSON fragment if
286324 * it is a CTF2 fragment it updates the major of the trace
0 commit comments