/// <summary>
        /// Convert class into a list of generic entries using custom strategy
        /// </summary>
        public static Entry EncodeClass(Type objType, ICustomSerialization customSerialization)
        {
            var encodedClass = CreateFromType(objType, customSerialization);

            var filtered = customSerialization.GetProperties(objType);

            foreach (var property in filtered)
            {
                var converted = EncodeProperty(property, customSerialization);
                // Assign default to current
                var value = converted.Value;
                value.Current = ConvertToString(value.Default, customSerialization.FormatProvider);
                // Recursive call for classes
                if (converted.Value.Type == EntryValueType.Class)
                {
                    // Convert sub entries for classes
                    var subentry = EncodeClass(property.PropertyType, customSerialization);
                    converted.SubEntries.AddRange(subentry.SubEntries);
                }

                encodedClass.SubEntries.Add(converted);
            }

            return(encodedClass);
        }
        /// <summary>
        /// Create strategy for collection
        /// </summary>
        private static ICollectionStrategy CreateStrategy(object collection, object currentCollection,
                                                          Type collectionType, ICustomSerialization serialization, ICustomAttributeProvider attributeProvider = null,
                                                          object instance = null)
        {
            ICollectionStrategy strategy;

            if (collectionType.IsArray)
            {
                strategy = new ArrayStrategy((Array)collection, currentCollection as Array, serialization);
            }
            else if (collection is IDictionary)
            {
                strategy = new DictionaryStrategy((IDictionary)collection, serialization);
            }
            else if (collection is IList)
            {
                if (currentCollection is Array)
                {
                    strategy = new ArrayIListStrategy(
                        (IList)collection, serialization, attributeProvider, instance);
                }
                else
                {
                    strategy = new ListStrategy((IList)collection, serialization);
                }
            }
            else
            {
                throw new InvalidOperationException($"Unsupported collection type {collectionType}");
            }

            return(strategy);
        }
        /// <summary>
        /// Create a prototype entry for a certain type
        /// </summary>
        public static Entry Prototype(EntryPrototype type, ICustomSerialization customSerialization)
        {
            Entry encoded;
            var   transformedType = TransformType(type.Prototype.GetType());

            if (transformedType != EntryValueType.Class)
            {
                var value     = type.Prototype.ToString();
                var valueType = type.Prototype.GetType();
                encoded = new Entry
                {
                    DisplayName = valueType.Name,
                    Identifier  = Entry.CreatedIdentifier,
                    Value       = new EntryValue
                    {
                        Current = value,
                        Default = value,
                        Type    = TransformType(valueType)
                    }
                };
            }
            else
            {
                encoded = EncodeObject(type.Prototype, customSerialization);
            }

            return(encoded);
        }
        /// <summary>
        /// Convert a single property into a derived type of entry using a custom strategy
        /// </summary>
        /// <returns>Converted property</returns>
        public static Entry EncodeProperty(PropertyInfo property, ICustomSerialization customSerialization)
        {
            // Fill with default if entry is null
            var entry = new Entry
            {
                DisplayName = property.GetDisplayName() ?? property.Name,
                Identifier  = property.Name,
                Description = property.GetDescription(),
                Value       = CreateEntryValue(property, customSerialization),
                Validation  = customSerialization.CreateValidation(property.PropertyType, property)
            };

            // No prototypes for readonly entries or entries without flexible sub-entries
            if (entry.Value.IsReadOnly || entry.Value.Type != EntryValueType.Collection && entry.Value.Type != EntryValueType.Class)
            {
                return(entry);
            }

            // Determine and convert prototypes
            var prototypes = Prototypes(property.PropertyType, property, customSerialization);

            entry.Prototypes.AddRange(prototypes);

            return(entry);
        }
 public HttpClientWrapper(
     HttpClient httpClient,
     ICustomSerialization customSerialization)
 {
     HttpClient          = httpClient ?? throw new ArgumentNullException(nameof(httpClient));
     CustomSerialization = customSerialization ?? throw new ArgumentNullException(nameof(customSerialization));
 }
        /// <summary>
        /// Create typed instance from encoded properties
        /// </summary>
        public static T CreateInstance <T>(Entry encoded, ICustomSerialization customSerialization)
            where T : class, new()
        {
            var instance = new T();

            UpdateInstance(instance, encoded, customSerialization);
            return(instance);
        }
 public ArrayIListStrategy(IList list, ICustomSerialization customSerialization,
                           ICustomAttributeProvider attributeProvider, object instance)
 {
     _list = list;
     _customSerialization = customSerialization;
     _property            = attributeProvider;
     _instance            = instance;
 }
