namespace Umbraco.Cms.Core; /// /// Represents a range. /// /// /// /// A Udi range is composed of a which represents the base of the range, /// plus a selector that can be "." (the Udi), ".*" (the Udi and its children), ".**" (the udi and /// its descendants, "*" (the children of the Udi), and "**" (the descendants of the Udi). /// /// The Udi here can be a closed entity, or an open entity. /// public class UdiRange { private readonly Uri _uriValue; /// /// Initializes a new instance of the class with a and an optional /// selector. /// /// A . /// An optional selector. public UdiRange(Udi udi, string selector = Constants.DeploySelector.This) { Udi = udi; switch (selector) { case Constants.DeploySelector.This: Selector = selector; _uriValue = udi.UriValue; break; case Constants.DeploySelector.ChildrenOfThis: case Constants.DeploySelector.DescendantsOfThis: case Constants.DeploySelector.ThisAndChildren: case Constants.DeploySelector.ThisAndDescendants: case Constants.DeploySelector.EntitiesOfType: Selector = selector; _uriValue = new Uri(Udi + "?" + selector); break; default: throw new ArgumentException(string.Format("Invalid selector \"{0}\".", selector)); } } /// /// Gets the for this range. /// public Udi Udi { get; } /// /// Gets or sets the selector for this range. /// public string Selector { get; } /// /// Gets the entity type of the for this range. /// public string EntityType => Udi.EntityType; public static bool operator ==(UdiRange? range1, UdiRange? range2) { if (ReferenceEquals(range1, range2)) { return true; } if (range1 is null || range2 is null) { return false; } return range1.Equals(range2); } public static bool operator !=(UdiRange range1, UdiRange range2) => !(range1 == range2); public static UdiRange Parse(string value) { if (Uri.TryCreate(value, UriKind.Absolute, out Uri? uri) is false || uri.IsWellFormedOriginalString() is false) { throw new FormatException($"String \"{value}\" is not a valid UDI range."); } // Remove selector from UDI Uri udiUri = string.IsNullOrEmpty(uri.Query) ? uri : new UriBuilder(uri) { Query = string.Empty }.Uri; var udi = Udi.Create(udiUri); // Only specify selector if query string is not empty return string.IsNullOrEmpty(uri.Query) ? new UdiRange(udi) : new UdiRange(udi, uri.Query.TrimStart(Constants.CharArrays.QuestionMark)); } public override string ToString() => _uriValue.ToString(); public override bool Equals(object? obj) => obj is UdiRange other && GetType() == other.GetType() && _uriValue == other._uriValue; public override int GetHashCode() => _uriValue.GetHashCode(); }