private Contracts.Entity ToContract()
        {
            var obj = new Contracts.Entity
            {
                Id           = Id,
                Type         = ToString(Type),
                Labels       = ToContract(_Labels),
                Aliases      = ToContract(_Aliases),
                Descriptions = ToContract(_Descriptions),
                Sitelinks    = SiteLinks.ToDictionary(link => link.Site,
                                                      link => new Contracts.SiteLink {
                    Site = link.Site, Title = link.Title, Badges = link.Badges.ToList()
                }),
                Claims = Claims.GroupBy(c => c.MainSnak.PropertyId).ToDictionary(g => g.Key,
                                                                                 g => (ICollection <Contracts.Claim>)g.Select(c => c.ToContract(false)).ToList())
            };

            return(obj);
        }
        internal static SerializableEntity Load(Contracts.Entity entity)
        {
            // If caller deserializes entity from EOF-ed stream, the caller can get null.
            if (entity == null)
            {
                return(null);
            }
            var inst = new SerializableEntity(false)
            {
                Id   = entity.Id,
                Type = ParseEntityType(entity.Type)
            };

            if (entity.DataType != null)
            {
                inst.DataType = BuiltInDataTypes.Get(entity.DataType) ?? MissingPropertyType.Get(entity.DataType, entity.DataType);
            }
            inst.Labels = new WbMonolingualTextCollection(
                entity.Labels?.Values.Select(v => new WbMonolingualText(v.Language, v.Value))
                ?? Enumerable.Empty <WbMonolingualText>());
            inst.Descriptions = new WbMonolingualTextCollection(
                entity.Descriptions?.Values.Select(v => new WbMonolingualText(v.Language, v.Value))
                ?? Enumerable.Empty <WbMonolingualText>());
            inst.Aliases = new WbMonolingualTextsCollection(
                entity.Aliases?.Values.SelectMany(vs => vs).Select(v => new WbMonolingualText(v.Language, v.Value))
                ?? Enumerable.Empty <WbMonolingualText>());
            inst.SiteLinks = new EntitySiteLinkCollection(
                entity.Sitelinks?.Values.Select(v => new EntitySiteLink(v.Site, v.Title,
                                                                        new ReadOnlyCollection <string>(v.Badges)))
                ?? Enumerable.Empty <EntitySiteLink>());
            if (entity.Claims == null || entity.Claims.Count == 0)
            {
                inst.Claims = new ClaimCollection();
            }
            else
            {
                // { claims : { P47 : [ {}, {}, ... ], P105 : ... } }
                inst.Claims = new ClaimCollection(entity.Claims.Values.SelectMany(c => c).Select(Claim.FromContract));
            }
            return(inst);
        }
        private Contracts.Entity SerializeEditEntries(IEnumerable <EntityEditEntry> edits)
        {
            if (edits == null)
            {
                throw new ArgumentNullException(nameof(edits));
            }
            var contract = new Contracts.Entity();

            foreach (var prop in edits.GroupBy(e => e.PropertyName))
            {
                if (prop.Any(p => p.Value == null))
                {
                    throw new ArgumentException($"Detected null value in {prop} entries.", nameof(edits));
                }
                switch (prop.Key)
                {
                case nameof(DataType):
                    contract.DataType = ((WikibaseDataType)prop.Last().Value).Name;
                    break;

                case nameof(Labels):
                    contract.Labels = new Dictionary <string, Contracts.MonolingualText>();
                    foreach (var entry in prop)
                    {
                        var value = (WbMonolingualText)entry.Value;
                        var item  = entry.State == EntityEditEntryState.Removed
                                ? new Contracts.MonolingualText {
                            Language = value.Language, Remove = true
                        }
                                : new Contracts.MonolingualText {
                            Language = value.Language, Value = value.Text
                        };
                        contract.Labels.Add(value.Language, item);
                    }
                    break;

                case nameof(Descriptions):
                    contract.Descriptions = new Dictionary <string, Contracts.MonolingualText>();
                    foreach (var entry in prop)
                    {
                        var value = (WbMonolingualText)entry.Value;
                        var item  = entry.State == EntityEditEntryState.Removed
                                ? new Contracts.MonolingualText {
                            Language = value.Language, Remove = true
                        }
                                : new Contracts.MonolingualText {
                            Language = value.Language, Value = value.Text
                        };
                        contract.Descriptions.Add(value.Language, item);
                    }
                    break;

                case nameof(Aliases):
                    contract.Aliases = new Dictionary <string, ICollection <MonolingualText> >();
                    foreach (var entry in prop)
                    {
                        var value = (WbMonolingualText)entry.Value;
                        var item  = entry.State == EntityEditEntryState.Removed
                                ? new Contracts.MonolingualText {
                            Language = value.Language, Remove = true
                        }
                                : new Contracts.MonolingualText {
                            Language = value.Language, Value = value.Text
                        };
                        if (!contract.Aliases.TryGetValue(item.Language, out var items))
                        {
                            items = new List <MonolingualText>();
                            contract.Aliases.Add(item.Language, items);
                        }
                        items.Add(item);
                    }
                    break;

                case nameof(SiteLinks):
                    contract.Sitelinks = new Dictionary <string, SiteLink>();
                    foreach (var entry in prop)
                    {
                        var value = (EntitySiteLink)entry.Value;
                        var item  = entry.State == EntityEditEntryState.Removed
                                ? new Contracts.SiteLink {
                            Site = value.Site, Remove = true
                        }
                                : new Contracts.SiteLink {
                            Site = value.Site, Title = value.Title, Badges = value.Badges.ToList()
                        };
                        contract.Sitelinks.Add(value.Site, item);
                    }
                    break;

                case nameof(Claims):
                    contract.Claims = new Dictionary <string, ICollection <Contracts.Claim> >();
                    foreach (var entry in prop)
                    {
                        var             value = (Claim)entry.Value;
                        Contracts.Claim item;
                        if (entry.State == EntityEditEntryState.Removed)
                        {
                            item        = value.ToContract(true);
                            item.Remove = true;
                        }
                        else
                        {
                            item = value.ToContract(false);
                        }
                        if (!contract.Claims.TryGetValue(value.MainSnak.PropertyId, out var items))
                        {
                            items = new List <Contracts.Claim>();
                            contract.Claims.Add(value.MainSnak.PropertyId, items);
                        }
                        items.Add(item);
                    }
                    break;

                default:
                    throw new ArgumentException($"Unrecognized {nameof(Entity)} property name: {prop.Key}.");
                }
            }
            return(contract);
        }