Beispiel #8
0
        /// <summary>
        /// Create entry for object from collection
        /// </summary>
        public static Entry CreateSub(object item, int index, ICustomSerialization customSerialization)
        {
            var subEntry = EntryConvert.EncodeObject(item, customSerialization);

            subEntry.DisplayName = GetEntryName(item);
            subEntry.Identifier  = index.ToString("D");

            return(subEntry);
        }
        /// <summary>
        /// Update existing object from encoded values
        /// </summary>
        public static object UpdateInstance(object instance, Entry encoded, ICustomSerialization customSerialization)
        {
            var filtered = customSerialization.WriteFilter(instance.GetType(), encoded.SubEntries);

            foreach (var mapped in filtered)
            {
                var property            = mapped.Property;
                var propertyType        = mapped.Property.PropertyType;
                var doNotUpdateProperty = false;

                // Do not operate on faulty properties or read-only properties
                // For security reasons read the flag from the property again
                if (mapped.Entry?.Value.Type == EntryValueType.Exception || property.GetCustomAttribute <ReadOnlyAttribute>()?.IsReadOnly == true)
                {
                    continue;
                }

                // Try to assign value to the property
                var currentValue = mapped.Property.GetValue(instance);
                var value        = mapped.Entry == null
                    ? customSerialization.DefaultValue(property, currentValue)
                    : customSerialization.ConvertValue(propertyType, property, mapped.Entry, currentValue);

                // Value types, strings and streams do not need recursion
                if (ValueOrStringType(propertyType) || typeof(Stream).IsAssignableFrom(propertyType))
                {
                }
                // Update collection from entry
                else if (IsCollection(propertyType) && mapped.Entry != null)
                {
                    // Pick collection strategy
                    var strategy = CreateStrategy(value, currentValue, propertyType, customSerialization, mapped.Property, instance);
                    UpdateCollection(currentValue, mapped.Property.PropertyType, mapped.Property, mapped.Entry, strategy, customSerialization);
                    if (strategy is ArrayIListStrategy)
                    {
                        doNotUpdateProperty = true;
                    }
                }
                // Update class
                else if (propertyType.IsClass)
                {
                    UpdateInstance(value, mapped.Entry ?? new Entry(), customSerialization);
                }
                else
                {
                    throw new SerializationException($"Unsupported property {property.Name} on {instance.GetType().Name}!");
                }

                // Write new value to property
                if (property.CanWrite && !doNotUpdateProperty)
                {
                    mapped.Property.SetValue(instance, value);
                }
            }

            return(instance);
        }
        /// <summary>
        /// Invoke a method on the target object using custom customSerialization
        /// </summary>
        public static Entry InvokeMethod(object target, MethodEntry methodEntry, ICustomSerialization customSerialization)
        {
            var method = target.GetType().GetMethods()
                         .First(m => m.Name == methodEntry.Name && ParametersProvided(m.GetParameters(), methodEntry));
            var arguments = ConvertArguments(method, methodEntry, customSerialization);

            var result = method.Invoke(target, arguments);

            return(result == null ? null : EncodeObject(result, customSerialization));
        }
        /// <summary>
        /// Update or fill the collection using the mapping entry
        /// </summary>
        private static void UpdateCollection(object currentValue, Type memberType, ICustomAttributeProvider attributeProvider, Entry rootEntry,
                                             ICollectionStrategy strategy, ICustomSerialization customSerialization)
        {
            var currentCollection = currentValue as ICollection;

            // Loop over the collection and update the entries that are still present
            if (currentCollection != null)
            {
                foreach (var key in strategy.Keys())
                {
                    var item  = strategy.ElementAt(key);
                    var match = rootEntry.SubEntries.Find(se => se.Identifier == key);
                    if (match == null)
                    {
                        strategy.Removed(key);
                        continue;
                    }

                    if (match.Value.Type < EntryValueType.Class)
                    {
                        item = CreatePrimitiveOrEnum(memberType, match.Value, customSerialization.FormatProvider);
                    }
                    else
                    {
                        UpdateInstance(item, match, customSerialization);
                    }
                    strategy.Updated(match, item);
                }
            }

            // Add new entries to the collection
            foreach (var subEntry in rootEntry.SubEntries.Where(se => se.Identifier == Entry.CreatedIdentifier))
            {
                object item;
                // All value types
                if (subEntry.Value.Type < EntryValueType.Class)
                {
                    // Create value type
                    item = CreatePrimitiveOrEnum(memberType, subEntry.Value, customSerialization.FormatProvider);
                }
                else
                {
                    // Create and update reference types
                    item = customSerialization.CreateInstance(memberType, attributeProvider, subEntry);
                    item = UpdateInstance(item, subEntry, customSerialization);
                }
                strategy.Added(subEntry, item);
            }

            // Finalize all operations
            strategy.Flush();
        }
