private static IEnumerable <string> GetTagsValue(this IProperty property, TagsStorageType storageType, IJsonSerializer serializer, char delimiter, string?culture = null)
    {
        if (property == null)
        {
            throw new ArgumentNullException(nameof(property));
        }

        var value = property.GetValue(culture)?.ToString();

        if (string.IsNullOrWhiteSpace(value))
        {
            return(Enumerable.Empty <string>());
        }

        switch (storageType)
        {
        case TagsStorageType.Csv:
            return(value.Split(new[] { delimiter }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()));

        case TagsStorageType.Json:
            try
            {
                return(serializer.Deserialize <string[]>(value)?.Select(x => x.Trim()) ?? Enumerable.Empty <string>());
            }
            catch (Exception)
            {
                // cannot parse, malformed
                return(Enumerable.Empty <string>());
            }

        default:
            throw new NotSupportedException($"Value \"{storageType}\" is not a valid TagsStorageType.");
        }
    }
    /// <summary>
    ///     Sets tags on a content property, based on the property editor tags configuration.
    /// </summary>
    /// <param name="property">The property.</param>
    /// <param name="serializer"></param>
    /// <param name="value">The property value.</param>
    /// <param name="tagConfiguration">The datatype configuration.</param>
    /// <param name="culture">A culture, for multi-lingual properties.</param>
    /// <remarks>
    ///     <para>The value is either a string (delimited string) or an enumeration of strings (tag list).</para>
    ///     <para>
    ///         This is used both by the content repositories to initialize a property with some tag values, and by the
    ///         content controllers to update a property with values received from the property editor.
    ///     </para>
    /// </remarks>
    public static void SetTagsValue(this IProperty property, IJsonSerializer serializer, object?value, TagConfiguration?tagConfiguration, string?culture)
    {
        if (property == null)
        {
            throw new ArgumentNullException(nameof(property));
        }

        if (tagConfiguration == null)
        {
            throw new ArgumentNullException(nameof(tagConfiguration));
        }

        TagsStorageType storageType = tagConfiguration.StorageType;
        var             delimiter   = tagConfiguration.Delimiter;

        SetTagsValue(property, value, storageType, serializer, delimiter, culture);
    }
    // assumes that parameters are consistent with the datatype configuration
    // value can be an enumeration of string, or a serialized value using storageType format
    private static void SetTagsValue(IProperty property, object?value, TagsStorageType storageType, IJsonSerializer serializer, char delimiter, string?culture)
    {
        if (value == null)
        {
            value = Enumerable.Empty <string>();
        }

        // if value is already an enumeration of strings, just use it
        if (value is IEnumerable <string> tags1)
        {
            property.AssignTags(tags1, false, storageType, serializer, delimiter, culture);
            return;
        }

        // otherwise, deserialize value based upon storage type
        switch (storageType)
        {
        case TagsStorageType.Csv:
            var tags2 = value.ToString() !.Split(new[] { delimiter }, StringSplitOptions.RemoveEmptyEntries);
            property.AssignTags(tags2, false, storageType, serializer, delimiter, culture);
            break;

        case TagsStorageType.Json:
            try
            {
                IEnumerable <string>?tags3 = serializer.Deserialize <IEnumerable <string> >(value.ToString() !);
                property.AssignTags(tags3 ?? Enumerable.Empty <string>(), false, storageType, serializer, delimiter, culture);
            }
            catch (Exception ex)
            {
                StaticApplicationLogging.Logger.LogWarning(
                    ex,
                    "Could not automatically convert stored json value to an enumerable string '{Json}'",
                    value.ToString());
            }

            break;

        default:
            throw new ArgumentOutOfRangeException(nameof(storageType));
        }
    }
    // assumes that parameters are consistent with the datatype configuration
    private static void RemoveTags(this IProperty property, IEnumerable <string> tags, TagsStorageType storageType, IJsonSerializer serializer, char delimiter, string?culture)
    {
        // already empty = nothing to do
        var value = property.GetValue(culture)?.ToString();

        if (string.IsNullOrWhiteSpace(value))
        {
            return;
        }

        // set the property value
        var trimmedTags = tags.Select(x => x.Trim()).ToArray();
        IEnumerable <string> currentTags = property.GetTagsValue(storageType, serializer, delimiter, culture);

        switch (storageType)
        {
        case TagsStorageType.Csv:
            property.SetValue(
                string.Join(delimiter.ToString(), currentTags.Except(trimmedTags)).NullOrWhiteSpaceAsNull(),
                culture);     // csv string
            break;

        case TagsStorageType.Json:
            var updatedTags  = currentTags.Except(trimmedTags).ToArray();
            var updatedValue = updatedTags.Length == 0 ? null : serializer.Serialize(updatedTags);
            property.SetValue(updatedValue, culture);     // json array
            break;
        }
    }
    // assumes that parameters are consistent with the datatype configuration
    private static void AssignTags(this IProperty property, IEnumerable <string> tags, bool merge, TagsStorageType storageType, IJsonSerializer serializer, char delimiter, string?culture)
    {
        // set the property value
        var trimmedTags = tags.Select(x => x.Trim()).ToArray();

        if (merge)
        {
            IEnumerable <string> currentTags = property.GetTagsValue(storageType, serializer, delimiter);

            switch (storageType)
            {
            case TagsStorageType.Csv:
                property.SetValue(
                    string.Join(delimiter.ToString(), currentTags.Union(trimmedTags)).NullOrWhiteSpaceAsNull(),
                    culture);     // csv string
                break;

            case TagsStorageType.Json:
                var updatedTags  = currentTags.Union(trimmedTags).ToArray();
                var updatedValue = updatedTags.Length == 0 ? null : serializer.Serialize(updatedTags);
                property.SetValue(updatedValue, culture);     // json array
                break;
            }
        }
        else
        {
            switch (storageType)
            {
            case TagsStorageType.Csv:
                property.SetValue(
                    string.Join(delimiter.ToString(), trimmedTags).NullOrWhiteSpaceAsNull(),
                    culture);     // csv string
                break;

            case TagsStorageType.Json:
                var updatedValue = trimmedTags.Length == 0 ? null : serializer.Serialize(trimmedTags);
                property.SetValue(updatedValue, culture);     // json array
                break;
            }
        }
    }
