// ========================================================================== // ContentData.cs // Squidex Headless CMS // ========================================================================== // Copyright (c) Squidex Group // All rights reserved. // ========================================================================== using System; using System.Collections.Generic; using System.Linq; using Newtonsoft.Json.Linq; using Squidex.Core.Schemas; using Squidex.Infrastructure; // ReSharper disable InvertIf namespace Squidex.Core.Contents { public abstract class ContentData : Dictionary, IEquatable> { public IEnumerable> ValidValues { get { return this.Where(x => x.Value != null); } } protected ContentData(IEqualityComparer comparer) : base(comparer) { } protected ContentData(IDictionary copy, IEqualityComparer comparer) : base(copy, comparer) { } protected static TResult Merge(TResult source, TResult target) where TResult : ContentData { if (ReferenceEquals(target, source)) { return source; } foreach (var otherValue in source) { var fieldValue = target.GetOrAdd(otherValue.Key, x => new ContentFieldData()); foreach (var value in otherValue.Value) { fieldValue[value.Key] = value.Value; } } return target; } protected static TResult Clean(TResult source, TResult target) where TResult : ContentData { foreach (var fieldValue in source.ValidValues) { var resultValue = new ContentFieldData(); foreach (var partitionValue in fieldValue.Value.Where(x => IsNotNull(x.Value))) { resultValue[partitionValue.Key] = partitionValue.Value; } if (resultValue.Count > 0) { target[fieldValue.Key] = resultValue; } } return target; } public IEnumerable GetReferencedIds(Schema schema) { Guard.NotNull(schema, nameof(schema)); var foundReferences = new HashSet(); foreach (var field in schema.Fields) { if (field is IReferenceField referenceField) { var fieldKey = GetKey(field); var fieldData = this.GetOrDefault(fieldKey); if (fieldData == null) { continue; } foreach (var partitionValue in fieldData.Where(x => x.Value != null)) { var ids = referenceField.GetReferencedIds(partitionValue.Value); foreach (var id in ids.Where(x => foundReferences.Add(x))) { yield return id; } } } } } public override bool Equals(object obj) { return Equals(obj as ContentData); } public bool Equals(ContentData other) { return other != null && (ReferenceEquals(this, other) || this.EqualsDictionary(other)); } public override int GetHashCode() { return this.DictionaryHashCode(); } protected static bool IsNull(JToken value) { return value == null || value.Type == JTokenType.Null; } protected static bool IsNotNull(JToken value) { return value != null && value.Type != JTokenType.Null; } public abstract T GetKey(Field field); } }