Beispiel #12
0
 public void Serialize(Stream stream, BinaryWriter writer)
 {
     writer.Write(m_customSerializationAssets.Count);
     for (int i = 0; i < m_customSerializationAssets.Count; ++i)
     {
         ICustomSerialization asset = m_customSerializationAssets[i];
         writer.Write(asset.AllowStandardSerialization);
         writer.Write(m_customSerializationAssetIndices[i]);
         writer.Write(m_typeMap.ToGuid(asset.GetType()).ToByteArray());
         asset.Serialize(stream, writer);
     }
     m_customSerializationAssets       = null;
     m_customSerializationAssetIndices = null;
 }
        /// <see cref="ICustomSerialization"/>
        private static EntryValue CreateEntryValue(PropertyInfo property, ICustomSerialization customSerialization)
        {
            // Set if the current entry is readonly by checking if the property has a setter
            // or the ReadOnlyAttribute was set to true
            var isReadOnly = !property.CanWrite;

            if (!isReadOnly)
            {
                var readOnlyAtt = property.GetCustomAttribute <ReadOnlyAttribute>();
                isReadOnly = readOnlyAtt?.IsReadOnly ?? false;
            }

            // Prepare object
            var entryValue = new EntryValue
            {
                Type       = TransformType(property.PropertyType),
                UnitType   = customSerialization.GetUnitTypeByAttributes(property),
                IsReadOnly = isReadOnly,
                Possible   = customSerialization.PossibleValues(property.PropertyType, property)
            };

            // Get most basic default
            var defaultAttribute = property.GetCustomAttribute <DefaultValueAttribute>();

            if (defaultAttribute != null)
            {
                entryValue.Default = defaultAttribute.Value.ToString();
            }
            else if (entryValue.Possible != null && entryValue.Possible.Length >= 1)
            {
                entryValue.Default = entryValue.Possible[0];
            }
            else if (property.PropertyType.IsValueType)
            {
                entryValue.Default = Activator.CreateInstance(property.PropertyType).ToString();
            }

            // Value types should have the default value as current value
            if (ValueOrStringType(property.PropertyType))
            {
                entryValue.Current = ConvertToString(entryValue.Default, customSerialization.FormatProvider);
            }

            return(entryValue);
        }
        /// <summary>
        /// Create basic <see cref="Entry"/> instance for a given object type
        /// </summary>
        private static Entry CreateFromType(Type objectType, ICustomSerialization serialization)
        {
            var entry = new Entry
            {
                DisplayName = objectType.GetDisplayName() ?? objectType.Name,
                Identifier  = objectType.Name,
                Value       = new EntryValue
                {
                    Current = objectType.Name,
                    Default = objectType.Name,
                    Type    = TransformType(objectType)
                },
                Validation  = serialization.CreateValidation(objectType, objectType),
                Description = objectType.GetDescription()
            };

            return(entry);
        }
 /// <summary>
 /// Encode a <see cref="MethodBase"/> to the transmittable <see cref="MethodEntry"/>
 /// </summary>
 public static MethodEntry EncodeMethod(MethodBase method, ICustomSerialization serialization)
 {
     return(new MethodEntry
     {
         Name = method.Name,
         IsConstructor = method.IsConstructor,
         DisplayName = method.GetDisplayName() ?? method.Name,
         Description = method.GetDescription(),
         Parameters = new Entry
         {
             DisplayName = "Root",
             Identifier = "Root",
             Value = new EntryValue {
                 Type = EntryValueType.Class
             },
             SubEntries = method.GetParameters().Select(p => ConvertParameter(p, serialization)).ToList()
         }
     });
 }
        /// <summary>
        /// Checks if resource and model are equal
        /// </summary>
        /// <param name="resource"></param>
        /// <param name="serialization"></param>
        /// <returns></returns>
        internal bool DifferentFrom(Resource resource, ICustomSerialization serialization)
        {
            // Do not compare values that were not transmitted
            if (resource.Descriptor == null || PartiallyLoaded)
            {
                return(false);
            }

            // Compare obvious base properties
            var different = resource.Name != Name || resource.Description != Description;

            if (different)
            {
                return(true);
            }

            var resourceProperties = EntryConvert.EncodeObject(resource.Descriptor, serialization);

            return(!Entry.ValuesEqual(Properties, resourceProperties));
        }
