internal static IStorable LoadObject(Type objType, string idStr, Database db, SerializationContext context = null) { IStorable storable = null, parent; Document doc; Guid id; id = DocumentsSerializer.IDFromString(idStr); if (context == null) { context = new SerializationContext(db, objType); context.ContractResolver = new StorablesStackContractResolver(context, null); context.RootID = id; } if (context.Cache.IsCached(id)) { return(context.Cache.ResolveReference(id)); } doc = db.GetExistingDocument(idStr); if (doc != null) { Type realType = context.Binder.BindToType(doc.Properties [OBJ_TYPE] as string); if (realType == null) { /* Should never happen */ Log.Error("Error getting type " + doc.Properties [OBJ_TYPE] as string); realType = objType; } else if (!objType.IsAssignableFrom(realType)) { Log.Error("Types mismatch " + objType.FullName + " vs " + realType.FullName); return(null); } storable = DeserializeObject(doc, realType, context) as IStorable; if (storable != null) { storable.DocumentID = idStr; if (context.Stack.Count != 0) { parent = context.Stack.Peek(); parent.SavedChildren.Add(storable); storable.ParentID = parent.ID; } else { storable.ParentID = ParentIDFromString(idStr); } } } return(storable); }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { IStorable storable; Guid id; string idStr; idStr = reader.Value as string; if (idStr == null) { return(null); } id = DocumentsSerializer.IDFromString(idStr); /* Check if it's a circular reference and the object is currently being deserialized. In this scenario * the oject is not yet in the cache, but we have a reference of the object in the stack. * eg: TimelineEvent.Project where the TimelineEvent is a children of Project and Project is in the stack * as being deserialized */ storable = context.Stack.FirstOrDefault(e => e.ID == id); if (storable == null) { /* Now check in the Cache and return the cached object instance instead a new one */ storable = context.Cache.ResolveReference(id); } /* If the object is being deserialized for the first retrieve from the DB document */ if (storable == null) { storable = DocumentsSerializer.LoadObject(objectType, idStr, context.DB, context) as IStorable; if (storable == null) { throw new StorageException( String.Format("Referenced object of type {0} with id: {1} was not found in the DB", objectType, id)); } context.Cache.AddReference(storable); } return(storable); }