using System; using System.Globalization; using JD.Kernel.StaticHelpers; namespace JD.TeaBoxAddinSystem.Addins.Description { /// /// Represents a versioned reference to an . /// public sealed class AddinReference { #region Variables private readonly string m_name; private readonly Version m_minVersion; private readonly Version m_maxVersion; /// /// Cached versions /// internal readonly static Version ZeroVersion = new Version(0, 0, 0, 0); internal readonly static Version InfiniteVersion = new Version(int.MaxValue, int.MaxValue); #endregion #region Constructor /// /// Constructor. /// /// Name of the referenced addin. public AddinReference(string name) : this(name, ZeroVersion, InfiniteVersion) { } /// /// Constructor. /// /// Name of the referenced addin. /// Version of the referenced addin. public AddinReference(string name, Version specificVersion) : this(name, specificVersion, specificVersion) { } /// /// Constructor. /// /// Name of the referenced addin. /// Minimum version of the referenced addin. /// Maximum version of the referenced addin. public AddinReference(string name, Version minVersion, Version maxVersion) { Throw.IfEmpty(name, "name"); Throw.IfNull(minVersion, "minVersion"); Throw.IfNull(maxVersion, "maxVersion"); if (Compare(minVersion, maxVersion) > 0) { throw new ArgumentException("minVersion cannot be higher than maxVersion"); } m_name = name; m_minVersion = minVersion; m_maxVersion = maxVersion; } #endregion #region Properties /// /// Name of the referenced addin. /// public string Name { get { return m_name; } } /// /// The minimum version of the referenced addin. /// public Version MinimumVersion { get { return m_minVersion; } } /// /// The maximum version of the referenced addin. /// public Version MaximumVersion { get { return m_maxVersion; } } #endregion #region Methods #region Public Methods /// /// Validates that the given version is between the minimum and maximum version. /// /// Version to test /// Whether the given bersion is between the minimum and maximum version. public bool Validate(Version version) { return (Compare(m_minVersion, version) <= 0 && Compare(m_maxVersion, version) >= 0); } /// /// Checks whether this reference overlaps another reference (i.e. if A intersects B). /// /// Other reference to check /// public bool Overlaps(AddinReference reference) { if (string.Compare(this.Name, reference.Name, StringComparison.Ordinal) != 0) { return false; } return ((Compare(m_maxVersion, reference.MinimumVersion) >= 0) && (Compare(m_minVersion, reference.MaximumVersion) <= 0)); } #endregion #region Static Methods /// /// Compares two version together, ignoring unspecified fields (unlike ). /// /// /// /// -1 if a < b, 0 if a == b, 1 if a > b public static int Compare(Version a, Version b) { if (a.Major != b.Major) { return a.Major > b.Major ? 1 : -1; } if (a.Minor != b.Minor) { return a.Minor > b.Minor ? 1 : -1; } if (a.Build < 0 || b.Build < 0) return 0; if (a.Build != b.Build) { return a.Build > b.Build ? 1 : -1; } if (a.Revision < 0 || b.Revision < 0) return 0; if (a.Revision != b.Revision) { return a.Revision > b.Revision ? 1 : -1; } return 0; } #endregion #region Operator Overloading /// /// Equality Operator /// /// /// /// public static bool operator == (AddinReference a, AddinReference b) { return (object)a == null ? (object)b == null : a.Equals(b); } /// /// Inequality Operator /// /// /// /// public static bool operator !=(AddinReference a, AddinReference b) { return !(a==b); } /// /// Equals Override /// /// /// public override bool Equals(object obj) { if (object.ReferenceEquals(this, obj)) { return true; } AddinReference other = obj as AddinReference; if ((object)other == null) { return false; } return string.Equals(m_name, other.m_name) && Compare(m_minVersion, other.m_minVersion) == 0 && Compare(m_maxVersion, other.m_maxVersion) == 0; } /// /// GetHashCode Override /// /// public override int GetHashCode() { return m_name.GetHashCode() ^ m_minVersion.GetHashCode() ^ m_maxVersion.GetHashCode(); } /// /// ToString Override /// /// public override string ToString() { string version; if (MinimumVersion == ZeroVersion && MaximumVersion == InfiniteVersion) { version = "Any"; } else if (MinimumVersion == MaximumVersion) { version = MinimumVersion.ToString(); } else { if (MinimumVersion == ZeroVersion) { version = MaximumVersion.ToString() + " and earlier"; } else if (MaximumVersion == InfiniteVersion) { version = MinimumVersion.ToString() + " and later"; } else { version = MinimumVersion.ToString() + "-" + MaximumVersion; } } return string.Format(CultureInfo.InvariantCulture, "[Addin={0}, Version={1}]", Name, version); } #endregion #endregion } }