Beispiel #17
0
        /// <summary>
        /// Convert a single property into a derived type of entry using a custom strategy
        /// </summary>
        /// <returns>Covnerted property</returns>
        public static Entry EncodeProperty(PropertyInfo property, ICustomSerialization customSerialization)
        {
            // Fill with default if entry is null
            var entry = new Entry
            {
                DisplayName = property.GetDisplayName() ?? property.Name,
                Identifier  = property.Name,
                Description = property.GetDescription(),
                Value       = CreateEntryValue(property, customSerialization),
                Validation  = customSerialization.CreateValidation(property.PropertyType, property)
            };

            // Include prototypes for collections and classes
            if (entry.Value.Type == EntryValueType.Collection || entry.Value.Type == EntryValueType.Class)
            {
                var prototypes = Prototypes(property.PropertyType, property, customSerialization);
                entry.Prototypes.AddRange(prototypes);
            }

            return(entry);
        }
        /// <summary>
        /// Convert a method parameter to our standard <see cref="Entry"/> format
        /// </summary>
        private static Entry ConvertParameter(ParameterInfo parameter, ICustomSerialization serialization)
        {
            var parameterType = parameter.ParameterType;
            var defaultValue  = parameter.HasDefaultValue ? parameter.DefaultValue.ToString() : null;

            var parameterModel = new Entry
            {
                DisplayName = parameter.GetDisplayName() ?? parameter.Name,
                Identifier  = parameter.Name,
                Description = parameter.GetDescription(),
                Value       = new EntryValue
                {
                    Type     = TransformType(parameter.ParameterType),
                    UnitType = serialization.GetUnitTypeByAttributes(parameter),
                    Current  = defaultValue,
                    Default  = defaultValue,
                    Possible = serialization.PossibleValues(parameterType, parameter)
                },
                Validation = serialization.CreateValidation(parameterType, parameter)
            };

            switch (parameterModel.Value.Type)
            {
            case EntryValueType.Class:
                parameterModel.Value.Current = parameterType.Name;
                parameterModel.Prototypes.AddRange(Prototypes(parameterType, parameter, serialization));
                parameterModel.SubEntries = EncodeClass(parameterType, serialization).SubEntries;
                break;

            case EntryValueType.Collection:
                var elemType = ElementType(parameterType);
                parameterModel.Value.Current = elemType.Name;
                parameterModel.Prototypes.AddRange(Prototypes(parameterType, parameter, serialization));
                break;
            }

            return(parameterModel);
        }
