private void Add(SharedDictionaryEntry eWithValue)
        {
            // First ensures that the plugin is registered.
            // This may throw an ArgumentException if the Guid is associated to another IVersionedUniqueId.
            PluginConfigByPlugin cp;

            if (!_byPlugin.TryGetValue(eWithValue.PluginId.UniqueId, out cp))
            {
                cp = CreatePluginConfigByPlugin(eWithValue.PluginId);
            }
            // If the entry already exists, an ArgumentException is thrown.
            // If this happens it means that the IVersionedUniqueId is already registered:
            // we do not have to clean up the plugin registration.
            _values.Add(eWithValue, eWithValue);
            // No exception: let us add into the other indices.

            cp.Add(eWithValue);

            PluginConfigByObject co;

            if (!_byObject.TryGetValue(eWithValue.Obj, out co))
            {
                co = CreatePluginConfigByObject(eWithValue.Obj);
            }
            co.Add(eWithValue);

            // Increment the final dictionary count.
            FinalDictionary d;

            if (!_finalDictionary.TryGetValue(eWithValue, out d))
            {
                d = new FinalDictionary(this, eWithValue.Obj, eWithValue.PluginId);
                _finalDictionary.Add(eWithValue, d);
            }
            d.Count++;
            if (Changed != null)
            {
                Changed(this, new ConfigChangedEventArgs(eWithValue, eWithValue, ChangeStatus.Add));
            }
        }
        internal FinalDictionary GetFinalDictionary(SharedDictionaryEntry e, bool ensure)
        {
            FinalDictionary d;

            if (!_finalDictionary.TryGetValue(e, out d))
            {
                if (ensure)
                {
                    if (!_byObject.ContainsKey(e.Obj))
                    {
                        CreatePluginConfigByObject(e.Obj);
                    }
                    d = new FinalDictionary(this, e.Obj, e.PluginId);
                    _finalDictionary.Add(e, d);
                    if (!_byPlugin.ContainsKey(e.PluginId.UniqueId))
                    {
                        CreatePluginConfigByPlugin(e.PluginId);
                    }
                }
            }
            return(d);
        }
        int WritePluginsData(object o, string elementName)
        {
            _alreadyWritten.Add(o);
            int                  writeCount     = 0;
            XmlWriter            w              = StructuredWriter.Xml;
            bool                 mustEndElement = false;
            PluginConfigByObject c;

            if (_dic.TryGetPluginConfigByObject(o, out c) && c.Count > 0)
            {
                HashSet <FinalDictionary> done = new HashSet <FinalDictionary>();
                foreach (SharedDictionaryEntry e in c)
                {
                    FinalDictionary f = _dic.GetFinalDictionary(e, false);
                    if (!done.Contains(f))
                    {
                        done.Add(f);
                        if (elementName != null)
                        {
                            w.WriteStartElement(elementName);
                            mustEndElement = true;
                            elementName    = null;
                        }
                        w.WriteStartElement("p");
                        w.WriteAttributeString("guid", e.PluginId.UniqueId.ToString());
                        w.WriteAttributeString("version", e.PluginId.Version.ToString());
                        if (e.PluginId.PublicName.Length > 0)
                        {
                            w.WriteAttributeString("name", e.PluginId.PublicName);
                        }
                        ++writeCount;

                        SharedDictionaryWriterEventArgs ev = null;
                        if (BeforePluginsData != null)
                        {
                            BeforePluginsData(this, (ev = new SharedDictionaryWriterEventArgs(this, f)));
                        }

                        f.WriteData(this);

                        if (AfterPluginsData != null)
                        {
                            AfterPluginsData(this, ev ?? new SharedDictionaryWriterEventArgs(this, f));
                        }

                        w.WriteEndElement();
                    }
                }
            }
            // Obtains the list of SkippedFragments associated to the object.
            IEnumerable <SkippedFragment> fragments = _dic.GetSkippedFragments(o);

            if (fragments != null)
            {
                foreach (SkippedFragment f in fragments)
                {
                    if (elementName != null)
                    {
                        w.WriteStartElement(elementName);
                        mustEndElement = true;
                        elementName    = null;
                    }
                    ++writeCount;
                    f.Bookmark.WriteBack(StructuredWriter);
                }
            }
            if (mustEndElement)
            {
                w.WriteEndElement();
            }
            return(writeCount);
        }
Beispiel #4
0
        public void ReadPluginsData(object o)
        {
            Guid    prevPluginId      = _currentPluginId;
            Version prevPluginVersion = _currentPluginVersion;
            string  prevPluginName    = _currentPluginName;

            try
            {
                XmlReader r = _reader.Xml;
                while (r.IsStartElement("p"))
                {
                    Guid    p = SimpleUniqueId.InvalidId.UniqueId;
                    Version v = null;
                    string  n = null;
                    try
                    {
                        p = new Guid(r.GetAttribute("guid"));
                        v = r.GetAttributeVersion("version", Util.EmptyVersion);
                        // Since the public name of the plugin is not a key data in any manner,
                        // we may use here the actual uid.PublicName but this would introduce
                        // a diff between the exposed version (which is the version form the input stream)
                        // and the public name.
                        // We prefer here to stay consistent: we expose read information for version and name.
                        n = r.GetAttribute("name") ?? String.Empty;
                        INamedVersionedUniqueId uid = _dic.FindPlugin(p);
                        if (uid != null)
                        {
                            FinalDictionary fDic = _dic.GetFinalDictionary(o, uid, true);

                            r.Read();
                            _currentPluginId      = p;
                            _currentPluginVersion = v;
                            _currentPluginName    = n;

                            SharedDictionaryReaderEventArgs ev = null;
                            if (BeforePluginsData != null)
                            {
                                BeforePluginsData(this, (ev = new SharedDictionaryReaderEventArgs(this, fDic)));
                            }

                            if (_mergeMode == MergeMode.None)
                            {
                                fDic.Clear();
                            }
                            fDic.ReadData(this);

                            if (AfterPluginsData != null)
                            {
                                AfterPluginsData(this, ev ?? new SharedDictionaryReaderEventArgs(this, fDic));
                            }

                            r.ReadEndElement();
                        }
                        else
                        {
                            _dic.StoreSkippedFragment(o, p, v, _reader.CreateBookmark());
                        }
                    }
                    catch (Exception ex)
                    {
                        if (ErrorCollector != null)
                        {
                            if (p == SimpleUniqueId.InvalidId.UniqueId)
                            {
                                ErrorCollector.Add(new ReadElementObjectInfo(ReadElementObjectInfo.ReadStatus.ErrorGuidAttributeMissing, r, ex.Message));
                            }
                            else if (v == null)
                            {
                                ErrorCollector.Add(new ReadElementObjectInfo(ReadElementObjectInfo.ReadStatus.ErrorVersionAttributeInvalid, r, ex.Message));
                            }
                            else
                            {
                                ErrorCollector.Add(new ReadElementObjectInfo(ReadElementObjectInfo.ReadStatus.ErrorXmlRead, r, ex.Message));
                            }
                        }
                        r.Skip();
                    }
                }
            }
            finally
            {
                _currentPluginId      = prevPluginId;
                _currentPluginVersion = prevPluginVersion;
                _currentPluginName    = prevPluginName;
            }
        }