示例#1
0
        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();
        }
示例#2
0
        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;
 }
示例#5
0
 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);
        }
示例#10
0
 protected SerializerNode(TypeSpec expectedBaseType,
                          string expandPath,
                          ISerializationContext context,
                          ISerializerNode parentNode,
                          bool isRemoved = false)
 {
     ExpectedBaseType = expectedBaseType;
     ExpandPath       = expandPath;
     Context          = context;
     ParentNode       = parentNode;
     IsRemoved        = isRemoved;
 }
示例#11
0
 protected SerializerNode(TypeSpec expectedBaseType,
                          string expandPath,
                          ISerializationContext context,
                          ISerializerNode parentNode,
                          bool isRemoved = false)
 {
     ExpectedBaseType = expectedBaseType;
     ExpandPath = expandPath;
     Context = context;
     ParentNode = parentNode;
     IsRemoved = isRemoved;
 }
示例#12
0
        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;
 }
示例#14
0
        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);
        }
示例#15
0
        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();
            }
        }
示例#16
0
 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);
     }
 }
示例#17
0
        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--;
            }
        }
示例#18
0
        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();
        }
示例#19
0
 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;
 }
示例#20
0
        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);
        }
示例#21
0
        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 });
        }
示例#22
0
        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();
            }
        }
示例#23
0
 protected void SerializeThroughContext(ISerializerNode node, TWriter writer)
 {
     node.Context.Serialize(node, n => SerializeNode(n, writer));
 }
示例#24
0
        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();
        }
示例#25
0
 protected abstract void SerializeNode(ISerializerNode node, TWriter writer);