Beispiel #19
0
        private static byte[] serializeObject(Object o)
        {
            byte[] result     = null;
            byte[] serialized = null;

            if (o is ICustomSerialization)
            {
                ICustomSerialization serializable = o as ICustomSerialization;
                serialized = serializable.toByteArray();
            }
            else
            {
                serialized = Converter.ObjectToByteArray(o);
            }


            int length = serialized.Length;

            byte[] lenArr = Converter.toByteArray(length);
            result = Combine(lenArr, serialized);

            return(result);
        }
Beispiel #20
0
        public void OnBeforeSerialization()
        {
            if (!RTSLSettings.IsCustomSerializationEnabled)
            {
                return;
            }
            m_customSerializationAssets       = new List <ICustomSerialization>();
            m_customSerializationAssetIndices = new List <int>();

            for (int i = 0; i < Assets.Length; ++i)
            {
                ICustomSerialization asset = Assets[i] as ICustomSerialization;
                if (asset != null)
                {
                    m_customSerializationAssets.Add(asset);
                    m_customSerializationAssetIndices.Add(i);
                    if (!asset.AllowStandardSerialization)
                    {
                        Assets[i] = null;
                    }
                }
            }
        }
 public ArrayStrategy(Array array, Array currentArray, ICustomSerialization serialization)
 {
     _array         = array;
     _currentArray  = currentArray;
     _serialization = serialization;
 }
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="resourceGraph"></param>
 /// <param name="serialization"></param>
 public ModelToResourceConverter(IResourceGraph resourceGraph, ICustomSerialization serialization)
 {
     _resourceGraph = resourceGraph;
     _serialization = serialization;
 }
        /// <summary>
        /// Convert encoded parameters to argument array for method invocation
        /// </summary>
        private static object[] ConvertArguments(MethodBase method, MethodEntry encodedMethod, ICustomSerialization customSerialization)
        {
            var parameters       = method.GetParameters();
            var arguments        = new object[parameters.Length];
            var parameterEntries = encodedMethod.Parameters.SubEntries;

            for (var i = 0; i < parameters.Length; i++)
            {
                var entry     = parameterEntries[i];
                var parameter = parameters[i];
                var paramType = parameter.ParameterType;
                var argument  = customSerialization.ConvertValue(paramType, parameter, entry, null);

                // Value types and strings do not need recursion
                if (ValueOrStringType(paramType))
                {
                }
                // Update collection from entry
                else if (argument is ICollection && entry != null)
                {
                    // Pick collection strategy
                    var strategy = CreateStrategy(argument, null, paramType, customSerialization);
                    UpdateCollection(null, paramType, parameter, entry, strategy, customSerialization);
                }
                // Update class
                else if (paramType.IsClass)
                {
                    if (entry == null)
                    {
                        UpdateInstance(argument, new Entry(), customSerialization);
                    }
                    else
                    {
                        UpdateInstance(argument, entry, customSerialization);
                    }
                }

                arguments[i] = argument;
            }

            return(arguments);
        }
        /// <summary>
        /// Encode all methods of a type using a custom customSerialization
        /// </summary>
        public static IEnumerable <MethodEntry> EncodeMethods(Type objType, ICustomSerialization serialization)
        {
            var methods = serialization.GetMethods(objType);

            return(methods.Select(m => EncodeMethod(m, serialization)));
        }
        /// <summary>
        /// Encode all constructors of a class
        /// </summary>
        public static IEnumerable <MethodEntry> EncodeConstructors(Type objType, ICustomSerialization serialization)
        {
            var constructors = objType.GetConstructors();

            return(constructors.Select(c => EncodeMethod(c, serialization)));
        }