Beispiel #4
0
        // postEditing: Is the entity param from the response of wbeditentity API call?
        internal void LoadFromContract(Contracts.Entity entity, EntityQueryOptions options, bool isPostEditing)
        {
            var extensionData = entity.ExtensionData ?? emptyExtensionData;
            var id            = entity.Id;

            Debug.Assert(id != null);
            if ((options & EntityQueryOptions.SupressRedirects) != EntityQueryOptions.SupressRedirects &&
                Id != null && Id != id)
            {
                // The page has been overwritten, or deleted.
                //logger.LogWarning("Detected change of page id for [[{Title}]]: {Id1} -> {Id2}.", Title, Id, id);
            }
            var serializable = extensionData.ContainsKey("missing")
                ? null
                : SerializableEntity.Load(entity);

            Id             = id;
            Exists         = serializable != null;
            Type           = EntityType.Unknown;
            PageId         = -1;
            NamespaceId    = -1;
            Title          = null;
            LastModified   = DateTime.MinValue;
            LastRevisionId = 0;
            Labels         = null;
            Aliases        = null;
            Descriptions   = null;
            SiteLinks      = null;
            QueryOptions   = options;
            if (serializable == null)
            {
                return;
            }
            serializable = SerializableEntity.Load(entity);
            Type         = serializable.Type;
            DataType     = serializable.DataType;
            if ((options & EntityQueryOptions.FetchInfo) == EntityQueryOptions.FetchInfo)
            {
                if (!isPostEditing)
                {
                    // wbeditentity response does not have these properties.
                    PageId       = (int)extensionData["pageid"];
                    NamespaceId  = (int)extensionData["ns"];
                    Title        = (string)extensionData["title"];
                    LastModified = (DateTime)extensionData["modified"];
                }
                LastRevisionId = (int)extensionData["lastrevid"];
            }
            if ((options & EntityQueryOptions.FetchLabels) == EntityQueryOptions.FetchLabels)
            {
                Labels = serializable.Labels;
                if (Labels.Count == 0)
                {
                    Labels = emptyStringDict;
                }
                else
                {
                    Labels.IsReadOnly = true;
                }
            }
            if ((options & EntityQueryOptions.FetchAliases) == EntityQueryOptions.FetchAliases)
            {
                Aliases = serializable.Aliases;
                if (Aliases.Count == 0)
                {
                    Aliases = emptyStringsDict;
                }
                else
                {
                    Aliases.IsReadOnly = true;
                }
            }
            if ((options & EntityQueryOptions.FetchDescriptions) == EntityQueryOptions.FetchDescriptions)
            {
                Descriptions = serializable.Descriptions;
                if (Descriptions.Count == 0)
                {
                    Descriptions = emptyStringDict;
                }
                else
                {
                    Descriptions.IsReadOnly = true;
                }
            }
            if ((options & EntityQueryOptions.FetchSiteLinks) == EntityQueryOptions.FetchSiteLinks)
            {
                SiteLinks = serializable.SiteLinks;
                if (SiteLinks.Count == 0)
                {
                    SiteLinks = emptySiteLinks;
                }
                else
                {
                    SiteLinks.IsReadOnly = true;
                }
            }
            if ((options & EntityQueryOptions.FetchClaims) == EntityQueryOptions.FetchClaims)
            {
                Claims = serializable.Claims;
                if (Claims.Count == 0)
                {
                    Claims = emptyClaims;
                }
                else
                {
                    Claims.IsReadOnly = true;
                }
            }
        }