private void SerializeDictionaryGeneric <TValue>(ISerializerNode node, Writer writer, DictionaryTypeSpec dictType) { var jsonWriter = writer.JsonWriter; var dict = (IDictionary <string, TValue>)node.Value; var expectedValueType = dictType.ValueType; jsonWriter.WriteStartObject(); var dictDelta = dict as IDictionaryDelta <string, TValue>; var serializedKeyValuePairs = dictDelta != null ? dictDelta.ModifiedItems : dict; if (dictDelta != null && dictDelta.RemovedKeys.Any()) { foreach (var removed in dictDelta.RemovedKeys) { jsonWriter.WritePropertyName("-" + EscapePropertyName(removed)); jsonWriter.WriteStartObject(); jsonWriter.WriteEndObject(); } } foreach (var kvp in serializedKeyValuePairs) { // TODO: Support other key types than string jsonWriter.WritePropertyName(EscapePropertyName(kvp.Key)); var itemNode = new ItemValueSerializerNode(kvp.Value, expectedValueType, node.ExpandPath, node.Context, node); SerializeThroughContext(itemNode, writer); } jsonWriter.WriteEndObject(); }
private void SerializeNodeInner(ISerializerNode node, Writer writer) { if (node.Value == null) { writer.JsonWriter.WriteNull(); return; } var mappedType = node.ExpectedBaseType ?? node.ValueType; if (mappedType == typeof(object)) { mappedType = node.ValueType; } switch (mappedType.SerializationMode) { case TypeSerializationMode.Dictionary: SerializeDictionary(node, writer); break; case TypeSerializationMode.Structured: SerializeComplex(node, writer); break; case TypeSerializationMode.Array: SerializeCollection(node, writer); break; case TypeSerializationMode.Value: SerializeValue(node, writer); break; } }
public void Serialize(ISerializerNode node, Action<ISerializerNode> serializeNodeAction) { if (node.Value is IClientResource && !(node.Value is PostResourceBase) && !(node.Value is IDelta) && !node.IsRemoved) { node.SerializeAsReference = true; } serializeNodeAction(node); }
public ItemValueSerializerNode(object value, TypeSpec expectedBaseType, string expandPath, ISerializationContext context, ISerializerNode parentNode, bool isRemoved = false) : base(expectedBaseType, expandPath, context, parentNode, isRemoved) { Value = value; }
private static string GetExpandPath(ISerializerNode parentNode, PropertySpec property) { if (string.IsNullOrEmpty(parentNode.ExpandPath)) { if (property is QueryResultType.ItemsPropertySpec) return string.Empty; return property.LowerCaseName; } return string.Concat(parentNode.ExpandPath, ".", property.LowerCaseName); }
public PropertyValueSerializerNode( ISerializerNode parentNode, PropertySpec property) { if (parentNode == null) throw new ArgumentNullException("parentNode"); if (property == null) throw new ArgumentNullException("propertyMapping"); this.parentNode = parentNode; this.property = property; context = parentNode.Context; }
public ItemValueSerializerNode( object value, TypeSpec expectedBaseType, string expandPath, ISerializationContext context, ISerializerNode parentNode, bool isRemoved = false) { this.value = value; this.expectedBaseType = expectedBaseType; this.expandPath = expandPath; this.context = context; this.parentNode = parentNode; this.isRemoved = isRemoved; }
public void Serialize(ISerializerNode node, Action <ISerializerNode> serializeNodeAction) { if (node.Value is IClientResource && !(node.Value is PostResourceBase) && !(node.Value is IDelta) && !node.IsRemoved) { node.SerializeAsReference = true; } serializeNodeAction(node); }
protected SerializerNode(TypeSpec expectedBaseType, string expandPath, ISerializationContext context, ISerializerNode parentNode, bool isRemoved = false) { ExpectedBaseType = expectedBaseType; ExpandPath = expandPath; Context = context; ParentNode = parentNode; IsRemoved = isRemoved; }
private static string GetExpandPath(ISerializerNode parentNode, PropertySpec property) { if (string.IsNullOrEmpty(parentNode.ExpandPath)) { if (property is QueryResultType.ItemsPropertySpec) { return(string.Empty); } return(property.LowerCaseName); } return(string.Concat(parentNode.ExpandPath, ".", property.LowerCaseName)); }
public PropertyValueSerializerNode( ISerializerNode parentNode, PropertySpec property) : base( property != null ? property.PropertyType : null, GetExpandPath(parentNode, property), parentNode != null ? parentNode.Context : null, parentNode) { if (parentNode == null) throw new ArgumentNullException(nameof(parentNode)); if (property == null) throw new ArgumentNullException(nameof(property)); Property = property; }
public void Serialize(ISerializerNode node, Action <ISerializerNode> nodeSerializerAction) { var isExpanded = (node.ExpectedBaseType != typeof(object) && node.ExpectedBaseType != null && node.ExpectedBaseType.IsAlwaysExpanded) || PathToBeExpanded(node.ExpandPath) || (node.ExpectedBaseType != null && node.ExpectedBaseType.IsCollection && node.Context.PathToBeExpanded(node.ExpandPath + "!")) || (GetPropertyExpandMode(node) != ExpandMode.Default) || (node.Value != null && node.ValueType != null && node.ValueType.IsAlwaysExpanded); node.SerializeAsReference = !isExpanded; nodeSerializerAction(node); }
private void SerializeCollection(ISerializerNode node, Writer writer) { var jsonWriter = writer.JsonWriter; if (node.SerializeAsReference) { jsonWriter.WriteStartObject(); jsonWriter.WritePropertyName("_ref"); jsonWriter.WriteValue(node.Uri); jsonWriter.WriteEndObject(); } else { jsonWriter.WriteStartArray(); TypeSpec baseElementType; if (node.ExpectedBaseType != null && node.ExpectedBaseType.IsCollection) { baseElementType = node.ExpectedBaseType.ElementType; } else { baseElementType = node.Context.GetClassMapping(typeof(object)); } var delta = node.Value as ICollectionDelta; if (delta != null) { foreach (var item in delta.AddedItems.Concat(delta.ModifiedItems)) { var itemNode = new ItemValueSerializerNode(item, baseElementType, node.ExpandPath, node.Context, node); SerializeThroughContext(itemNode, writer); } foreach (var item in delta.RemovedItems) { var itemNode = new ItemValueSerializerNode(item, baseElementType, node.ExpandPath, node.Context, node, true); SerializeThroughContext(itemNode, writer); } } else { foreach (var item in (IEnumerable)node.Value) { var itemNode = new ItemValueSerializerNode(item, baseElementType, node.ExpandPath, node.Context, node); SerializeThroughContext(itemNode, writer); } } jsonWriter.WriteEndArray(); } }
private void SerializeComplex(ISerializerNode node, Writer writer) { if (node.Value == null) { writer.JsonWriter.WriteNull(); } else if (node.SerializeAsReference) { SerializeReference(node, writer); } else { SerializeExpanded(node, writer); } }
protected override void SerializeNode(ISerializerNode node, Writer writer) { try { if (this.loopDetector.Value++ > 300) { throw new InvalidOperationException("Deep recursion detected, trying to avoid stack overflow."); } SerializeNodeInner(node, writer); } finally { this.loopDetector.Value--; } }
private static void SerializeReference(ISerializerNode node, Writer writer) { var jsonWriter = writer.JsonWriter; jsonWriter.WriteStartObject(); jsonWriter.WritePropertyName("_ref"); jsonWriter.WriteValue(node.Uri); var valueType = node.ValueType; if (node.ExpectedBaseType != valueType) { SerializeTypeProperty(jsonWriter, valueType); } jsonWriter.WriteEndObject(); }
public PropertyValueSerializerNode( ISerializerNode parentNode, PropertySpec property) : base( property != null ? property.PropertyType : null, GetExpandPath(parentNode, property), parentNode != null ? parentNode.Context : null, parentNode) { if (parentNode == null) { throw new ArgumentNullException(nameof(parentNode)); } if (property == null) { throw new ArgumentNullException(nameof(property)); } Property = property; }
private ExpandMode GetPropertyExpandMode(ISerializerNode node) { if (node.ExpectedBaseType.IsCollection && node.ExpectedBaseType.ElementType.IsAlwaysExpanded) { return(ExpandMode.Full); } if (node.ParentNode != null && node.ParentNode.ValueType.IsCollection && GetPropertyExpandMode(node.ParentNode) == ExpandMode.Full) { return(ExpandMode.Full); } var propNode = node as PropertyValueSerializerNode; if (propNode == null) { return(ExpandMode.Default); } return(propNode.Property.ExpandMode); }
private void SerializeDictionary(ISerializerNode node, Writer writer) { var dictType = node.ExpectedBaseType as DictionaryTypeSpec ?? node.ValueType as DictionaryTypeSpec; if (dictType == null) { throw new PomonaSerializationException("Unable to serialize dictionary of typespec " + node.ExpectedBaseType); } var keyMappedType = dictType.KeyType.Type; if (keyMappedType != typeof(string)) { throw new NotImplementedException( "Does not support serialization of dictionaries where key is not string."); } var valueMappedType = dictType.ValueType.Type; serializeDictionaryGenericMethod .MakeGenericMethod(valueMappedType) .Invoke(this, new object[] { node, writer, dictType }); }
private static void SerializeValue(ISerializerNode node, Writer writer) { var value = node.Value; var boxValueWithTypeSpec = node.ExpectedBaseType != null && node.ExpectedBaseType.Type == typeof(object) && ValueBoxingRequired(node.Value.GetType()); if (boxValueWithTypeSpec) { writer.JsonWriter.WriteStartObject(); SerializeTypeProperty(writer.JsonWriter, node.ValueType); writer.JsonWriter.WritePropertyName("value"); } var jsonConverter = node.ValueType.GetCustomJsonConverter(); if (jsonConverter == null && node.ValueType is EnumTypeSpec) { jsonConverter = new StringEnumConverter(); } if (jsonConverter != null) { jsonConverter.WriteJson(writer.JsonWriter, value, null); } else { writer.JsonWriter.WriteValue(value); } if (boxValueWithTypeSpec) { writer.JsonWriter.WriteEndObject(); } }
protected void SerializeThroughContext(ISerializerNode node, TWriter writer) { node.Context.Serialize(node, n => SerializeNode(n, writer)); }
private void SerializeExpanded(ISerializerNode node, Writer writer) { var jsonWriter = writer.JsonWriter; var serializingDelta = node.Value is IDelta; jsonWriter.WriteStartObject(); if (node.ValueType is ResourceType && node.Uri != null) { jsonWriter.WritePropertyName("_uri"); jsonWriter.WriteValue(node.Uri); } if (node.ExpectedBaseType != node.ValueType && !node.ValueType.IsAnonymous() && !serializingDelta && !node.IsRemoved) { SerializeTypeProperty(jsonWriter, node.ValueType); } if (node.IsRemoved || (serializingDelta && node.ParentNode != null && node.ParentNode.ValueType.IsCollection)) { var primaryId = node.ValueType.Maybe().OfType <StructuredType>().Select(x => x.PrimaryId).OrDefault(); if (primaryId == null) { throw new PomonaSerializationException("When we are removing complex object a primary id is required."); } jsonWriter.WritePropertyName((node.IsRemoved ? "-@" : "*@") + primaryId.JsonName); jsonWriter.WriteValue(primaryId.GetValue(node.Value, node.Context)); if (node.IsRemoved) { jsonWriter.WriteEndObject(); return; } } PomonaJsonSerializerTypeEntry cacheTypeEntry; IEnumerable <PropertySpec> propertiesToSerialize = null; var pomonaSerializable = node.Value as IPomonaSerializable; if (pomonaSerializable == null && TryGetTypeEntry(node.ValueType, out cacheTypeEntry)) { cacheTypeEntry.WritePropertiesFunc(jsonWriter, node.Value, node.Context); propertiesToSerialize = cacheTypeEntry.ManuallyWrittenProperties; } propertiesToSerialize = propertiesToSerialize ?? node.ValueType.Properties; propertiesToSerialize = propertiesToSerialize.Where(x => x.IsSerialized); if (pomonaSerializable != null) { propertiesToSerialize = propertiesToSerialize.Where(x => pomonaSerializable.PropertyIsSerialized(x.Name)); } foreach (var prop in propertiesToSerialize) { var propNode = new PropertyValueSerializerNode(node, prop); if (serializingDelta && propNode.ValueType.SerializationMode == TypeSerializationMode.Structured && !(propNode.Value is IDelta)) { jsonWriter.WritePropertyName("!" + prop.JsonName); } else if (serializingDelta && propNode.ValueType.SerializationMode == TypeSerializationMode.Array && propNode.Value.Maybe().OfType <ICollectionDelta>().Select(x => x.Cleared).OrDefault(true)) { jsonWriter.WritePropertyName("!" + prop.JsonName); } else { jsonWriter.WritePropertyName(prop.JsonName); } SerializeThroughContext(propNode, writer); } jsonWriter.WriteEndObject(); }
protected abstract void SerializeNode(ISerializerNode node, TWriter writer);