Beispiel #26
0
        public void SerializeResponse(XmlWriter writer, object value, XRoadMessage message, XmlReader requestReader, ICustomSerialization customSerialization = null)
        {
            var containsRequest = requestReader.MoveToElement(2, OperationDefinition.Name);

            if (containsRequest)
            {
                writer.WriteStartElement(requestReader.Prefix, $"{OperationDefinition.Name.LocalName}Response", OperationDefinition.Name.NamespaceName);
            }
            else
            {
                writer.WriteStartElement($"{OperationDefinition.Name.LocalName}Response", OperationDefinition.Name.NamespaceName);
            }

            writer.WriteEndElement();
        }
 public ResourceQueryConverter(IResourceTypeTree typeController, ICustomSerialization serialization, ResourceQuery query) : base(typeController, serialization)
 {
     Query = query;
 }
        /// <summary>
        /// Create object instance from config model using entry for specialized types
        /// </summary>
        public static object CreateInstance(Type type, Entry encoded, ICustomSerialization customSerialization)
        {
            var instance = customSerialization.CreateInstance(type, encoded);

            return(UpdateInstance(instance, encoded, customSerialization));
        }
Beispiel #29
0
        /// <summary>
        /// Serializes `listMethods` response.
        /// </summary>
        public void SerializeResponse(XmlWriter writer, object value, XRoadMessage message, XmlReader requestReader, ICustomSerialization customSerialization = null)
        {
            var containsRequest = requestReader.MoveToElement(2, OperationDefinition.Name.LocalName, OperationDefinition.Name.NamespaceName);

            if (containsRequest)
            {
                writer.WriteStartElement(requestReader.Prefix, $"{OperationDefinition.Name.LocalName}Response", OperationDefinition.Name.NamespaceName);
            }
            else
            {
                writer.WriteStartElement($"{OperationDefinition.Name.LocalName}Response", OperationDefinition.Name.NamespaceName);
            }

            var namespaceInContext = requestReader.NamespaceURI;

            var responsePartName = OperationDefinition.Name.NamespaceName.Equals(NamespaceConstants.XTEE) ? "keha" : "response";
            var style            = OperationDefinition.Name.NamespaceName.Equals(NamespaceConstants.XTEE) ? (Style) new RpcEncodedStyle() : new DocLiteralStyle();

            if (Equals(namespaceInContext, ""))
            {
                writer.WriteStartElement(responsePartName);
            }
            else
            {
                writer.WriteStartElement(responsePartName, "");
            }

            var typeName    = XName.Get("string", NamespaceConstants.XSD);
            var methodNames = value as ICollection <string> ?? new string[0];

            style.WriteExplicitArrayType(writer, typeName, methodNames.Count);

            foreach (var methodName in methodNames)
            {
                writer.WriteStartElement("item");
                style.WriteExplicitType(writer, typeName);
                writer.WriteString(methodName);
                writer.WriteEndElement();
            }

            writer.WriteEndElement();
            writer.WriteEndElement();
        }
        /// <summary>
        /// Create object instance from config model using entry for specialized types
        /// </summary>
        public static object CreateInstance(Type type, MethodEntry encodedConstructor, ICustomSerialization customSerialization)
        {
            // Retrieve the most specific constructor matched by the encoded method entry
            var constructor = (from ctor in type.GetConstructors()
                               let parameters = ctor.GetParameters()
                                                where parameters.Length == encodedConstructor.Parameters.SubEntries.Count &&
                                                ParametersProvided(parameters, encodedConstructor)
                                                select ctor).First();
            var arguments = ConvertArguments(constructor, encodedConstructor, customSerialization);
            var instance  = constructor.Invoke(arguments);

            return(instance);
        }