示例#1
0
        /// <summary>
        /// Loads the assemblies.
        /// </summary>
        /// <param name="assemblies"> Array of the used assemblies. </param>
        private void LoadAssemblies(params Assembly[] assemblies)
        {
            Interlocked.Exchange(ref this.formatterIsLoading, 1);

            Assembly assembly;
            Type     type;

            Type[] types;
            FormattableAttribute         assemblyAttribute;
            FormattableAttribute         typeAttribute;
            FormattableType              formattableType;
            LinkedList <FormattableType> loadedTypes = new LinkedList <FormattableType>();

            int assembliesLength = assemblies.Length;
            int typesLength      = 0;

            for (int i = 0; i < assembliesLength; i++)
            {
                assembly = assemblies[i];

                if (assembly == null)
                {
                    continue;
                }

                assemblyAttribute = assembly.GetAttribute <FormattableAttribute>();

                if (assemblyAttribute == null)
                {
                    continue;
                }

                types       = assembly.GetTypes();
                typesLength = types.Length;

                for (int k = 0; k < typesLength; k++)
                {
                    type          = types[k];
                    typeAttribute = type.GetAttribute <FormattableAttribute>(false);

                    if (typeAttribute != null)
                    {
                        if (type.IsInterface || type.IsAbstract)
                        {
                            throw new AbstractTypeException(type);
                        }

                        formattableType = new FormattableType(type, typeAttribute);
                        loadedTypes.AddLast(formattableType);
                    }
                }
            }

            this.formattableTypes = loadedTypes.ToArray();

            Interlocked.Exchange(ref this.formatterIsLoading, 0);
        }
示例#2
0
        /// <summary>
        /// Tries read an entry of the data by the path and creates a new class/struct.
        /// </summary>
        /// <param name="type"> The type. </param>
        /// <param name="className"> Name of the class. </param>
        /// <param name="values"> Values of the class. </param>
        /// <param name="path"> The path. </param>
        /// <param name="storer"> The storer. </param>
        /// <param name="entries"> List of the entries of the storer. </param>
        /// <param name="references"> Dictionary that contains references to the objects. </param>
        /// <returns> Graph if graph has been created successfully, otherwise null. </returns>
        private object TryReadFormattable(string path, Type type, string className, IDictionary <string, string> values, IReadOnlyDataStorer storer, LinkedList <IDataStorerEntry> entries, Dictionary <string, object> references)
        {
            // Tries get the formattable type that is related (same) with the declared type

            FormattableType formattableType = this.formattableTypes.FindOrDefault(f => f.Name == className && f.IsRelatedType(type, false));

            if (formattableType == null)
            {
                // Tries get the formattable type that is related (not same, derived) with the declared type
                formattableType = this.formattableTypes.FindOrDefault(f => f.IsRelatedType(type, true));
            }

            if (formattableType == null)
            {
                // Formattable type is null -> type isn't supported -> returns null
                return(null);
            }

            object graph = formattableType.CreateInstance(type);

            references.Add(path, graph);

            formattableType.OnDeserializing(graph);

            // Restores the keys and values of the objects

            FormattableValue[] formattableValues = formattableType.GetValues(type);
            int length = formattableValues.Length;

            FormattableValue value     = null;
            Type             valueType = null;
            string           valueName = "";

            for (int i = 0; i < length; i++)
            {
                value     = formattableValues[i];
                valueType = value.Type;
                valueName = value.Name;

                if (this.IsPrimitive(valueType))
                {
                    // Value of the object is primitive - reads it from information file

                    Func <string, object> primitiveConverter = this.GetPrimitiveConverterToObject(valueType);

                    if (values.ContainsKey(value.Name))
                    {
                        value.SetValue(graph, primitiveConverter(values[valueName]));
                    }
                    else
                    {
                        if (!value.Optional)
                        {
                            throw new KeyCanNotLoadedException(formattableType, valueName);
                        }
                    }
                }
                else
                {
                    // Value of the object isn't primitive - reads it from special file

                    try
                    {
                        value.SetValue(graph,
                                       this.Read(
                                           value.Type,
                                           StringUtils.Combine(path, valueName, DirectorySeparatorString),
                                           storer,
                                           entries,
                                           references
                                           ));
                    }
                    catch (Exception ex)
                    {
                        // Thrown error if value isn't optional

                        if (!value.Optional)
                        {
                            throw new KeyCanNotLoadedException(formattableType, valueName, ex);
                        }
                    }
                }
            }

            formattableType.OnDeserialized(graph);

            // Makes the substitution (if required)

            object substitution = formattableType.Substitution(graph);

            if (substitution != graph)
            {
                references.Remove(path);
                references.Add(path, substitution);

                // Returns the substituted graph

                return(substitution);
            }
            else
            {
                // Returns the created graph

                return(graph);
            }
        }
