internal protected override object OnDeserialize(SerializationContext serCtx, object mdata, DataNode data)
        {
            DataCollection items = ((DataItem)data).ItemData;
            object         position;
            object         collectionInstance = handler.CreateCollection(out position, items.Count);

            Deserialize(serCtx, mdata, items, collectionInstance, position);
            return(collectionInstance);
        }
Exemple #2
0
        void Deserialize(SerializationContext serCtx, object obj, DataCollection itemData, DataItem ukwnDataRoot, string baseName)
        {
            Hashtable expandedCollections = null;

            foreach (DataNode value in itemData)
            {
                ItemProperty prop = (ItemProperty)properties [baseName + value.Name];
                if (prop == null)
                {
                    if (value is DataItem)
                    {
                        DataItem root = new DataItem();
                        root.Name        = value.Name;
                        root.UniqueNames = ((DataItem)value).UniqueNames;
                        if (ukwnDataRoot != null)
                        {
                            ukwnDataRoot.ItemData.Add(root);
                        }
                        Deserialize(serCtx, obj, ((DataItem)value).ItemData, root, baseName + value.Name + "/");

                        // If no unknown data has been added, there is no need to keep this
                        // in the unknown items list.
                        if (ukwnDataRoot != null && !root.HasItemData)
                        {
                            ukwnDataRoot.ItemData.Remove(root);
                        }
                    }
                    else if (obj is IExtendedDataItem && (value.Name != "ctype" || baseName.Length > 0))
                    {
                        // store unreadable raw data to a special property so it can be
                        // serialized back an the original format is kept
                        // The ctype attribute don't need to be stored for the root object, since
                        // it is generated by the serializer
                        ukwnDataRoot.ItemData.Add(value);
                    }
                    continue;
                }
                if (prop.WriteOnly || !prop.CanDeserialize(serCtx, obj))
                {
                    continue;
                }

                try
                {
                    if (prop.ExpandedCollection)
                    {
                        ICollectionHandler handler = prop.ExpandedCollectionHandler;
                        if (expandedCollections == null)
                        {
                            expandedCollections = new Hashtable();
                        }

                        object pos, col;
                        if (!expandedCollections.ContainsKey(prop))
                        {
                            col = handler.CreateCollection(out pos, -1);
                        }
                        else
                        {
                            pos = expandedCollections [prop];
                            col = prop.GetValue(obj);
                        }
                        handler.AddItem(ref col, ref pos, prop.Deserialize(serCtx, obj, value));
                        expandedCollections [prop] = pos;
                        prop.SetValue(obj, col);
                    }
                    else
                    {
                        if (prop.HasSetter && prop.DataType.CanCreateInstance)
                        {
                            prop.SetValue(obj, prop.Deserialize(serCtx, obj, value));
                        }
                        else if (prop.DataType.CanReuseInstance)
                        {
                            object pval = prop.GetValue(obj);
                            if (pval == null)
                            {
                                if (prop.HasSetter)
                                {
                                    throw new InvalidOperationException("The property '" + prop.Name + "' is null and a new instance of '" + prop.PropertyType + "' can't be created.");
                                }
                                else
                                {
                                    throw new InvalidOperationException("The property '" + prop.Name + "' is null and it does not have a setter.");
                                }
                            }
                            prop.Deserialize(serCtx, obj, value, pval);
                        }
                        else
                        {
                            throw new InvalidOperationException("The property does not have a setter.");
                        }
                    }
                }
                catch (Exception ex)
                {
                    throw new InvalidOperationException("Could not set property '" + prop.Name + "' in type '" + Name + "'", ex);
                }
            }
        }