Esempio n. 6
0
 /// <summary>
 /// Make new tag
 /// </summary>
 /// <param name="name"></param>
 /// <param name="tagType"></param>
 public TagsStorage(string name, TagsStorageType tagType)
 {
     this.tagType = tagType;
     // Set tag name
     this.name = name;
 }
        // assumes that parameters are consistent with the datatype configuration
        private static void AssignTags(this Property property, IEnumerable <string> tags, bool merge, TagsStorageType storageType, char delimiter, string culture)
        {
            // set the property value
            var trimmedTags = tags.Select(x => x.Trim()).ToArray();

            if (merge)
            {
                var currentTags = property.GetTagsValue(storageType, delimiter);

                switch (storageType)
                {
                case TagsStorageType.Csv:
                    property.SetValue(string.Join(delimiter.ToString(), currentTags.Union(trimmedTags)), culture);     // csv string
                    break;

                case TagsStorageType.Json:
                    property.SetValue(JsonConvert.SerializeObject(currentTags.Union(trimmedTags).ToArray()), culture);     // json array
                    break;
                }
            }
            else
            {
                switch (storageType)
                {
                case TagsStorageType.Csv:
                    property.SetValue(string.Join(delimiter.ToString(), trimmedTags), culture);     // csv string
                    break;

                case TagsStorageType.Json:
                    property.SetValue(JsonConvert.SerializeObject(trimmedTags), culture);     // json array
                    break;
                }
            }
        }
        // assumes that parameters are consistent with the datatype configuration
        private static void RemoveTags(this Property property, IEnumerable <string> tags, TagsStorageType storageType, char delimiter, string culture)
        {
            // already empty = nothing to do
            var value = property.GetValue(culture)?.ToString();

            if (string.IsNullOrWhiteSpace(value))
            {
                return;
            }

            // set the property value
            var trimmedTags = tags.Select(x => x.Trim()).ToArray();
            var currentTags = property.GetTagsValue(storageType, delimiter, culture);

            switch (storageType)
            {
            case TagsStorageType.Csv:
                property.SetValue(string.Join(delimiter.ToString(), currentTags.Except(trimmedTags)), culture);     // csv string
                break;

            case TagsStorageType.Json:
                property.SetValue(JsonConvert.SerializeObject(currentTags.Except(trimmedTags).ToArray()), culture);     // json array
                break;
            }
        }
Esempio n. 9
0
 /// <summary>
 /// Make new tag
 /// </summary>
 /// <param name="name"></param>
 /// <param name="tagType"></param>
 public TagsStorage(string name, TagsStorageType tagType)
 {
     this.tagType = tagType;
     // Set tag name
     this.name = name;
 }