示例#3
0
 /// <summary>
 /// The exception that is thrown when key can't be saved.
 /// </summary>
 /// <param name="formattableType"> Type. </param>
 /// <param name="keyName"> Name of key. </param>
 /// <param name="exception"> Exception. </param>
 public KeyCanNotSavedException(FormattableType formattableType, string keyName, Exception exception) : base("Key <{0}> in <{1}> can't be saved.", exception, keyName, formattableType.Name)
 {
 }
        /// <summary>
        /// Tries write a formattable object in the storer.
        /// </summary>
        /// <param name="graph"> Object (or graph of objects with the given root). </param>
        /// <param name="type"> Type of the object. </param>
        /// <param name="path"> The path to the file. </param>
        /// <param name="storer"> The storer. </param>
        /// <param name="references"> Dictionary that contains references to the objects. </param>
        /// <returns> True if formattable objecthas been written (or is exist), otherwise false. </returns>
        private bool TryWriteFormattable(object graph, Type type, string path, IWriteOnlyDataStorer storer, IDictionary <object, string> references)
        {
            // Gets a formattable type for the specified type

            FormattableType formattableType = this.formattableTypes.FindOrDefault(f => f.IsRelatedType(type, true));

            if (formattableType == null)
            {
                // If formattable type isn't exists -> type isn't supported -> returns false
                return(false);
            }

            // Tries write the object in the storer

            string className = formattableType.Name;

            if (this.TryWriteValue(storer, path, references, graph, className))
            {
                formattableType.OnSerializing(graph);

                FormattableValue[] formattableValues = formattableType.GetValues(type);
                FormattableValue   formattableValue;
                int    length = formattableValues.Length;
                object value;
                Type   valueType;

                IDictionary <string, string> values = new Dictionary <string, string>(length);

                for (int i = 0; i < length; i++)
                {
                    formattableValue = formattableValues[i];

                    value     = formattableValue.GetValue(graph);
                    valueType = formattableValue.Type;

                    if (this.IsPrimitive(valueType))
                    {
                        // Value of the object is primitive - writes it in the information file

                        values.Add(formattableValue.Name, this.GetPrimitiveConverterToString(valueType)(value));
                    }
                    else
                    {
                        // Value of the object isn't primitive - writes it in new file

                        try
                        {
                            // Tries write a value in the new file
                            this.Write(
                                value,
                                StringUtils.Combine(path, formattableValue.Name, DirectorySeparatorString),
                                storer,
                                references
                                );
                        }
                        catch (Exception ex)
                        {
                            // Thrown error if value isn't optional
                            if (!formattableValue.Optional)
                            {
                                throw new KeyCanNotSavedException(formattableType, formattableType.Name, ex);
                            }
                        }
                    }
                }

                formattableType.OnSerialized(graph);

                this.WriteInfo(storer, path, className, values);
            }

            return(true);
        }
示例#5
0
 /// <summary>
 /// The exception that is thrown when key can't be loaded.
 /// </summary>
 /// <param name="formattableType"> Type. </param>
 /// <param name="keyName"> Name of key. </param>
 public KeyCanNotLoadedException(FormattableType formattableType, string keyName) : base("Key <{0}> in <{1}> can't be loaded.", keyName, formattableType.Name)
 {
 }