public static DataObject Construct(String key, bool quietFail = false) { if (!constructorMap.ContainsKey(key)) { if (quietFail) { return(null); } throw new ParseDataException("No constructor for type: " + key); } Constructor constructor = constructorMap[key]; return(constructor.Construct()); }
private DataObject read(JsonObject obj, bool skipUnknownClasses = false) { if (obj == null) { return(null); } if (!obj.containsKey(ID)) { return(null); } // First check to see if it's been created, and if so simply return it int id = obj.getInt(ID); if (id < seenObjects.Count) { DataObject seen = seenObjects[id]; if (seen != null) { return(seen); } } // Create the (unpopulated) object and register it String className = obj.getString(CLASS); if (className == null) { return(null); } DataObject data = Constructor.Construct(className, skipUnknownClasses); while (seenObjects.Count <= id) { seenObjects.Add(null); } seenObjects[id] = data; // Instantiate the children of this object in the JSON file // This is done to create objects whose parents may no longer // exist in the data-structure, but who are themselves still // referenced. This occurs when fields are removed from a class. foreach (var kvp in obj.Entries) { object value = kvp.Value; List <object> list = value as List <object>; if (list != null) { foreach (object entry in list) { read(entry as Dictionary <string, object>, true); } } read(value as Dictionary <string, object>, true); } // If there's not corresponding C# class, we stop here. // This may happen if the class was deleted, but its data // is still in an older JSON file. if (data == null) { return(null); } // Now actually populate the object, having guaranteed // that all its children have been created (but not // necessarily populated!) readObjectBody(() => { makeKey(CLASS); makeKey(ID); data.AddFields(this); if (data is GuidDataObject) { context.Add(data as GuidDataObject); } }, obj); return(data); }