diff --git a/src/CycloneDX.Core/Models/Annotation.cs b/src/CycloneDX.Core/Models/Annotation.cs index bf10b666..a64f75e9 100644 --- a/src/CycloneDX.Core/Models/Annotation.cs +++ b/src/CycloneDX.Core/Models/Annotation.cs @@ -20,11 +20,12 @@ using System.Xml.Serialization; using System.Text.Json.Serialization; using ProtoBuf; +using System.Linq; namespace CycloneDX.Models { [ProtoContract] - public class Annotation + public class Annotation : IEquatable { [XmlType("subject")] public class XmlAnnotationSubject @@ -81,9 +82,31 @@ public DateTime? Timestamp set { _timestamp = BomUtils.UtcifyDateTime(value); } } public bool ShouldSerializeTimestamp() { return Timestamp != null; } - + + [XmlElement("text")] [ProtoMember(5)] public string Text { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as Annotation); + } + + public bool Equals(Annotation obj) + { + return obj != null && + (object.ReferenceEquals(this.Annotator, obj.Annotator) || + this.Annotator.Equals(obj.Annotator)) && + (object.ReferenceEquals(this.BomRef, obj.BomRef) || + this.BomRef.Equals(obj.BomRef, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Subjects, obj.Subjects) || + this.Subjects.SequenceEqual(obj.Subjects)) && + (object.ReferenceEquals(this.Text, obj.Text) || + this.Text.Equals(obj.Text)) && + (this.Timestamp.Equals(obj.Timestamp)) && + (object.ReferenceEquals(this.XmlSubjects, obj.XmlSubjects) || + this.XmlSubjects.SequenceEqual(obj.XmlSubjects)); + } } } diff --git a/src/CycloneDX.Core/Models/AnnotatorChoice.cs b/src/CycloneDX.Core/Models/AnnotatorChoice.cs index b996fec3..452f6331 100644 --- a/src/CycloneDX.Core/Models/AnnotatorChoice.cs +++ b/src/CycloneDX.Core/Models/AnnotatorChoice.cs @@ -15,13 +15,14 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright (c) OWASP Foundation. All Rights Reserved. +using System; using System.Xml.Serialization; using ProtoBuf; namespace CycloneDX.Models { [ProtoContract] - public class AnnotatorChoice + public class AnnotatorChoice : IEquatable { [XmlElement("organization")] [ProtoMember(1)] @@ -38,5 +39,23 @@ public class AnnotatorChoice [XmlElement("service")] [ProtoMember(4)] public Service Service { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as AnnotatorChoice); + } + + public bool Equals(AnnotatorChoice obj) + { + return obj != null && + (object.ReferenceEquals(this.Component, obj.Component) || + this.Component.Equals(obj.Component)) && + (object.ReferenceEquals(this.Individual, obj.Individual) || + this.Individual.Equals(obj.Individual)) && + (object.ReferenceEquals(this.Organization, obj.Organization) || + this.Organization.Equals(obj.Organization)) && + (object.ReferenceEquals(this.Service, obj.Service) || + this.Service.Equals(obj.Service)); + } } } diff --git a/src/CycloneDX.Core/Models/AttachedText.cs b/src/CycloneDX.Core/Models/AttachedText.cs index 26b8d004..80a8b675 100644 --- a/src/CycloneDX.Core/Models/AttachedText.cs +++ b/src/CycloneDX.Core/Models/AttachedText.cs @@ -15,13 +15,14 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright (c) OWASP Foundation. All Rights Reserved. +using System; using System.Xml.Serialization; using ProtoBuf; namespace CycloneDX.Models { [ProtoContract] - public class AttachedText + public class AttachedText : IEquatable { [XmlAttribute("content-type")] [ProtoMember(1)] @@ -34,5 +35,21 @@ public class AttachedText [XmlText] [ProtoMember(3)] public string Content { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as AttachedText); + } + + public bool Equals(AttachedText obj) + { + return obj != null && + (object.ReferenceEquals(this.Content, obj.Content) || + this.Content.Equals(obj.Content, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.ContentType, obj.ContentType) || + this.ContentType.Equals(obj.ContentType, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Encoding, obj.Encoding) || + this.Encoding.Equals(obj.Encoding, StringComparison.InvariantCultureIgnoreCase)); + } } } diff --git a/src/CycloneDX.Core/Models/Bom.cs b/src/CycloneDX.Core/Models/Bom.cs index ed3c6644..82910066 100644 --- a/src/CycloneDX.Core/Models/Bom.cs +++ b/src/CycloneDX.Core/Models/Bom.cs @@ -29,7 +29,7 @@ namespace CycloneDX.Models [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] [XmlRoot("bom", IsNullable=false)] [ProtoContract] - public class Bom + public class Bom : IEquatable { [XmlIgnore] public string BomFormat => "CycloneDX"; @@ -168,5 +168,44 @@ public int NonNullableVersion [ProtoMember(13)] public List Formulation { get; set; } public bool ShouldSerializeFormulation() { return Formulation?.Count > 0; } + + public override bool Equals(object obj) + { + return Equals(obj as Bom); + } + + public bool Equals(Bom obj) + { + return obj != null && + (object.ReferenceEquals(this.Annotations, obj.Annotations) || + this.Annotations.SequenceEqual(obj.Annotations)) && + (object.ReferenceEquals(this.BomFormat, obj.BomFormat) || + this.BomFormat.Equals(obj.BomFormat, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Components, obj.Components) || + this.Components.SequenceEqual(obj.Components)) && + (object.ReferenceEquals(this.Compositions, obj.Compositions) || + this.Compositions.SequenceEqual(obj.Compositions)) && + (object.ReferenceEquals(this.Dependencies, obj.Dependencies) || + this.Dependencies.SequenceEqual(obj.Dependencies)) && + (object.ReferenceEquals(this.ExternalReferences, obj.ExternalReferences) || + this.ExternalReferences.SequenceEqual(obj.ExternalReferences)) && + (object.ReferenceEquals(this.Formulation, obj.Formulation) || + this.Formulation.SequenceEqual(obj.Formulation)) && + (object.ReferenceEquals(this.Metadata, obj.Metadata) || + this.Metadata.Equals(obj.Metadata)) && + (this.NonNullableVersion.Equals(obj.NonNullableVersion)) && + + (object.ReferenceEquals(this.Properties, obj.Properties) || + this.Properties.SequenceEqual(obj.Properties)) && + (object.ReferenceEquals(this.SerialNumber, obj.SerialNumber) || + this.SerialNumber.Equals(obj.SerialNumber, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Services, obj.Services) || + this.Services.SequenceEqual(obj.Services)) && + (this.SpecVersion.Equals(obj.SpecVersion)) && + (this.SpecVersionString.Equals(obj.SpecVersionString)) && + (this.Version.Equals(obj.Version)) && + (object.ReferenceEquals(this.Vulnerabilities, obj.Vulnerabilities) || + this.Vulnerabilities.Equals(obj.Vulnerabilities)); + } } } \ No newline at end of file diff --git a/src/CycloneDX.Core/Models/Callstack.cs b/src/CycloneDX.Core/Models/Callstack.cs index 522d68db..3a86c998 100644 --- a/src/CycloneDX.Core/Models/Callstack.cs +++ b/src/CycloneDX.Core/Models/Callstack.cs @@ -18,6 +18,7 @@ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using System.Linq; using System.Linq.Expressions; using System.Text.Json.Serialization; using System.Xml; @@ -28,11 +29,11 @@ namespace CycloneDX.Models { [XmlType("callstack")] [ProtoContract] - public class Callstack + public class Callstack : IEquatable { [XmlType("frame")] [ProtoContract] - public class Frame + public class Frame : IEquatable { [XmlElement("package")] [ProtoMember(1)] @@ -63,11 +64,45 @@ public class Frame [XmlElement("fullFilename")] [ProtoMember(7)] public string FullFilename { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as Frame); + } + + public bool Equals(Frame obj) + { + return obj != null && + (this.Column.Equals(obj.Column)) && + (object.ReferenceEquals(this.FullFilename, obj.FullFilename) || + this.FullFilename.SequenceEqual(obj.FullFilename)) && + (object.ReferenceEquals(this.Function, obj.Function) || + this.Function.Equals(obj.Function, StringComparison.InvariantCultureIgnoreCase)) && + (this.Line.Equals(obj.Line)) && + (object.ReferenceEquals(this.Module, obj.Module) || + this.Module.SequenceEqual(obj.Module)) && + (object.ReferenceEquals(this.Package, obj.Package) || + this.Package.Equals(obj.Package)) && + (object.ReferenceEquals(this.Parameters, obj.Parameters) || + this.Parameters.SequenceEqual(obj.Parameters)); + } } [XmlArray("frames")] [XmlArrayItem("frame")] [ProtoMember(1)] public List Frames { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as Callstack); + } + + public bool Equals(Callstack obj) + { + return obj != null && + (object.ReferenceEquals(this.Frames, obj.Frames) || + this.Frames.SequenceEqual(obj.Frames)); + } } } \ No newline at end of file diff --git a/src/CycloneDX.Core/Models/Command.cs b/src/CycloneDX.Core/Models/Command.cs index f0bfc1ff..c0cc6d04 100644 --- a/src/CycloneDX.Core/Models/Command.cs +++ b/src/CycloneDX.Core/Models/Command.cs @@ -18,6 +18,7 @@ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using System.Linq; using System.Text.Json.Serialization; using System.Xml.Serialization; using ProtoBuf; @@ -26,7 +27,7 @@ namespace CycloneDX.Models { [XmlType("command")] [ProtoContract] - public class Command + public class Command : IEquatable { [XmlElement("executed")] [ProtoMember(1)] @@ -37,5 +38,19 @@ public class Command [ProtoMember(2)] public List Properties { get; set; } public bool ShouldSerializeProperties() { return Properties?.Count > 0; } + + public override bool Equals(object obj) + { + return Equals(obj as Command); + } + + public bool Equals(Command obj) + { + return obj != null && + (object.ReferenceEquals(this.Executed, obj.Executed) || + this.Executed.Equals(obj.Executed, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Properties, obj.Properties) || + this.Properties.SequenceEqual(obj.Properties)); + } } } \ No newline at end of file diff --git a/src/CycloneDX.Core/Models/Commit.cs b/src/CycloneDX.Core/Models/Commit.cs index bd0ea2d1..3fd378d6 100644 --- a/src/CycloneDX.Core/Models/Commit.cs +++ b/src/CycloneDX.Core/Models/Commit.cs @@ -15,13 +15,14 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright (c) OWASP Foundation. All Rights Reserved. +using System; using System.Xml.Serialization; using ProtoBuf; namespace CycloneDX.Models { [ProtoContract] - public class Commit + public class Commit : IEquatable { [XmlElement("uid")] [ProtoMember(1)] @@ -42,5 +43,25 @@ public class Commit [XmlElement("message")] [ProtoMember(5)] public string Message { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as Commit); + } + + public bool Equals(Commit obj) + { + return obj != null && + (object.ReferenceEquals(this.Author, obj.Author) || + this.Author.Equals(obj.Author)) && + (object.ReferenceEquals(this.Committer, obj.Committer) || + this.Committer.Equals(obj.Committer)) && + (object.ReferenceEquals(this.Message, obj.Message) || + this.Message.Equals(obj.Message, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Uid, obj.Uid) || + this.Uid.Equals(obj.Uid, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Url, obj.Url) || + this.Url.Equals(obj.Url, StringComparison.InvariantCultureIgnoreCase)); + } } } diff --git a/src/CycloneDX.Core/Models/Composition.cs b/src/CycloneDX.Core/Models/Composition.cs index bdad1ad6..6a6919d5 100644 --- a/src/CycloneDX.Core/Models/Composition.cs +++ b/src/CycloneDX.Core/Models/Composition.cs @@ -26,7 +26,7 @@ namespace CycloneDX.Models { [ProtoContract] - public class Composition : IXmlSerializable, IEquatable + public class Composition : IEquatable, IXmlSerializable { [ProtoContract] public enum AggregateType @@ -69,7 +69,32 @@ public enum AggregateType [ProtoMember(5)] public string BomRef { get; set; } - public System.Xml.Schema.XmlSchema GetSchema() { + public override bool Equals(object obj) + { + return Equals(obj as Composition); + } + + public bool Equals(Composition obj) + { + return obj != null && + (this.Aggregate == obj.Aggregate) && + (object.ReferenceEquals(this.BomRef, obj.BomRef) || + this.BomRef.Equals(obj.BomRef, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Assemblies, obj.Assemblies) || + this.Assemblies.SequenceEqual(obj.Assemblies)) && + (object.ReferenceEquals(this.Dependencies, obj.Dependencies) || + this.Dependencies.SequenceEqual(obj.Dependencies)) && + (object.ReferenceEquals(this.Vulnerabilities, obj.Vulnerabilities) || + this.Vulnerabilities.SequenceEqual(obj.Vulnerabilities)); + } + + public override int GetHashCode() + { + return CycloneDX.Json.Serializer.Serialize(this).GetHashCode(); + } + + public System.Xml.Schema.XmlSchema GetSchema() + { return null; } @@ -77,7 +102,7 @@ public void ReadXml(XmlReader reader) { BomRef = reader.GetAttribute("bom-ref"); reader.ReadStartElement(); - + if (reader.LocalName == "aggregate") { var aggregateString = reader.ReadElementContentAsString(); @@ -148,8 +173,9 @@ public void ReadXml(XmlReader reader) reader.ReadEndElement(); } - - public void WriteXml(System.Xml.XmlWriter writer) { + + public void WriteXml(System.Xml.XmlWriter writer) + { if (BomRef != null) { writer.WriteAttributeString("bom-ref", BomRef); @@ -195,29 +221,5 @@ public void WriteXml(System.Xml.XmlWriter writer) { writer.WriteEndElement(); } } - - public override bool Equals(object obj) - { - return Equals(obj as Composition); - } - - public bool Equals(Composition obj) - { - return obj != null && - (this.Aggregate == obj.Aggregate) && - (object.ReferenceEquals(this.BomRef, obj.BomRef) || - this.BomRef.Equals(obj.BomRef, StringComparison.InvariantCultureIgnoreCase)) && - (object.ReferenceEquals(this.Assemblies, obj.Assemblies) || - this.Assemblies.SequenceEqual(obj.Assemblies)) && - (object.ReferenceEquals(this.Dependencies, obj.Dependencies) || - this.Dependencies.SequenceEqual(obj.Dependencies)) && - (object.ReferenceEquals(this.Vulnerabilities, obj.Vulnerabilities) || - this.Vulnerabilities.SequenceEqual(obj.Vulnerabilities)); - } - - public override int GetHashCode() - { - return CycloneDX.Json.Serializer.Serialize(this).GetHashCode(); - } } } \ No newline at end of file diff --git a/src/CycloneDX.Core/Models/Data.cs b/src/CycloneDX.Core/Models/Data.cs index 7741a68a..85fe560e 100644 --- a/src/CycloneDX.Core/Models/Data.cs +++ b/src/CycloneDX.Core/Models/Data.cs @@ -18,6 +18,7 @@ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using System.Linq; using System.Text.Json.Serialization; using System.Xml.Serialization; using ProtoBuf; @@ -25,7 +26,7 @@ namespace CycloneDX.Models { [ProtoContract] - public class Data + public class Data : IEquatable { [ProtoContract] public enum DataType @@ -43,7 +44,7 @@ public enum DataType } [ProtoContract] - public class DataContents + public class DataContents : IEquatable { [XmlElement("attachment")] [ProtoMember(1)] @@ -58,6 +59,22 @@ public class DataContents [ProtoMember(22)] public List Properties { get; set; } public bool ShouldSerializeProperties() { return Properties?.Count > 0; } + + public override bool Equals(object obj) + { + return Equals(obj as DataContents); + } + + public bool Equals(DataContents obj) + { + return obj != null && + (object.ReferenceEquals(this.Attachment, obj.Attachment) || + this.Attachment.Equals(obj.Attachment)) && + (object.ReferenceEquals(this.Properties, obj.Properties) || + this.Properties.SequenceEqual(obj.Properties)) && + (object.ReferenceEquals(this.Url, obj.Url) || + this.Url.Equals(obj.Url, StringComparison.InvariantCultureIgnoreCase)); + } } [JsonPropertyName("bom-ref")] @@ -96,5 +113,33 @@ public class DataContents [XmlElement("governance")] [ProtoMember(9)] public DataGovernance Governance { get; set; } + + + public override bool Equals(object obj) + { + return Equals(obj as Data); + } + + public bool Equals(Data obj) + { + return obj != null && + (object.ReferenceEquals(this.BomRef, obj.BomRef) || + this.BomRef.Equals(obj.BomRef, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Classification, obj.Classification) || + this.Classification.Equals(obj.Classification, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Contents, obj.Contents) || + this.Contents.Equals(obj.Contents)) && + (object.ReferenceEquals(this.Description, obj.Description) || + this.Description.Equals(obj.Description, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Governance, obj.Governance) || + this.Governance.Equals(obj.Governance)) && + (object.ReferenceEquals(this.Graphics, obj.Graphics) || + this.Graphics.Equals(obj.Graphics)) && + (object.ReferenceEquals(this.Name, obj.Name) || + this.Name.Equals(obj.Name, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.SensitiveData, obj.SensitiveData) || + this.SensitiveData.Equals(obj.SensitiveData, StringComparison.InvariantCultureIgnoreCase)) && + (this.Type.Equals(obj.Type)); + } } } \ No newline at end of file diff --git a/src/CycloneDX.Core/Models/DataClassification.cs b/src/CycloneDX.Core/Models/DataClassification.cs index 1defc8a2..69550cdb 100644 --- a/src/CycloneDX.Core/Models/DataClassification.cs +++ b/src/CycloneDX.Core/Models/DataClassification.cs @@ -15,6 +15,7 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright (c) OWASP Foundation. All Rights Reserved. +using System; using System.Collections.Generic; using System.Text.Json.Serialization; using System.Xml.Serialization; @@ -25,7 +26,7 @@ namespace CycloneDX.Models // this is the version that was prior to v1.5 [XmlType("classification")] [ProtoContract] - public class DataClassification + public class DataClassification : IEquatable { [XmlAttribute("flow")] [ProtoMember(1, IsRequired=true)] @@ -34,5 +35,18 @@ public class DataClassification [XmlText] [ProtoMember(2)] public string Classification { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as DataClassification); + } + + public bool Equals(DataClassification obj) + { + return obj != null && + (object.ReferenceEquals(this.Classification, obj.Classification) || + this.Classification.Equals(obj.Classification, StringComparison.InvariantCultureIgnoreCase)) && + (this.Flow == obj.Flow); + } } } diff --git a/src/CycloneDX.Core/Models/DataFlow.cs b/src/CycloneDX.Core/Models/DataFlow.cs index 099d6d1b..494a80ea 100644 --- a/src/CycloneDX.Core/Models/DataFlow.cs +++ b/src/CycloneDX.Core/Models/DataFlow.cs @@ -15,7 +15,9 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright (c) OWASP Foundation. All Rights Reserved. +using System; using System.Collections.Generic; +using System.Linq; using System.Text.Json.Serialization; using System.Xml.Serialization; using ProtoBuf; @@ -24,7 +26,7 @@ namespace CycloneDX.Models { [XmlType("dataflow")] [ProtoContract] - public class DataFlow + public class DataFlow : IEquatable { [XmlIgnore] [JsonPropertyName("flow")] @@ -73,5 +75,30 @@ public DataClassification XmlClassification { [ProtoMember(6)] public List Destination { get; set; } public bool ShouldSerializeDestination() => Destination != null; + + public override bool Equals(object obj) + { + return Equals(obj as DataFlow); + } + + public bool Equals(DataFlow obj) + { + return obj != null && + (object.ReferenceEquals(this.Classification, obj.Classification) || + this.Classification.Equals(obj.Classification, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Description, obj.Description) || + this.Description.Equals(obj.Description, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Destination, obj.Destination) || + this.Destination.SequenceEqual(obj.Destination)) && + (this.Flow.Equals(obj.Flow)) && + (object.ReferenceEquals(this.Governance, obj.Governance) || + this.Governance.Equals(obj.Governance)) && + (object.ReferenceEquals(this.Name, obj.Name) || + this.Name.Equals(obj.Name, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Source, obj.Source) || + this.Source.SequenceEqual(obj.Source)) && + (object.ReferenceEquals(this.XmlClassification, obj.XmlClassification) || + this.XmlClassification.Equals(obj.XmlClassification)); + } } } diff --git a/src/CycloneDX.Core/Models/DataGovernance.cs b/src/CycloneDX.Core/Models/DataGovernance.cs index 0b8b939e..98299df8 100644 --- a/src/CycloneDX.Core/Models/DataGovernance.cs +++ b/src/CycloneDX.Core/Models/DataGovernance.cs @@ -18,6 +18,7 @@ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using System.Linq; using System.Text.Json.Serialization; using System.Xml.Serialization; using ProtoBuf; @@ -26,7 +27,7 @@ namespace CycloneDX.Models { [XmlType("data-governance")] [ProtoContract] - public class DataGovernance + public class DataGovernance : IEquatable { [XmlArray("custodians")] [XmlArrayItem("custodian")] @@ -45,5 +46,21 @@ public class DataGovernance [ProtoMember(3)] public List Owners { get; set; } public bool ShouldSerializeOwners() { return Owners?.Count > 0; } + + public override bool Equals(object obj) + { + return Equals(obj as DataGovernance); + } + + public bool Equals(DataGovernance obj) + { + return obj != null && + (object.ReferenceEquals(this.Custodians, obj.Custodians) || + this.Custodians.SequenceEqual(obj.Custodians)) && + (object.ReferenceEquals(this.Owners, obj.Owners) || + this.Owners.SequenceEqual(obj.Owners)) && + (object.ReferenceEquals(this.Stewards, obj.Stewards) || + this.Stewards.SequenceEqual(obj.Stewards)); + } } } \ No newline at end of file diff --git a/src/CycloneDX.Core/Models/DataflowSourceDestination.cs b/src/CycloneDX.Core/Models/DataflowSourceDestination.cs index e2b4157b..d6fd1d7e 100644 --- a/src/CycloneDX.Core/Models/DataflowSourceDestination.cs +++ b/src/CycloneDX.Core/Models/DataflowSourceDestination.cs @@ -15,16 +15,29 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright (c) OWASP Foundation. All Rights Reserved. +using System; using System.Xml.Serialization; using ProtoBuf; namespace CycloneDX.Models { [ProtoContract] - public class DataflowSourceDestination + public class DataflowSourceDestination : IEquatable { [XmlElement("url")] [ProtoMember(1)] public string Url { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as Annotation); + } + + public bool Equals(DataflowSourceDestination obj) + { + return obj != null && + (object.ReferenceEquals(this.Url, obj.Url) || + this.Url.Equals(obj.Url, StringComparison.InvariantCultureIgnoreCase)); + } } } diff --git a/src/CycloneDX.Core/Models/DatasetChoice.cs b/src/CycloneDX.Core/Models/DatasetChoice.cs index c50d9684..1ba5c2ff 100644 --- a/src/CycloneDX.Core/Models/DatasetChoice.cs +++ b/src/CycloneDX.Core/Models/DatasetChoice.cs @@ -15,13 +15,14 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright (c) OWASP Foundation. All Rights Reserved. +using System; using System.Xml.Serialization; using ProtoBuf; namespace CycloneDX.Models { [ProtoContract] - public class DatasetChoice + public class DatasetChoice : IEquatable { [XmlElement("dataset")] [ProtoMember(1)] @@ -30,5 +31,19 @@ public class DatasetChoice [XmlElement("ref")] [ProtoMember(2)] public string Ref { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as DatasetChoice); + } + + public bool Equals(DatasetChoice obj) + { + return obj != null && + (object.ReferenceEquals(this.DataSet, obj.DataSet) || + this.DataSet.Equals(obj.DataSet)) && + (object.ReferenceEquals(this.Ref, obj.Ref) || + this.Ref.Equals(obj.Ref, StringComparison.InvariantCultureIgnoreCase)); + } } } diff --git a/src/CycloneDX.Core/Models/DatasetChoices.cs b/src/CycloneDX.Core/Models/DatasetChoices.cs index 6dafcb10..c1ba3782 100644 --- a/src/CycloneDX.Core/Models/DatasetChoices.cs +++ b/src/CycloneDX.Core/Models/DatasetChoices.cs @@ -15,7 +15,9 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright (c) OWASP Foundation. All Rights Reserved. +using System; using System.Collections.Generic; +using System.Linq; using System.Text.Json.Serialization; using System.Xml; using System.Xml.Serialization; @@ -24,7 +26,7 @@ namespace CycloneDX.Models { [ProtoContract] - public class DatasetChoices : List, IXmlSerializable + public class DatasetChoices : List, IEquatable, IXmlSerializable { private static XmlSerializer _datasetSerializer; private static XmlSerializer GetDatasetSerializer() @@ -39,7 +41,20 @@ private static XmlSerializer GetDatasetSerializer() return _datasetSerializer; } - public System.Xml.Schema.XmlSchema GetSchema() { + public override bool Equals(object obj) + { + return Equals(obj as DatasetChoices); + } + + public bool Equals(DatasetChoices obj) + { + return obj != null && + (object.ReferenceEquals(this, obj) || + (this.SequenceEqual(obj))); + } + + public System.Xml.Schema.XmlSchema GetSchema() + { return null; } @@ -62,8 +77,9 @@ public void ReadXml(XmlReader reader) } reader.ReadEndElement(); } - - public void WriteXml(System.Xml.XmlWriter writer) { + + public void WriteXml(System.Xml.XmlWriter writer) + { foreach (var datasetChoice in this) { if (datasetChoice.Ref != null) diff --git a/src/CycloneDX.Core/Models/Diff.cs b/src/CycloneDX.Core/Models/Diff.cs index 3eda6e66..2975f703 100644 --- a/src/CycloneDX.Core/Models/Diff.cs +++ b/src/CycloneDX.Core/Models/Diff.cs @@ -15,13 +15,14 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright (c) OWASP Foundation. All Rights Reserved. +using System; using System.Xml.Serialization; using ProtoBuf; namespace CycloneDX.Models { [ProtoContract] - public class Diff + public class Diff : IEquatable { [XmlElement("text")] [ProtoMember(1)] @@ -29,5 +30,19 @@ public class Diff [XmlElement("url")] [ProtoMember(2)] public string Url { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as Diff); + } + + public bool Equals(Diff obj) + { + return obj != null && + (object.ReferenceEquals(this.Text, obj.Text) || + this.Text.Equals(obj.Text)) && + (object.ReferenceEquals(this.Url, obj.Url) || + this.Url.Equals(obj.Url, StringComparison.InvariantCultureIgnoreCase)); + } } } diff --git a/src/CycloneDX.Core/Models/EnvironmentVarChoice.cs b/src/CycloneDX.Core/Models/EnvironmentVarChoice.cs index 733b6ed0..96b7ac1e 100644 --- a/src/CycloneDX.Core/Models/EnvironmentVarChoice.cs +++ b/src/CycloneDX.Core/Models/EnvironmentVarChoice.cs @@ -15,6 +15,7 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright (c) OWASP Foundation. All Rights Reserved. +using System; using System.Text.Json.Serialization; using System.Xml; using System.Xml.Serialization; @@ -23,12 +24,26 @@ namespace CycloneDX.Models { [ProtoContract] - public class EnvironmentVarChoice + public class EnvironmentVarChoice : IEquatable { [ProtoMember(1)] public Property Property { get; set; } [ProtoMember(2)] public string Value { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as EnvironmentVarChoice); + } + + public bool Equals(EnvironmentVarChoice obj) + { + return obj != null && + (object.ReferenceEquals(this.Property, obj.Property) || + this.Property.Equals(obj.Property)) && + (object.ReferenceEquals(this.Value, obj.Value) || + this.Value.Equals(obj.Value, StringComparison.InvariantCultureIgnoreCase)); + } } } diff --git a/src/CycloneDX.Core/Models/EnvironmentVarChoices.cs b/src/CycloneDX.Core/Models/EnvironmentVarChoices.cs index b7df48d8..bca149df 100644 --- a/src/CycloneDX.Core/Models/EnvironmentVarChoices.cs +++ b/src/CycloneDX.Core/Models/EnvironmentVarChoices.cs @@ -15,7 +15,9 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright (c) OWASP Foundation. All Rights Reserved. +using System; using System.Collections.Generic; +using System.Linq; using System.Text.Json.Serialization; using System.Xml; using System.Xml.Serialization; @@ -24,9 +26,22 @@ namespace CycloneDX.Models { [ProtoContract] - public class EnvironmentVarChoices : List, IXmlSerializable + public class EnvironmentVarChoices : List, IEquatable, IXmlSerializable { - public System.Xml.Schema.XmlSchema GetSchema() { + public override bool Equals(object obj) + { + return Equals(obj as Annotation); + } + + public bool Equals(EnvironmentVarChoices obj) + { + return obj != null && + (object.ReferenceEquals(this, obj) || + this.SequenceEqual(obj)); + } + + public System.Xml.Schema.XmlSchema GetSchema() + { return null; } @@ -44,13 +59,14 @@ public void ReadXml(XmlReader reader) { var nameString = reader.GetAttribute("name"); var valueString = reader.ReadElementContentAsString(); - this.Add(new EnvironmentVarChoice { Property = new Property { Name = nameString, Value = valueString }}); + this.Add(new EnvironmentVarChoice { Property = new Property { Name = nameString, Value = valueString } }); } } reader.ReadEndElement(); } - - public void WriteXml(System.Xml.XmlWriter writer) { + + public void WriteXml(System.Xml.XmlWriter writer) + { foreach (var envVar in this) { if (envVar.Value != null) diff --git a/src/CycloneDX.Core/Models/Event.cs b/src/CycloneDX.Core/Models/Event.cs index ae9d4196..cacca958 100644 --- a/src/CycloneDX.Core/Models/Event.cs +++ b/src/CycloneDX.Core/Models/Event.cs @@ -18,6 +18,7 @@ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using System.Linq; using System.Text.Json.Serialization; using System.Xml.Serialization; using ProtoBuf; @@ -26,7 +27,7 @@ namespace CycloneDX.Models { [XmlType("event")] [ProtoContract] - public class Event + public class Event : IEquatable { [XmlElement("uid")] [ProtoMember(1)] @@ -63,5 +64,28 @@ public DateTime? TimeReceived [ProtoMember(7)] public List Properties { get; set; } public bool ShouldSerializeProperties() { return Properties?.Count > 0; } + + public override bool Equals(object obj) + { + return Equals(obj as Event); + } + + public bool Equals(Event obj) + { + return obj != null && + (object.ReferenceEquals(this.Data, obj.Data) || + this.Data.Equals(obj.Data)) && + (object.ReferenceEquals(this.Description, obj.Description) || + this.Description.Equals(obj.Description, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Properties, obj.Properties) || + this.Properties.SequenceEqual(obj.Properties)) && + (object.ReferenceEquals(this.Source, obj.Source) || + this.Description.Equals(obj.Source)) && + (object.ReferenceEquals(this.Target, obj.Target) || + this.Description.Equals(obj.Target)) && + (this.TimeReceived.Equals(obj.TimeReceived)) && + (object.ReferenceEquals(this.Uid, obj.Uid) || + this.Uid.Equals(obj.Uid, StringComparison.InvariantCultureIgnoreCase)); + } } } \ No newline at end of file diff --git a/src/CycloneDX.Core/Models/Evidence.cs b/src/CycloneDX.Core/Models/Evidence.cs index cead04c9..61098299 100644 --- a/src/CycloneDX.Core/Models/Evidence.cs +++ b/src/CycloneDX.Core/Models/Evidence.cs @@ -19,6 +19,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics.CodeAnalysis; +using System.Linq; using System.Linq.Expressions; using System.Text.Json.Serialization; using System.Xml; @@ -29,7 +30,7 @@ namespace CycloneDX.Models { [XmlType("evidence")] [ProtoContract] - public class Evidence + public class Evidence : IEquatable { [XmlIgnore] [ProtoMember(1)] @@ -63,5 +64,27 @@ public LicenseChoiceList LicensesSerialized [XmlElement("callstack", Order = 2)] [ProtoMember(5)] public Callstack Callstack { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as Evidence); + } + + public bool Equals(Evidence obj) + { + return obj != null && + (object.ReferenceEquals(this.Callstack, obj.Callstack) || + this.Callstack.Equals(obj.Callstack)) && + (object.ReferenceEquals(this.Copyright, obj.Copyright) || + this.Copyright.SequenceEqual(obj.Copyright)) && + (object.ReferenceEquals(this.Identity, obj.Identity) || + this.Identity.Equals(obj.Identity)) && + (object.ReferenceEquals(this.Licenses, obj.Licenses) || + this.Licenses.SequenceEqual(obj.Licenses)) && + (object.ReferenceEquals(this.LicensesSerialized, obj.LicensesSerialized) || + this.LicensesSerialized.Equals(obj.LicensesSerialized)) && + (object.ReferenceEquals(this.Occurrences, obj.Occurrences) || + this.Occurrences.Equals(obj.Occurrences)); + } } } \ No newline at end of file diff --git a/src/CycloneDX.Core/Models/EvidenceCopyright.cs b/src/CycloneDX.Core/Models/EvidenceCopyright.cs index 03161b88..2814192a 100644 --- a/src/CycloneDX.Core/Models/EvidenceCopyright.cs +++ b/src/CycloneDX.Core/Models/EvidenceCopyright.cs @@ -15,16 +15,29 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright (c) OWASP Foundation. All Rights Reserved. +using System; using System.Xml.Serialization; using ProtoBuf; namespace CycloneDX.Models { [ProtoContract] - public class EvidenceCopyright + public class EvidenceCopyright : IEquatable { [XmlText] [ProtoMember(1)] public string Text { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as EvidenceCopyright); + } + + public bool Equals(EvidenceCopyright obj) + { + return obj != null && + (object.ReferenceEquals(this.Text, obj.Text) || + this.Text.Equals(obj.Text, StringComparison.InvariantCultureIgnoreCase)); + } } } diff --git a/src/CycloneDX.Core/Models/EvidenceIdentity.cs b/src/CycloneDX.Core/Models/EvidenceIdentity.cs index a9c3c18a..7c71e100 100644 --- a/src/CycloneDX.Core/Models/EvidenceIdentity.cs +++ b/src/CycloneDX.Core/Models/EvidenceIdentity.cs @@ -18,6 +18,7 @@ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using System.Linq; using System.Linq.Expressions; using System.Text.Json.Serialization; using System.Xml; @@ -28,7 +29,7 @@ namespace CycloneDX.Models { [XmlType("evidence-identity")] [ProtoContract] - public class EvidenceIdentity + public class EvidenceIdentity : IEquatable { [ProtoContract] public enum EvidenceFieldType @@ -67,5 +68,21 @@ public enum EvidenceFieldType [XmlElement("tools")] [ProtoMember(4)] public EvidenceTools Tools { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as EvidenceIdentity); + } + + public bool Equals(EvidenceIdentity obj) + { + return obj != null && + (this.Confidence.Equals(obj.Confidence)) && + (this.Field.Equals(obj.Field)) && + (object.ReferenceEquals(this.Methods, obj.Methods) || + this.Methods.SequenceEqual(obj.Methods)) && + (object.ReferenceEquals(this.Tools, obj.Tools) || + this.Tools.SequenceEqual(obj.Tools)); + } } } \ No newline at end of file diff --git a/src/CycloneDX.Core/Models/EvidenceMethods.cs b/src/CycloneDX.Core/Models/EvidenceMethods.cs index dce4170e..fdd4edc5 100644 --- a/src/CycloneDX.Core/Models/EvidenceMethods.cs +++ b/src/CycloneDX.Core/Models/EvidenceMethods.cs @@ -28,7 +28,7 @@ namespace CycloneDX.Models { [XmlType("evidence-methods")] [ProtoContract] - public class EvidenceMethods + public class EvidenceMethods : IEquatable { [ProtoContract] public enum EvidenceTechnique @@ -66,5 +66,20 @@ public enum EvidenceTechnique [XmlElement("value")] [ProtoMember(3)] public string Value { get; set; } + + + public override bool Equals(object obj) + { + return Equals(obj as EvidenceMethods); + } + + public bool Equals(EvidenceMethods obj) + { + return obj != null && + (this.Confidence.Equals(obj.Confidence)) && + (this.Technique.Equals(obj.Technique)) && + (object.ReferenceEquals(this.Value, obj.Value) || + this.Value.Equals(obj.Value, StringComparison.InvariantCultureIgnoreCase)); + } } } \ No newline at end of file diff --git a/src/CycloneDX.Core/Models/EvidenceOccurrence.cs b/src/CycloneDX.Core/Models/EvidenceOccurrence.cs index 126ce97a..08000668 100644 --- a/src/CycloneDX.Core/Models/EvidenceOccurrence.cs +++ b/src/CycloneDX.Core/Models/EvidenceOccurrence.cs @@ -28,7 +28,7 @@ namespace CycloneDX.Models { [XmlType("evidence-occurrence")] [ProtoContract] - public class EvidenceOccurrence + public class EvidenceOccurrence : IEquatable { [JsonPropertyName("bom-ref")] [XmlAttribute("bom-ref")] @@ -38,5 +38,19 @@ public class EvidenceOccurrence [XmlElement("location")] [ProtoMember(2)] public string Location { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as Annotation); + } + + public bool Equals(EvidenceOccurrence obj) + { + return obj != null && + (object.ReferenceEquals(this.BomRef, obj.BomRef) || + this.BomRef.Equals(obj.BomRef, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Location, obj.Location) || + this.Location.Equals(obj.Location, StringComparison.InvariantCultureIgnoreCase)); + } } } \ No newline at end of file diff --git a/src/CycloneDX.Core/Models/EvidenceTools.cs b/src/CycloneDX.Core/Models/EvidenceTools.cs index 2e675b1c..bbf6d67c 100644 --- a/src/CycloneDX.Core/Models/EvidenceTools.cs +++ b/src/CycloneDX.Core/Models/EvidenceTools.cs @@ -22,11 +22,24 @@ namespace CycloneDX.Models { - public class EvidenceTools : List, IXmlSerializable + public class EvidenceTools : List, IEquatable, IXmlSerializable { private readonly string _elementName = "tool"; - public System.Xml.Schema.XmlSchema GetSchema() { + public override bool Equals(object obj) + { + return Equals(obj as EvidenceTools); + } + + public bool Equals(EvidenceTools obj) + { + return obj != null && + (object.ReferenceEquals(this, obj) || + this.Equals(obj)); + } + + public System.Xml.Schema.XmlSchema GetSchema() + { return null; } @@ -40,8 +53,9 @@ public void ReadXml(XmlReader reader) } reader.ReadEndElement(); } - - public void WriteXml(XmlWriter writer) { + + public void WriteXml(XmlWriter writer) + { foreach (var bomref in this) { writer.WriteStartElement(_elementName); @@ -49,5 +63,6 @@ public void WriteXml(XmlWriter writer) { writer.WriteEndElement(); } } + } } diff --git a/src/CycloneDX.Core/Models/Formula.cs b/src/CycloneDX.Core/Models/Formula.cs index d0b5ffed..df246719 100644 --- a/src/CycloneDX.Core/Models/Formula.cs +++ b/src/CycloneDX.Core/Models/Formula.cs @@ -18,6 +18,7 @@ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using System.Linq; using System.Text.Json.Serialization; using System.Xml.Serialization; using ProtoBuf; @@ -26,7 +27,7 @@ namespace CycloneDX.Models { [XmlType("formula")] [ProtoContract] - public class Formula + public class Formula : IEquatable { [JsonPropertyName("bom-ref")] [XmlAttribute("bom-ref")] @@ -54,5 +55,25 @@ public class Formula [ProtoMember(5)] public List Properties { get; set; } public bool ShouldSerializeProperties() { return Properties?.Count > 0; } + + public override bool Equals(object obj) + { + return Equals(obj as Formula); + } + + public bool Equals(Formula obj) + { + return obj != null && + (object.ReferenceEquals(this.BomRef, obj.BomRef) || + this.BomRef.Equals(obj.BomRef)) && + (object.ReferenceEquals(this.Components, obj.Components) || + this.Components.SequenceEqual(obj.Components)) && + (object.ReferenceEquals(this.Properties, obj.Properties) || + this.Properties.SequenceEqual(obj.Properties)) && + (object.ReferenceEquals(this.Services, obj.Services) || + this.Services.SequenceEqual(obj.Services)) && + (object.ReferenceEquals(this.Workflows, obj.Workflows) || + this.Workflows.Equals(obj.Workflows)); + } } } \ No newline at end of file diff --git a/src/CycloneDX.Core/Models/GraphicsCollection.cs b/src/CycloneDX.Core/Models/GraphicsCollection.cs index cc35bb19..a2c3a491 100644 --- a/src/CycloneDX.Core/Models/GraphicsCollection.cs +++ b/src/CycloneDX.Core/Models/GraphicsCollection.cs @@ -26,10 +26,10 @@ namespace CycloneDX.Models { [XmlType("graphics")] [ProtoContract] - public class GraphicsCollection + public class GraphicsCollection : IEquatable { [ProtoContract] - public class Graphic + public class Graphic : IEquatable { [XmlElement("name")] [ProtoMember(1)] @@ -38,6 +38,20 @@ public class Graphic [XmlElement("image")] [ProtoMember(2)] public AttachedText Image { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as Graphic); + } + + public bool Equals(Graphic obj) + { + return obj != null && + (object.ReferenceEquals(this.Image, obj.Image) || + this.Image.Equals(obj.Image)) && + (object.ReferenceEquals(this.Name, obj.Name) || + this.Name.Equals(obj.Name, StringComparison.InvariantCultureIgnoreCase)); + } } [XmlElement("description")] @@ -48,5 +62,19 @@ public class Graphic [XmlArrayItem("graphic")] [ProtoMember(2)] public List Collection { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as GraphicsCollection); + } + + public bool Equals(GraphicsCollection obj) + { + return obj != null && + (object.ReferenceEquals(this.Collection, obj.Collection) || + this.Collection.Equals(obj.Collection)) && + (object.ReferenceEquals(this.Description, obj.Description) || + this.Description.Equals(obj.Description, StringComparison.InvariantCultureIgnoreCase)); + } } } \ No newline at end of file diff --git a/src/CycloneDX.Core/Models/Hash.cs b/src/CycloneDX.Core/Models/Hash.cs index 567f8446..8786e136 100644 --- a/src/CycloneDX.Core/Models/Hash.cs +++ b/src/CycloneDX.Core/Models/Hash.cs @@ -15,6 +15,7 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright (c) OWASP Foundation. All Rights Reserved. +using System; using System.Xml.Serialization; using ProtoBuf; @@ -22,7 +23,7 @@ namespace CycloneDX.Models { [XmlType("hash")] [ProtoContract] - public class Hash + public class Hash : IEquatable { [ProtoContract] public enum HashAlgorithm @@ -62,5 +63,18 @@ public enum HashAlgorithm [XmlText] [ProtoMember(2)] public string Content { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as Hash); + } + + public bool Equals(Hash obj) + { + return obj != null && + (this.Alg== obj.Alg) && + (object.ReferenceEquals(this.Content, obj.Content) || + this.Content.Equals(obj.Content, StringComparison.InvariantCultureIgnoreCase)); + } } } \ No newline at end of file diff --git a/src/CycloneDX.Core/Models/IdentifiableAction.cs b/src/CycloneDX.Core/Models/IdentifiableAction.cs index 8cc58365..dc5e1acd 100644 --- a/src/CycloneDX.Core/Models/IdentifiableAction.cs +++ b/src/CycloneDX.Core/Models/IdentifiableAction.cs @@ -22,7 +22,7 @@ namespace CycloneDX.Models { [ProtoContract] - public class IdentifiableAction + public class IdentifiableAction : IEquatable { private DateTime? _timestamp; [XmlElement("timestamp")] @@ -41,5 +41,19 @@ public DateTime? Timestamp [XmlElement("email")] [ProtoMember(3)] public string Email { get; set; } + public override bool Equals(object obj) + { + return Equals(obj as IdentifiableAction); + } + + public bool Equals(IdentifiableAction obj) + { + return obj != null && + (object.ReferenceEquals(this.Email, obj.Email) || + this.Email.Equals(obj.Email, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Name, obj.Name) || + this.Name.Equals(obj.Name, StringComparison.InvariantCultureIgnoreCase)) && + (this.Timestamp.Equals(obj.Timestamp)); + } } } diff --git a/src/CycloneDX.Core/Models/Input.cs b/src/CycloneDX.Core/Models/Input.cs index d8366765..779ef9ff 100644 --- a/src/CycloneDX.Core/Models/Input.cs +++ b/src/CycloneDX.Core/Models/Input.cs @@ -19,6 +19,7 @@ using System.Collections; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using System.Linq; using System.Text.Json.Serialization; using System.Xml.Serialization; using ProtoBuf; @@ -27,7 +28,7 @@ namespace CycloneDX.Models { [XmlType("input")] [ProtoContract] - public class Input + public class Input : IEquatable { [XmlElement("resource")] [ProtoMember(3)] @@ -61,5 +62,29 @@ public class Input [ProtoMember(7)] public List Properties { get; set; } public bool ShouldSerializeProperties() { return Properties?.Count > 0; } + + public override bool Equals(object obj) + { + return Equals(obj as Input); + } + + public bool Equals(Input obj) + { + return obj != null && + (object.ReferenceEquals(this.Data, obj.Data) || + this.Data.Equals(obj.Data)) && + (object.ReferenceEquals(this.EnvironmentVars, obj.EnvironmentVars) || + this.EnvironmentVars.Equals(obj.EnvironmentVars)) && + (object.ReferenceEquals(this.Parameters, obj.Parameters) || + this.Parameters.SequenceEqual(obj.Parameters)) && + (object.ReferenceEquals(this.Properties, obj.Properties) || + this.Properties.SequenceEqual(obj.Properties)) && + (object.ReferenceEquals(this.Resource, obj.Resource) || + this.Resource.Equals(obj.Resource)) && + (object.ReferenceEquals(this.Source, obj.Source) || + this.Source.Equals(obj.Source)) && + (object.ReferenceEquals(this.Target, obj.Target) || + this.Target.Equals(obj.Target)); + } } } \ No newline at end of file diff --git a/src/CycloneDX.Core/Models/Issue.cs b/src/CycloneDX.Core/Models/Issue.cs index d8f3f584..fd8ad720 100644 --- a/src/CycloneDX.Core/Models/Issue.cs +++ b/src/CycloneDX.Core/Models/Issue.cs @@ -15,14 +15,16 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright (c) OWASP Foundation. All Rights Reserved. +using System; using System.Collections.Generic; +using System.Linq; using System.Xml.Serialization; using ProtoBuf; namespace CycloneDX.Models { [ProtoContract] - public class Issue + public class Issue : IEquatable { [ProtoContract] public enum IssueClassification @@ -61,5 +63,26 @@ public enum IssueClassification [XmlArrayItem("url")] [ProtoMember(6)] public List References { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as Issue); + } + + public bool Equals(Issue obj) + { + return obj != null && + (object.ReferenceEquals(this.Description, obj.Description) || + this.Description.Equals(obj.Description, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Id, obj.Id) || + this.Id.Equals(obj.Id, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Name, obj.Name) || + this.Name.Equals(obj.Name, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.References, obj.References) || + this.References.SequenceEqual(obj.References)) && + (object.ReferenceEquals(this.Source, obj.Source) || + this.Source.Equals(obj.Source)) && + (this.Type == obj.Type); + } } } diff --git a/src/CycloneDX.Core/Models/License.cs b/src/CycloneDX.Core/Models/License.cs index 00edcc72..007ca779 100644 --- a/src/CycloneDX.Core/Models/License.cs +++ b/src/CycloneDX.Core/Models/License.cs @@ -15,7 +15,9 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright (c) OWASP Foundation. All Rights Reserved. +using System; using System.Collections.Generic; +using System.Linq; using System.Text.Json.Serialization; using System.Xml.Serialization; using ProtoBuf; @@ -24,7 +26,7 @@ namespace CycloneDX.Models { [XmlType("license")] [ProtoContract] - public class License + public class License : IEquatable { [XmlElement("id")] [ProtoMember(1)] @@ -58,5 +60,30 @@ public class License [ProtoMember(7)] public List Properties { get; set; } public bool ShouldSerializeProperties() { return Properties?.Count > 0; } + + public override bool Equals(object obj) + { + return Equals(obj as License); + } + + public bool Equals(License obj) + { + return obj != null && + (object.ReferenceEquals(this.BomRef, obj.BomRef) || + this.BomRef.Equals(obj.BomRef, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Id, obj.Id) || + this.Id.Equals(obj.Id, StringComparison.InvariantCultureIgnoreCase)) && + (this.Type == obj.Type) && + (object.ReferenceEquals(this.Licensing, obj.Licensing) || + this.Licensing.Equals(obj.Licensing)) && + (object.ReferenceEquals(this.Name, obj.Name) || + this.Name.Equals(obj.Name, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Properties, obj.Id) || + this.Properties.SequenceEqual(obj.Properties)) && + (object.ReferenceEquals(this.Text, obj.Text) || + this.Id.Equals(obj.Text)) && + (object.ReferenceEquals(this.Url, obj.Url) || + this.Url.Equals(obj.Url, StringComparison.InvariantCultureIgnoreCase)); + } } } diff --git a/src/CycloneDX.Core/Models/LicenseChoice.cs b/src/CycloneDX.Core/Models/LicenseChoice.cs index 47639ed5..e47b0517 100644 --- a/src/CycloneDX.Core/Models/LicenseChoice.cs +++ b/src/CycloneDX.Core/Models/LicenseChoice.cs @@ -17,6 +17,7 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Linq.Expressions; using System.Text.Json.Serialization; using System.Xml.Serialization; @@ -26,7 +27,7 @@ namespace CycloneDX.Models { [ProtoContract] - public class LicenseChoice + public class LicenseChoice : IEquatable { [XmlElement("license")] [ProtoMember(1)] @@ -40,10 +41,26 @@ public class LicenseChoice [JsonPropertyName("bom-ref")] [ProtoMember(3)] public string BomRef { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as LicenseChoice); + } + + public bool Equals(LicenseChoice obj) + { + return obj != null && + (object.ReferenceEquals(this.BomRef, obj.BomRef) || + this.BomRef.Equals(obj.BomRef, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Expression, obj.Expression) || + this.Expression.Equals(obj.Expression, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.License, obj.License) || + this.License.Equals(obj.License)); + } } // This is a workaround to serialize licenses correctly - public class LicenseChoiceList : IXmlSerializable + public class LicenseChoiceList : IEquatable, IXmlSerializable { public LicenseChoiceList(List licenses) { @@ -54,6 +71,18 @@ public LicenseChoiceList() { } public List Licenses { get; set; } + public override bool Equals(object obj) + { + return Equals(obj as LicenseChoiceList); + } + + public bool Equals(LicenseChoiceList obj) + { + return obj != null && + (object.ReferenceEquals(this.Licenses, obj.Licenses) || + this.Licenses.SequenceEqual(obj.Licenses)); + } + public System.Xml.Schema.XmlSchema GetSchema() { return (null); @@ -123,5 +152,6 @@ public void WriteXml(System.Xml.XmlWriter writer) } } + } } diff --git a/src/CycloneDX.Core/Models/Licensing.cs b/src/CycloneDX.Core/Models/Licensing.cs index ac62118a..6b4f09df 100644 --- a/src/CycloneDX.Core/Models/Licensing.cs +++ b/src/CycloneDX.Core/Models/Licensing.cs @@ -18,6 +18,7 @@ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using System.Linq; using System.Text.Json.Serialization; using System.Xml.Serialization; using ProtoBuf; @@ -27,7 +28,7 @@ namespace CycloneDX.Models [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] [XmlType("licensing")] [ProtoContract] - public class Licensing + public class Licensing : IEquatable { [ProtoContract] public enum LicenseType @@ -114,5 +115,29 @@ public DateTime? Expiration set { _expiration = BomUtils.UtcifyDateTime(value); } } public bool ShouldSerializeExpiration() { return Expiration != null; } + + public override bool Equals(object obj) + { + return Equals(obj as Licensing); + } + + public bool Equals(Licensing obj) + { + return obj != null && + (object.ReferenceEquals(this.AltIds, obj.AltIds) || + this.AltIds.SequenceEqual(obj.AltIds)) && + (this.Expiration.Equals(obj.Expiration)) && + (this.LastRenewal.Equals(obj.LastRenewal)) && + (object.ReferenceEquals(this.Licensee, obj.Licensee) || + this.Licensee.Equals(obj.Licensee)) && + (object.ReferenceEquals(this.LicenseTypes, obj.LicenseTypes) || + this.LicenseTypes.SequenceEqual(obj.LicenseTypes)) && + (object.ReferenceEquals(this.Licensor, obj.Licensor) || + this.Licensor.Equals(obj.Licensor)) && + (object.ReferenceEquals(this.PurchaseOrder, obj.PurchaseOrder) || + this.PurchaseOrder.SequenceEqual(obj.PurchaseOrder)) && + (object.ReferenceEquals(this.Purchaser, obj.Purchaser) || + this.Purchaser.Equals(obj.Purchaser)); + } } } \ No newline at end of file diff --git a/src/CycloneDX.Core/Models/Lifecycles.cs b/src/CycloneDX.Core/Models/Lifecycles.cs index 48165d47..7e7e1d7b 100644 --- a/src/CycloneDX.Core/Models/Lifecycles.cs +++ b/src/CycloneDX.Core/Models/Lifecycles.cs @@ -23,7 +23,7 @@ namespace CycloneDX.Models { [ProtoContract] - public class Lifecycles + public class Lifecycles : IEquatable { [ProtoContract] public enum LifecyclePhase @@ -67,5 +67,21 @@ public LifecyclePhase? JsonPhase [XmlElement("description")] [ProtoMember(3)] public string Description { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as Lifecycles); + } + + public bool Equals(Lifecycles obj) + { + return obj != null && + (object.ReferenceEquals(this.Description, obj.Description) || + this.Description.Equals(obj.Description, StringComparison.InvariantCultureIgnoreCase)) && + (this.JsonPhase.Equals(obj.JsonPhase)) && + (object.ReferenceEquals(this.Name, obj.Name) || + this.Name.Equals(obj.Name, StringComparison.InvariantCultureIgnoreCase)) && + (this.Phase.Equals(obj.Phase)); + } } } diff --git a/src/CycloneDX.Core/Models/Metadata.cs b/src/CycloneDX.Core/Models/Metadata.cs index fad8b4e3..61b415d5 100644 --- a/src/CycloneDX.Core/Models/Metadata.cs +++ b/src/CycloneDX.Core/Models/Metadata.cs @@ -18,6 +18,7 @@ using System; using System.Collections.Generic; using System.ComponentModel; +using System.Linq; using System.Text.Json.Serialization; using System.Xml.Serialization; using ProtoBuf; @@ -25,7 +26,7 @@ namespace CycloneDX.Models { [ProtoContract] - public class Metadata + public class Metadata : IEquatable { private DateTime? _timestamp; [XmlElement("timestamp")] @@ -111,5 +112,36 @@ public LicenseChoiceList LicensesSerialized [ProtoMember(9)] public List Lifecycles { get; set; } public bool ShouldSerializeLifecycles() { return Lifecycles?.Count > 0; } + + public override bool Equals(object obj) + { + return Equals(obj as Metadata); + } + + public bool Equals(Metadata obj) + { + return obj != null && + (object.ReferenceEquals(this.Authors, obj.Authors) || + this.Authors.SequenceEqual(obj.Authors)) && + (object.ReferenceEquals(this.Component, obj.Component) || + this.Component.Equals(obj.Component)) && + (object.ReferenceEquals(this.Licenses, obj.Licenses) || + this.Licenses.SequenceEqual(obj.Licenses)) && + (object.ReferenceEquals(this.LicensesSerialized, obj.LicensesSerialized) || + this.LicensesSerialized.Equals(obj.LicensesSerialized)) && + (object.ReferenceEquals(this.Lifecycles, obj.Lifecycles) || + this.Lifecycles.SequenceEqual(obj.Lifecycles)) && + (object.ReferenceEquals(this.Manufacture, obj.Manufacture) || + this.Manufacture.Equals(obj.Manufacture)) && + (object.ReferenceEquals(this.Properties, obj.Properties) || + this.Properties.SequenceEqual(obj.Properties)) && + (object.ReferenceEquals(this.ProtobufTools, obj.ProtobufTools) || + this.ProtobufTools.Equals(obj.ProtobufTools)) && + (object.ReferenceEquals(this.Supplier, obj.Supplier) || + this.Supplier.Equals(obj.Supplier)) && + (this.Timestamp.Equals(obj.Timestamp)) && + (object.ReferenceEquals(this.Tools, obj.Tools) || + this.Tools.Equals(obj.Tools)); + } } } diff --git a/src/CycloneDX.Core/Models/ModelCard.cs b/src/CycloneDX.Core/Models/ModelCard.cs index 00afe51e..c48c896a 100644 --- a/src/CycloneDX.Core/Models/ModelCard.cs +++ b/src/CycloneDX.Core/Models/ModelCard.cs @@ -26,7 +26,7 @@ namespace CycloneDX.Models { [XmlType("modelCard")] [ProtoContract] - public class ModelCard + public class ModelCard : IEquatable { [ProtoContract] public enum ModelParameterApproachType @@ -44,13 +44,13 @@ public enum ModelParameterApproachType } [ProtoContract] - public class ModelCardQuantitativeAnalysis + public class ModelCardQuantitativeAnalysis : IEquatable { [ProtoContract] - public class PerformanceMetric + public class PerformanceMetric : IEquatable { [ProtoContract] - public class PerformanceMetricConfidenceInterval + public class PerformanceMetricConfidenceInterval : IEquatable { [XmlElement("lowerBound")] [ProtoMember(1)] @@ -59,6 +59,20 @@ public class PerformanceMetricConfidenceInterval [XmlElement("upperBound")] [ProtoMember(2)] public string UpperBound { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as PerformanceMetricConfidenceInterval); + } + + public bool Equals(PerformanceMetricConfidenceInterval obj) + { + return obj != null && + (object.ReferenceEquals(this.LowerBound, obj.LowerBound) || + this.LowerBound.Equals(obj.LowerBound)) && + (object.ReferenceEquals(this.UpperBound, obj.UpperBound) || + this.UpperBound.Equals(obj.UpperBound)); + } } [XmlElement("type")] @@ -76,6 +90,23 @@ public class PerformanceMetricConfidenceInterval [XmlElement("confidenceInterval")] [ProtoMember(4)] public PerformanceMetricConfidenceInterval ConfidenceInterval { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as PerformanceMetric); + } + + public bool Equals(PerformanceMetric obj) + { + return obj != null && + (object.ReferenceEquals(this.ConfidenceInterval, obj.ConfidenceInterval) || + this.ConfidenceInterval.Equals(obj.ConfidenceInterval)) && + (object.ReferenceEquals(this.Slice, obj.Slice) || + this.Slice.Equals(obj.Slice, StringComparison.InvariantCultureIgnoreCase)) && + (this.Type == obj.Type) && + (object.ReferenceEquals(this.Value, obj.Value) || + this.Value.Equals(obj.Value, StringComparison.InvariantCultureIgnoreCase)); + } } [XmlArray("performanceMetrics")] @@ -86,6 +117,20 @@ public class PerformanceMetricConfidenceInterval [XmlElement("graphics")] [ProtoMember(2)] public GraphicsCollection Graphics { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as ModelCardQuantitativeAnalysis); + } + + public bool Equals(ModelCardQuantitativeAnalysis obj) + { + return obj != null && + (object.ReferenceEquals(this.Graphics, obj.Graphics) || + this.Graphics.Equals(obj.Graphics)) && + (object.ReferenceEquals(this.PerformanceMetrics, obj.PerformanceMetrics) || + this.PerformanceMetrics.Equals(obj.PerformanceMetrics)); + } } [JsonPropertyName("bom-ref")] @@ -104,5 +149,23 @@ public class PerformanceMetricConfidenceInterval [XmlElement("considerations")] [ProtoMember(4)] public ModelCardConsiderations Considerations { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as ModelCard); + } + + public bool Equals(ModelCard obj) + { + return obj != null && + (object.ReferenceEquals(this.BomRef, obj.BomRef) || + this.BomRef.Equals(obj.BomRef, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Considerations, obj.Considerations) || + this.Considerations.Equals(obj.Considerations)) && + (object.ReferenceEquals(this.ModelParameters, obj.ModelParameters) || + this.ModelParameters.Equals(obj.ModelParameters)) && + (object.ReferenceEquals(this.QuantitativeAnalysis, obj.QuantitativeAnalysis) || + this.QuantitativeAnalysis.Equals(obj.QuantitativeAnalysis)); + } } } \ No newline at end of file diff --git a/src/CycloneDX.Core/Models/ModelCardConsiderations.cs b/src/CycloneDX.Core/Models/ModelCardConsiderations.cs index d42c88b7..71aab315 100644 --- a/src/CycloneDX.Core/Models/ModelCardConsiderations.cs +++ b/src/CycloneDX.Core/Models/ModelCardConsiderations.cs @@ -18,6 +18,7 @@ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using System.Linq; using System.Text.Json.Serialization; using System.Xml.Serialization; using ProtoBuf; @@ -26,10 +27,10 @@ namespace CycloneDX.Models { [XmlType("modelCardConsiderations")] [ProtoContract] - public class ModelCardConsiderations + public class ModelCardConsiderations : IEquatable { [ProtoContract] - public class ModelCardEthicalConsideration + public class ModelCardEthicalConsideration : IEquatable { [XmlElement("name")] [ProtoMember(1)] @@ -38,10 +39,24 @@ public class ModelCardEthicalConsideration [XmlElement("mitigationStrategy")] [ProtoMember(2)] public string MitigationStrategy { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as ModelCardEthicalConsideration); + } + + public bool Equals(ModelCardEthicalConsideration obj) + { + return obj != null && + (object.ReferenceEquals(this.MitigationStrategy, obj.MitigationStrategy) || + this.MitigationStrategy.Equals(obj.MitigationStrategy, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Name, obj.Name) || + this.Name.Equals(obj.Name, StringComparison.InvariantCultureIgnoreCase)); + } } [ProtoContract] - public class ModelCardFairnessAssessment + public class ModelCardFairnessAssessment : IEquatable { [XmlElement("groupAtRisk")] [ProtoMember(1)] @@ -58,6 +73,24 @@ public class ModelCardFairnessAssessment [XmlElement("mitigationStrategy")] [ProtoMember(4)] public string MitigationStrategy { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as ModelCardFairnessAssessment); + } + + public bool Equals(ModelCardFairnessAssessment obj) + { + return obj != null && + (object.ReferenceEquals(this.Benefits, obj.Benefits) || + this.Benefits.Equals(obj.Benefits, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.GroupAtRisk, obj.GroupAtRisk) || + this.GroupAtRisk.Equals(obj.GroupAtRisk, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Harms, obj.Harms) || + this.Harms.Equals(obj.Harms, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.MitigationStrategy, obj.MitigationStrategy) || + this.MitigationStrategy.Equals(obj.MitigationStrategy, StringComparison.InvariantCultureIgnoreCase)); + } } [XmlArray("users")] @@ -89,5 +122,27 @@ public class ModelCardFairnessAssessment [XmlArrayItem("fairnessAssessment")] [ProtoMember(6)] public List FairnessAssessments { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as ModelCardConsiderations); + } + + public bool Equals(ModelCardConsiderations obj) + { + return obj != null && + (object.ReferenceEquals(this.EthicalConsiderations, obj.EthicalConsiderations) || + this.EthicalConsiderations.SequenceEqual(obj.EthicalConsiderations)) && + (object.ReferenceEquals(this.FairnessAssessments, obj.FairnessAssessments) || + this.FairnessAssessments.SequenceEqual(obj.FairnessAssessments)) && + (object.ReferenceEquals(this.PerformanceTradeoffs, obj.PerformanceTradeoffs) || + this.PerformanceTradeoffs.SequenceEqual(obj.PerformanceTradeoffs)) && + (object.ReferenceEquals(this.TechnicalLimitations, obj.TechnicalLimitations) || + this.TechnicalLimitations.SequenceEqual(obj.TechnicalLimitations)) && + (object.ReferenceEquals(this.UseCases, obj.UseCases) || + this.UseCases.SequenceEqual(obj.UseCases)) && + (object.ReferenceEquals(this.Users, obj.Users) || + this.Users.SequenceEqual(obj.Users)); + } } } \ No newline at end of file diff --git a/src/CycloneDX.Core/Models/ModelParameters.cs b/src/CycloneDX.Core/Models/ModelParameters.cs index a568bb54..9da5b8e7 100644 --- a/src/CycloneDX.Core/Models/ModelParameters.cs +++ b/src/CycloneDX.Core/Models/ModelParameters.cs @@ -26,18 +26,29 @@ namespace CycloneDX.Models { [XmlType("model-parameters")] [ProtoContract] - public class ModelParameters + public class ModelParameters : IEquatable { [ProtoContract] - public class ModelApproach + public class ModelApproach : IEquatable { [XmlElement("type")] [ProtoMember(1)] - public ModelCard.ModelParameterApproachType Type { get; set; } + public ModelCard.ModelParameterApproachType Type { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as ModelApproach); + } + + public bool Equals(ModelApproach obj) + { + return obj != null && + (this.Type == obj.Type); + } } [ProtoContract] - public class ModelDataset + public class ModelDataset : IEquatable { [XmlElement("dataset")] [ProtoMember(1)] @@ -45,15 +56,41 @@ public class ModelDataset [XmlElement("ref")] [ProtoMember(2)] - public string Ref { get; set; } + public string Ref { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as ModelDataset); + } + + public bool Equals(ModelDataset obj) + { + return obj != null && + (object.ReferenceEquals(this.Data, obj.Data) || + this.Data.Equals(obj.Data)) && + (object.ReferenceEquals(this.Ref, obj.Ref) || + this.Ref.Equals(obj.Ref, StringComparison.InvariantCultureIgnoreCase)); + } } [ProtoContract] - public class MachineLearningInputOutputParameter + public class MachineLearningInputOutputParameter : IEquatable { [XmlElement("format")] [ProtoMember(1)] public string Format { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as MachineLearningInputOutputParameter); + } + + public bool Equals(MachineLearningInputOutputParameter obj) + { + return obj != null && + (object.ReferenceEquals(this.Format, obj.Format) || + this.Format.Equals(obj.Format, StringComparison.InvariantCultureIgnoreCase)); + } } [XmlElement("approach")] @@ -85,5 +122,29 @@ public class MachineLearningInputOutputParameter [XmlArrayItem("output")] [ProtoMember(7)] public List Outputs { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as ModelParameters); + } + + public bool Equals(ModelParameters obj) + { + return obj != null && + (object.ReferenceEquals(this.Approach, obj.Approach) || + this.Approach.Equals(obj.Approach)) && + (object.ReferenceEquals(this.ArchitectureFamily, obj.ArchitectureFamily) || + this.ArchitectureFamily.Equals(obj.ArchitectureFamily , StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Datasets, obj.Datasets) || + this.Datasets.Equals(obj.Datasets)) && + (object.ReferenceEquals(this.Inputs, obj.Inputs) || + this.Inputs.Equals(obj.Inputs)) && + (object.ReferenceEquals(this.ModelArchitecture, obj.ModelArchitecture) || + this.ModelArchitecture.Equals(obj.ModelArchitecture)) && + (object.ReferenceEquals(this.Outputs, obj.Outputs) || + this.Outputs.Equals(obj.Outputs)) && + (object.ReferenceEquals(this.Task, obj.Task) || + this.Task.Equals(obj.Task, StringComparison.InvariantCultureIgnoreCase)); + } } } \ No newline at end of file diff --git a/src/CycloneDX.Core/Models/Note.cs b/src/CycloneDX.Core/Models/Note.cs index feaea13e..e0ee33cc 100644 --- a/src/CycloneDX.Core/Models/Note.cs +++ b/src/CycloneDX.Core/Models/Note.cs @@ -15,13 +15,14 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright (c) OWASP Foundation. All Rights Reserved. +using System; using System.Xml.Serialization; using ProtoBuf; namespace CycloneDX.Models { [ProtoContract] - public class Note + public class Note : IEquatable { [XmlElement("locale")] [ProtoMember(1)] @@ -30,5 +31,19 @@ public class Note [XmlElement("text")] [ProtoMember(2)] public AttachedText Text { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as Note); + } + + public bool Equals(Note obj) + { + return obj != null && + (object.ReferenceEquals(this.Locale, obj.Locale) || + this.Locale.Equals(obj.Locale, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Text, obj.Text) || + this.Text.Equals(obj.Text)); + } } } diff --git a/src/CycloneDX.Core/Models/OrganizationalContact.cs b/src/CycloneDX.Core/Models/OrganizationalContact.cs index de677b62..54bf138d 100644 --- a/src/CycloneDX.Core/Models/OrganizationalContact.cs +++ b/src/CycloneDX.Core/Models/OrganizationalContact.cs @@ -15,6 +15,7 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright (c) OWASP Foundation. All Rights Reserved. +using System; using System.Text.Json.Serialization; using System.Xml.Serialization; using ProtoBuf; @@ -22,7 +23,7 @@ namespace CycloneDX.Models { [ProtoContract] - public class OrganizationalContact + public class OrganizationalContact : IEquatable { [XmlElement("name")] [ProtoMember(1)] @@ -40,5 +41,23 @@ public class OrganizationalContact [XmlAttribute("bom-ref")] [ProtoMember(4)] public string BomRef { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as OrganizationalContact); + } + + public bool Equals(OrganizationalContact obj) + { + return obj != null && + (object.ReferenceEquals(this.BomRef, obj.BomRef) || + this.BomRef.Equals(obj.BomRef, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Email, obj.Email) || + this.Email.Equals(obj.Email, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Name, obj.Name) || + this.Name.Equals(obj.Name, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Phone, obj.Phone) || + this.Phone.Equals(obj.Phone, StringComparison.InvariantCultureIgnoreCase)); + } } } diff --git a/src/CycloneDX.Core/Models/OrganizationalEntity.cs b/src/CycloneDX.Core/Models/OrganizationalEntity.cs index 77f60c03..441876be 100644 --- a/src/CycloneDX.Core/Models/OrganizationalEntity.cs +++ b/src/CycloneDX.Core/Models/OrganizationalEntity.cs @@ -15,7 +15,9 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright (c) OWASP Foundation. All Rights Reserved. +using System; using System.Collections.Generic; +using System.Linq; using System.Text.Json.Serialization; using System.Xml.Serialization; using ProtoBuf; @@ -23,7 +25,7 @@ namespace CycloneDX.Models { [ProtoContract] - public class OrganizationalEntity + public class OrganizationalEntity : IEquatable { [XmlElement("name")] [ProtoMember(1)] @@ -41,5 +43,23 @@ public class OrganizationalEntity [XmlAttribute("bom-ref")] [ProtoMember(4)] public string BomRef { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as OrganizationalEntity); + } + + public bool Equals(OrganizationalEntity obj) + { + return obj != null && + (object.ReferenceEquals(this.BomRef, obj.BomRef) || + this.BomRef.Equals(obj.BomRef, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Contact, obj.Contact) || + this.Contact.SequenceEqual(obj.Contact)) && + (object.ReferenceEquals(this.Name, obj.Name) || + this.Name.Equals(obj.Name, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Url, obj.Url) || + this.Url.SequenceEqual(obj.Url)); + } } } diff --git a/src/CycloneDX.Core/Models/OrganizationalEntityOrContact.cs b/src/CycloneDX.Core/Models/OrganizationalEntityOrContact.cs index 9db9fb40..f981d4dc 100644 --- a/src/CycloneDX.Core/Models/OrganizationalEntityOrContact.cs +++ b/src/CycloneDX.Core/Models/OrganizationalEntityOrContact.cs @@ -15,13 +15,14 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright (c) OWASP Foundation. All Rights Reserved. +using System; using System.Xml.Serialization; using ProtoBuf; namespace CycloneDX.Models { [ProtoContract] - public class OrganizationalEntityOrContact + public class OrganizationalEntityOrContact : IEquatable { [XmlElement("organization")] [ProtoMember(1)] @@ -30,5 +31,19 @@ public class OrganizationalEntityOrContact [XmlElement("individual")] [ProtoMember(2)] public OrganizationalContact Individual { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as OrganizationalEntityOrContact); + } + + public bool Equals(OrganizationalEntityOrContact obj) + { + return obj != null && + (object.ReferenceEquals(this.Individual, obj.Individual) || + this.Individual.Equals(obj.Individual)) && + (object.ReferenceEquals(this.Organization, obj.Organization) || + this.Organization.Equals(obj.Organization)); + } } } diff --git a/src/CycloneDX.Core/Models/Output.cs b/src/CycloneDX.Core/Models/Output.cs index 001e227b..7c32e160 100644 --- a/src/CycloneDX.Core/Models/Output.cs +++ b/src/CycloneDX.Core/Models/Output.cs @@ -18,6 +18,7 @@ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using System.Linq; using System.Text.Json.Serialization; using System.Xml.Serialization; using ProtoBuf; @@ -26,7 +27,7 @@ namespace CycloneDX.Models { [XmlType("output")] [ProtoContract] - public class Output + public class Output : IEquatable { [ProtoContract] public enum OutputType @@ -76,5 +77,28 @@ public enum OutputType [ProtoMember(7)] public List Properties { get; set; } public bool ShouldSerializeProperties() { return Properties?.Count > 0; } + + public override bool Equals(object obj) + { + return Equals(obj as Output); + } + + public bool Equals(Output obj) + { + return obj != null && + (object.ReferenceEquals(this.Data, obj.Data) || + this.Data.Equals(obj.Data)) && + (object.ReferenceEquals(this.EnvironmentVars, obj.EnvironmentVars) || + this.EnvironmentVars.Equals(obj.EnvironmentVars)) && + (object.ReferenceEquals(this.Properties, obj.Properties) || + this.Properties.SequenceEqual(obj.Properties)) && + (object.ReferenceEquals(this.Resource, obj.Resource) || + this.Resource.Equals(obj.Resource)) && + (object.ReferenceEquals(this.Source, obj.Source) || + this.Source.Equals(obj.Source)) && + (object.ReferenceEquals(this.Target, obj.Target) || + this.Target.Equals(obj.Target)) && + (this.Type.Equals(obj.Type)); + } } } \ No newline at end of file diff --git a/src/CycloneDX.Core/Models/Parameter.cs b/src/CycloneDX.Core/Models/Parameter.cs index 4de2b485..fc7056a4 100644 --- a/src/CycloneDX.Core/Models/Parameter.cs +++ b/src/CycloneDX.Core/Models/Parameter.cs @@ -15,13 +15,14 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright (c) OWASP Foundation. All Rights Reserved. +using System; using System.Xml.Serialization; using ProtoBuf; namespace CycloneDX.Models { [ProtoContract] - public class Parameter + public class Parameter : IEquatable { [XmlElement("name")] [ProtoMember(1)] @@ -34,5 +35,22 @@ public class Parameter [XmlElement("data-type")] [ProtoMember(3)] public string DataType { get; set; } + + + public override bool Equals(object obj) + { + return Equals(obj as Parameter); + } + + public bool Equals(Parameter obj) + { + return obj != null && + (object.ReferenceEquals(this.DataType, obj.DataType) || + this.DataType.Equals(obj.DataType, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Name, obj.Name) || + this.Name.Equals(obj.Name, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Value, obj.Value) || + this.Value.Equals(obj.Value, StringComparison.InvariantCultureIgnoreCase)); + } } } diff --git a/src/CycloneDX.Core/Models/Patch.cs b/src/CycloneDX.Core/Models/Patch.cs index cdc5e2cf..68130cfa 100644 --- a/src/CycloneDX.Core/Models/Patch.cs +++ b/src/CycloneDX.Core/Models/Patch.cs @@ -15,14 +15,16 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright (c) OWASP Foundation. All Rights Reserved. +using System; using System.Collections.Generic; +using System.Linq; using System.Xml.Serialization; using ProtoBuf; namespace CycloneDX.Models { [ProtoContract] - public class Patch + public class Patch : IEquatable { [ProtoContract] public enum PatchClassification @@ -51,5 +53,20 @@ public enum PatchClassification [XmlArrayItem("issue")] [ProtoMember(3)] public List Resolves { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as Patch); + } + + public bool Equals(Patch obj) + { + return obj != null && + (object.ReferenceEquals(this.Diff, obj.Diff) || + this.Diff.Equals(obj.Diff)) && + (object.ReferenceEquals(this.Resolves, obj.Resolves) || + this.Resolves.SequenceEqual(obj.Resolves)) && + (this.Type == obj.Type); + } } } diff --git a/src/CycloneDX.Core/Models/Pedigree.cs b/src/CycloneDX.Core/Models/Pedigree.cs index 537d6e87..07f584c3 100644 --- a/src/CycloneDX.Core/Models/Pedigree.cs +++ b/src/CycloneDX.Core/Models/Pedigree.cs @@ -15,14 +15,16 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright (c) OWASP Foundation. All Rights Reserved. +using System; using System.Collections.Generic; +using System.Linq; using System.Xml.Serialization; using ProtoBuf; namespace CycloneDX.Models { [ProtoContract] - public class Pedigree + public class Pedigree : IEquatable { [XmlArray("ancestors")] [XmlArrayItem("component")] @@ -53,5 +55,27 @@ public class Pedigree [XmlElement("notes")] [ProtoMember(6)] public string Notes { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as Annotation); + } + + public bool Equals(Pedigree obj) + { + return obj != null && + (object.ReferenceEquals(this.Ancestors, obj.Ancestors) || + this.Ancestors.SequenceEqual(obj.Ancestors)) && + (object.ReferenceEquals(this.Commits, obj.Commits) || + this.Commits.SequenceEqual(obj.Commits)) && + (object.ReferenceEquals(this.Descendants, obj.Descendants) || + this.Descendants.SequenceEqual(obj.Descendants)) && + (object.ReferenceEquals(this.Notes, obj.Notes) || + this.Notes.Equals(obj.Notes, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Patches, obj.Patches) || + this.Patches.SequenceEqual(obj.Patches)) && + (object.ReferenceEquals(this.Variants, obj.Variants) || + this.Variants.SequenceEqual(obj.Variants)); + } } } diff --git a/src/CycloneDX.Core/Models/Property.cs b/src/CycloneDX.Core/Models/Property.cs index a61b45f2..dfb5fa42 100644 --- a/src/CycloneDX.Core/Models/Property.cs +++ b/src/CycloneDX.Core/Models/Property.cs @@ -15,6 +15,7 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright (c) OWASP Foundation. All Rights Reserved. +using System; using System.Collections.Generic; using System.Xml.Serialization; using ProtoBuf; @@ -22,7 +23,7 @@ namespace CycloneDX.Models { [ProtoContract] - public class Property + public class Property : IEquatable { [XmlAttribute("name")] [ProtoMember(1)] @@ -31,5 +32,19 @@ public class Property [XmlText] [ProtoMember(2)] public string Value { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as Property); + } + + public bool Equals(Property obj) + { + return obj != null && + (object.ReferenceEquals(this.Name, obj.Name) || + this.Name.Equals(obj.Name, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Value, obj.Value) || + this.Value.Equals(obj.Value, StringComparison.InvariantCultureIgnoreCase)); + } } } diff --git a/src/CycloneDX.Core/Models/ReleaseNotes.cs b/src/CycloneDX.Core/Models/ReleaseNotes.cs index b8a33ce9..01bbb7b4 100644 --- a/src/CycloneDX.Core/Models/ReleaseNotes.cs +++ b/src/CycloneDX.Core/Models/ReleaseNotes.cs @@ -17,13 +17,14 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Xml.Serialization; using ProtoBuf; namespace CycloneDX.Models { [ProtoContract] - public class ReleaseNotes + public class ReleaseNotes : IEquatable { [XmlElement("type")] [ProtoMember(1)] @@ -79,5 +80,35 @@ public DateTime? Timestamp [XmlArrayItem("property")] [ProtoMember(11)] public List Properties { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as ReleaseNotes); + } + + public bool Equals(ReleaseNotes obj) + { + return obj != null && + (object.ReferenceEquals(this.Aliases, obj.Aliases) || + this.Aliases.SequenceEqual(obj.Aliases)) && + (object.ReferenceEquals(this.Description, obj.Description) || + this.Description.Equals(obj.Description, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.FeaturedImage, obj.FeaturedImage) || + this.FeaturedImage.Equals(obj.FeaturedImage, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Notes, obj.Notes) || + this.Notes.SequenceEqual(obj.Notes)) && + (object.ReferenceEquals(this.Properties, obj.Properties) || + this.Properties.SequenceEqual(obj.Properties)) && + (object.ReferenceEquals(this.Resolves, obj.Resolves) || + this.Resolves.SequenceEqual(obj.Resolves)) && + (object.ReferenceEquals(this.SocialImage, obj.SocialImage) || + this.SocialImage.SequenceEqual(obj.SocialImage)) && + (object.ReferenceEquals(this.Tags, obj.Tags) || + this.Tags.SequenceEqual(obj.Tags)) && + (object.ReferenceEquals(this.Title, obj.Title) || + this.Title.Equals(obj.Title, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Type, obj.Type) || + this.Type.Equals(obj.Type, StringComparison.InvariantCultureIgnoreCase)); + } } } diff --git a/src/CycloneDX.Core/Models/ResourceReferenceChoice.cs b/src/CycloneDX.Core/Models/ResourceReferenceChoice.cs index dc8153b4..ae979c48 100644 --- a/src/CycloneDX.Core/Models/ResourceReferenceChoice.cs +++ b/src/CycloneDX.Core/Models/ResourceReferenceChoice.cs @@ -15,6 +15,7 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright (c) OWASP Foundation. All Rights Reserved. +using System; using System.Text.Json.Serialization; using System.Xml; using System.Xml.Serialization; @@ -23,7 +24,7 @@ namespace CycloneDX.Models { [ProtoContract] - public class ResourceReferenceChoice : IXmlSerializable + public class ResourceReferenceChoice : IEquatable, IXmlSerializable { private static XmlSerializer _extRefSerializer; private static XmlSerializer GetExternalReferenceSerializer() @@ -42,7 +43,22 @@ private static XmlSerializer GetExternalReferenceSerializer() [ProtoMember(2)] public ExternalReference ExternalReference { get; set; } - public System.Xml.Schema.XmlSchema GetSchema() { + public override bool Equals(object obj) + { + return Equals(obj as ResourceReferenceChoice); + } + + public bool Equals(ResourceReferenceChoice obj) + { + return obj != null && + (object.ReferenceEquals(this.ExternalReference, obj.ExternalReference) || + this.ExternalReference.Equals(obj.ExternalReference)) && + (object.ReferenceEquals(this.Ref, obj.Ref) || + this.Ref.Equals(obj.Ref, StringComparison.InvariantCultureIgnoreCase)); + } + + public System.Xml.Schema.XmlSchema GetSchema() + { return null; } @@ -61,8 +77,9 @@ public void ReadXml(XmlReader reader) } reader.ReadEndElement(); } - - public void WriteXml(XmlWriter writer) { + + public void WriteXml(XmlWriter writer) + { if (this.Ref != null) { writer.WriteElementString("ref", this.Ref); diff --git a/src/CycloneDX.Core/Models/ResourceReferenceChoices.cs b/src/CycloneDX.Core/Models/ResourceReferenceChoices.cs index eb47fbd5..dc3229f7 100644 --- a/src/CycloneDX.Core/Models/ResourceReferenceChoices.cs +++ b/src/CycloneDX.Core/Models/ResourceReferenceChoices.cs @@ -15,6 +15,7 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright (c) OWASP Foundation. All Rights Reserved. +using System; using System.Collections.Generic; using System.Text.Json.Serialization; using System.Xml; @@ -24,11 +25,24 @@ namespace CycloneDX.Models { [ProtoContract] - public class ResourceReferenceChoices : List, IXmlSerializable + public class ResourceReferenceChoices : List, IEquatable, IXmlSerializable { private string _elementName = "resourceReference"; - public System.Xml.Schema.XmlSchema GetSchema() { + public override bool Equals(object obj) + { + return Equals(obj as ResourceReferenceChoices); + } + + public bool Equals(ResourceReferenceChoices obj) + { + return obj != null && + (object.ReferenceEquals(this, obj) || + this.Equals(obj)); + } + + public System.Xml.Schema.XmlSchema GetSchema() + { return null; } @@ -43,8 +57,9 @@ public void ReadXml(XmlReader reader) } reader.ReadEndElement(); } - - public void WriteXml(XmlWriter writer) { + + public void WriteXml(XmlWriter writer) + { foreach (var resRefChoice in this) { writer.WriteStartElement(_elementName); @@ -52,5 +67,6 @@ public void WriteXml(XmlWriter writer) { writer.WriteEndElement(); } } + } } diff --git a/src/CycloneDX.Core/Models/ServiceDataChoices.cs b/src/CycloneDX.Core/Models/ServiceDataChoices.cs index 51a64076..6f7f1af2 100644 --- a/src/CycloneDX.Core/Models/ServiceDataChoices.cs +++ b/src/CycloneDX.Core/Models/ServiceDataChoices.cs @@ -17,6 +17,7 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Text.Json.Serialization; using System.Xml; using System.Xml.Serialization; @@ -25,7 +26,7 @@ namespace CycloneDX.Models { [ProtoContract] - public class ServiceDataChoices : IXmlSerializable + public class ServiceDataChoices : IEquatable, IXmlSerializable { internal SpecificationVersion SpecVersion { get; set; } @@ -37,7 +38,21 @@ public ServiceDataChoices() { SpecVersion = SpecificationVersionHelpers.CurrentVersion; } - + + public override bool Equals(object obj) + { + return Equals(obj as ServiceDataChoices); + } + + public bool Equals(ServiceDataChoices obj) + { + return obj != null && + (object.ReferenceEquals(this.DataClassifications, obj.DataClassifications) || + this.DataClassifications.SequenceEqual(obj.DataClassifications)) && + (object.ReferenceEquals(this.DataFlows, obj.DataFlows) || + this.DataFlows.SequenceEqual(obj.DataFlows)); + } + public System.Xml.Schema.XmlSchema GetSchema() { return null; } diff --git a/src/CycloneDX.Core/Models/Source.cs b/src/CycloneDX.Core/Models/Source.cs index 1c6bbead..92523288 100644 --- a/src/CycloneDX.Core/Models/Source.cs +++ b/src/CycloneDX.Core/Models/Source.cs @@ -15,13 +15,14 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright (c) OWASP Foundation. All Rights Reserved. +using System; using System.Xml.Serialization; using ProtoBuf; namespace CycloneDX.Models { [ProtoContract] - public class Source + public class Source : IEquatable { [XmlElement("name")] [ProtoMember(1)] @@ -30,5 +31,19 @@ public class Source [XmlElement("url")] [ProtoMember(2)] public string Url { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as Source); + } + + public bool Equals(Source obj) + { + return obj != null && + (object.ReferenceEquals(this.Name, obj.Name) || + this.Name.Equals(obj.Name, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Url, obj.Url) || + this.Url.Equals(obj.Url, StringComparison.InvariantCultureIgnoreCase)); + } } } diff --git a/src/CycloneDX.Core/Models/Step.cs b/src/CycloneDX.Core/Models/Step.cs index 962c1e1e..efc3ca26 100644 --- a/src/CycloneDX.Core/Models/Step.cs +++ b/src/CycloneDX.Core/Models/Step.cs @@ -18,6 +18,7 @@ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using System.Linq; using System.Text.Json.Serialization; using System.Xml.Serialization; using ProtoBuf; @@ -26,7 +27,7 @@ namespace CycloneDX.Models { [XmlType("step")] [ProtoContract] - public class Step + public class Step : IEquatable { [XmlElement("name")] [ProtoMember(1)] @@ -47,5 +48,23 @@ public class Step [ProtoMember(4)] public List Properties { get; set; } public bool ShouldSerializeProperties() { return Properties?.Count > 0; } + + public override bool Equals(object obj) + { + return Equals(obj as Step); + } + + public bool Equals(Step obj) + { + return obj != null && + (object.ReferenceEquals(this.Commands, obj.Commands) || + this.Commands.SequenceEqual(obj.Commands)) && + (object.ReferenceEquals(this.Description, obj.Description) || + this.Description.Equals(obj.Description, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Name, obj.Name) || + this.Name.Equals(obj.Name)) && + (object.ReferenceEquals(this.Properties, obj.Properties) || + this.Properties.SequenceEqual(obj.Properties)); + } } } \ No newline at end of file diff --git a/src/CycloneDX.Core/Models/Swid.cs b/src/CycloneDX.Core/Models/Swid.cs index 4a0ccac2..3aabc332 100644 --- a/src/CycloneDX.Core/Models/Swid.cs +++ b/src/CycloneDX.Core/Models/Swid.cs @@ -23,7 +23,7 @@ namespace CycloneDX.Models { [ProtoContract] - public class Swid + public class Swid : IEquatable { [XmlAttribute("tagId")] [ProtoMember(1)] @@ -52,5 +52,27 @@ public class Swid [XmlAttribute("url")] [ProtoMember(7)] public string Url { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as Swid); + } + + public bool Equals(Swid obj) + { + return obj != null && + (object.ReferenceEquals(this.Name, obj.Name) || + this.Name.Equals(obj.Name, StringComparison.InvariantCultureIgnoreCase)) && + (this.Patch.Equals(obj.Patch)) && + (object.ReferenceEquals(this.TagId, obj.TagId) || + this.TagId.Equals(obj.TagId, StringComparison.InvariantCultureIgnoreCase)) && + (this.TagVersion.Equals(obj.TagVersion)) && + (object.ReferenceEquals(this.Text, obj.Text) || + this.Text.Equals(obj.Text)) && + (object.ReferenceEquals(this.Url, obj.Url) || + this.Url.Equals(obj.Url, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Version, obj.Version) || + this.Version.Equals(obj.Version, StringComparison.InvariantCultureIgnoreCase)); + } } } diff --git a/src/CycloneDX.Core/Models/ToolChoices.cs b/src/CycloneDX.Core/Models/ToolChoices.cs index e9059e57..21862fbb 100644 --- a/src/CycloneDX.Core/Models/ToolChoices.cs +++ b/src/CycloneDX.Core/Models/ToolChoices.cs @@ -15,7 +15,9 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright (c) OWASP Foundation. All Rights Reserved. +using System; using System.Collections.Generic; +using System.Linq; using System.Text.Json.Serialization; using System.Xml; using System.Xml.Serialization; @@ -24,7 +26,7 @@ namespace CycloneDX.Models { [ProtoContract] - public class ToolChoices : IXmlSerializable + public class ToolChoices : IEquatable, IXmlSerializable { internal SpecificationVersion SpecVersion { get; set; } @@ -47,7 +49,24 @@ public ToolChoices() { SpecVersion = SpecificationVersionHelpers.CurrentVersion; } - + + + public override bool Equals(object obj) + { + return Equals(obj as ToolChoices); + } + + public bool Equals(ToolChoices obj) + { + return obj != null && + (object.ReferenceEquals(this.Components, obj.Components) || + this.Components.SequenceEqual(obj.Components)) && + (object.ReferenceEquals(this.Services, obj.Services) || + this.Services.SequenceEqual(obj.Services)) && + (object.ReferenceEquals(this.Tools, obj.Tools) || + this.Tools.SequenceEqual(obj.Tools)); + } + public System.Xml.Schema.XmlSchema GetSchema() { return null; } diff --git a/src/CycloneDX.Core/Models/Trigger.cs b/src/CycloneDX.Core/Models/Trigger.cs index 5b8407b2..d050464d 100644 --- a/src/CycloneDX.Core/Models/Trigger.cs +++ b/src/CycloneDX.Core/Models/Trigger.cs @@ -18,6 +18,7 @@ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using System.Linq; using System.Text.Json.Serialization; using System.Xml.Serialization; using ProtoBuf; @@ -26,7 +27,7 @@ namespace CycloneDX.Models { [XmlType("trigger")] [ProtoContract] - public class Trigger + public class Trigger : IEquatable { [ProtoContract] public enum TriggerType @@ -42,7 +43,7 @@ public enum TriggerType } [ProtoContract] - public class Condition + public class Condition : IEquatable { [XmlElement("description")] [ProtoMember(1)] @@ -57,6 +58,22 @@ public class Condition [ProtoMember(3)] public List Properties { get; set; } public bool ShouldSerializeProperties() { return Properties?.Count > 0; } + + public override bool Equals(object obj) + { + return Equals(obj as Condition); + } + + public bool Equals(Condition obj) + { + return obj != null && + (object.ReferenceEquals(this.Description, obj.Description) || + this.Description.Equals(obj.Description, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Expression, obj.Expression) || + this.Expression.Equals(obj.Expression, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Properties, obj.Properties) || + this.Properties.SequenceEqual(obj.Properties)); + } } [JsonPropertyName("bom-ref")] @@ -120,5 +137,37 @@ public DateTime? TimeActivated [ProtoMember(5)] public List Properties { get; set; } public bool ShouldSerializeProperties() { return Properties?.Count > 0; } + + public override bool Equals(object obj) + { + return Equals(obj as Trigger); + } + + public bool Equals(Trigger obj) + { + return obj != null && + (object.ReferenceEquals(this.BomRef, obj.BomRef) || + this.BomRef.Equals(obj.BomRef, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Conditions, obj.Conditions) || + this.Conditions.SequenceEqual(obj.Conditions)) && + (object.ReferenceEquals(this.Description, obj.Description) || + this.Description.Equals(obj.Description, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Event, obj.Event) || + this.Event.Equals(obj.Event)) && + (object.ReferenceEquals(this.Inputs, obj.Inputs) || + this.Inputs.SequenceEqual(obj.Inputs)) && + (object.ReferenceEquals(this.Name, obj.Name) || + this.Name.SequenceEqual(obj.Name)) && + (object.ReferenceEquals(this.Outputs, obj.Outputs) || + this.Outputs.SequenceEqual(obj.Outputs)) && + (object.ReferenceEquals(this.Properties, obj.Properties) || + this.Properties.SequenceEqual(obj.Properties)) && + (object.ReferenceEquals(this.ResourceReferences, obj.ResourceReferences) || + this.ResourceReferences.SequenceEqual(obj.ResourceReferences)) && + (this.TimeActivated.Equals(obj.TimeActivated)) && + (this.Type.Equals(obj.Type)) && + (object.ReferenceEquals(this.Uid, obj.Uid) || + this.Uid.Equals(obj.Uid, StringComparison.InvariantCultureIgnoreCase)); + } } } \ No newline at end of file diff --git a/src/CycloneDX.Core/Models/Volume.cs b/src/CycloneDX.Core/Models/Volume.cs index 25a76eeb..63a7f1a2 100644 --- a/src/CycloneDX.Core/Models/Volume.cs +++ b/src/CycloneDX.Core/Models/Volume.cs @@ -18,6 +18,7 @@ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using System.Linq; using System.Text.Json.Serialization; using System.Xml.Serialization; using ProtoBuf; @@ -26,7 +27,7 @@ namespace CycloneDX.Models { [XmlType("volume")] [ProtoContract] - public class Volume + public class Volume : IEquatable { [ProtoContract] public enum VolumeMode @@ -100,5 +101,30 @@ public bool NonNullableRemote [ProtoMember(8)] public List Properties { get; set; } public bool ShouldSerializeProperties() { return Properties?.Count > 0; } + + public override bool Equals(object obj) + { + return Equals(obj as Volume); + } + + public bool Equals(Volume obj) + { + return obj != null && + (this.Mode.Equals(obj.Mode)) && + (object.ReferenceEquals(this.Name, obj.Name) || + this.Name.Equals(obj.Name, StringComparison.InvariantCultureIgnoreCase)) && + (this.NonNullablePersistent.Equals(obj.NonNullablePersistent)) && + (this.NonNullableRemote.Equals(obj.NonNullableRemote)) && + (object.ReferenceEquals(this.Path, obj.Path) || + this.Name.Equals(obj.Path, StringComparison.InvariantCultureIgnoreCase)) && + (this.Persistent.Equals(obj.Persistent)) && + (object.ReferenceEquals(this.Properties, obj.Properties) || + this.Properties.SequenceEqual(obj.Properties)) && + (this.Remote.Equals(obj.Remote)) && + (object.ReferenceEquals(this.SizeAllocated, obj.SizeAllocated) || + this.SizeAllocated.Equals(obj.SizeAllocated)) && + (object.ReferenceEquals(this.Uid, obj.Uid) || + this.Uid.Equals(obj.Uid)); + } } } \ No newline at end of file diff --git a/src/CycloneDX.Core/Models/Workflow.cs b/src/CycloneDX.Core/Models/Workflow.cs index 88d630e3..cbea53c4 100644 --- a/src/CycloneDX.Core/Models/Workflow.cs +++ b/src/CycloneDX.Core/Models/Workflow.cs @@ -18,6 +18,7 @@ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using System.Linq; using System.Text.Json.Serialization; using System.Xml.Serialization; using ProtoBuf; @@ -26,7 +27,7 @@ namespace CycloneDX.Models { [XmlType("workflow")] [ProtoContract] - public class Workflow + public class Workflow : IEquatable { [JsonPropertyName("bom-ref")] [XmlAttribute("bom-ref")] @@ -117,5 +118,47 @@ public DateTime? TimeEnd [ProtoMember(5)] public List Properties { get; set; } public bool ShouldSerializeProperties() { return Properties?.Count > 0; } + + public override bool Equals(object obj) + { + return Equals(obj as Workflow); + } + + public bool Equals(Workflow obj) + { + return obj != null && + (object.ReferenceEquals(this.BomRef, obj.BomRef) || + this.BomRef.Equals(obj.BomRef, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Description, obj.Description) || + this.Description.Equals(obj.Description, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Inputs, obj.Inputs) || + this.Inputs.SequenceEqual(obj.Inputs)) && + (object.ReferenceEquals(this.Name, obj.Name) || + this.Name.Equals(obj.Name, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Outputs, obj.Outputs) || + this.Outputs.SequenceEqual(obj.Outputs)) && + (object.ReferenceEquals(this.Properties, obj.Properties) || + this.Properties.SequenceEqual(obj.Properties)) && + (object.ReferenceEquals(this.ResourceReferences, obj.ResourceReferences) || + this.ResourceReferences.Equals(obj.ResourceReferences)) && + (object.ReferenceEquals(this.RuntimeTopologies, obj.RuntimeTopologies) || + this.RuntimeTopologies.SequenceEqual(obj.RuntimeTopologies)) && + (object.ReferenceEquals(this.Steps, obj.Steps) || + this.Steps.SequenceEqual(obj.Steps)) && + (object.ReferenceEquals(this.TaskDependencies, obj.TaskDependencies) || + this.TaskDependencies.Equals(obj.TaskDependencies)) && + (object.ReferenceEquals(this.Tasks, obj.Tasks) || + this.Tasks.Equals(obj.Tasks)) && + (object.ReferenceEquals(this.TaskTypes, obj.TaskTypes) || + this.TaskTypes.Equals(obj.TaskTypes)) && + (this.TimeEnd.Equals(obj.TimeEnd)) && + (this.TimeStart.Equals(obj.TimeStart)) && + (object.ReferenceEquals(this.Trigger, obj.Trigger) || + this.Trigger.Equals(obj.Trigger)) && + (object.ReferenceEquals(this.Uid, obj.Uid) || + this.Uid.Equals(obj.Uid)) && + (object.ReferenceEquals(this.Workspaces, obj.Workspaces) || + this.Workspaces.SequenceEqual(obj.Workspaces)); + } } } \ No newline at end of file diff --git a/src/CycloneDX.Core/Models/WorkflowTask.cs b/src/CycloneDX.Core/Models/WorkflowTask.cs index 9eb0d514..69997264 100644 --- a/src/CycloneDX.Core/Models/WorkflowTask.cs +++ b/src/CycloneDX.Core/Models/WorkflowTask.cs @@ -18,6 +18,7 @@ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using System.Linq; using System.Text.Json.Serialization; using System.Xml.Serialization; using ProtoBuf; @@ -26,7 +27,7 @@ namespace CycloneDX.Models { [XmlType("task")] [ProtoContract] - public class WorkflowTask + public class WorkflowTask : IEquatable { [ProtoContract] public enum TaskType @@ -134,5 +135,43 @@ public DateTime? TimeEnd [XmlArrayItem("dependency")] [ProtoMember(17)] public List RuntimeTopologies { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as WorkflowTask); + } + + public bool Equals(WorkflowTask obj) + { + return obj != null && + (object.ReferenceEquals(this.BomRef, obj.BomRef) || + this.BomRef.Equals(obj.BomRef, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Description, obj.Description) || + this.Description.Equals(obj.Description, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Inputs, obj.Inputs) || + this.Inputs.SequenceEqual(obj.Inputs)) && + (object.ReferenceEquals(this.Name, obj.Name) || + this.Name.Equals(obj.Name, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Outputs, obj.Outputs) || + this.Outputs.SequenceEqual(obj.Outputs)) && + (object.ReferenceEquals(this.Properties, obj.Properties) || + this.Properties.SequenceEqual(obj.Properties)) && + (object.ReferenceEquals(this.ResourceReferences, obj.ResourceReferences) || + this.ResourceReferences.Equals(obj.ResourceReferences)) && + (object.ReferenceEquals(this.ResourceReferences, obj.RuntimeTopologies) || + this.RuntimeTopologies.SequenceEqual(obj.RuntimeTopologies)) && + (object.ReferenceEquals(this.Steps, obj.Steps) || + this.Steps.SequenceEqual(obj.Steps)) && + (object.ReferenceEquals(this.TaskTypes, obj.TaskTypes) || + this.TaskTypes.SequenceEqual(obj.TaskTypes)) && + (this.TimeEnd.Equals(obj.TimeEnd)) && + (this.TimeStart.Equals(obj.TimeStart)) && + (object.ReferenceEquals(this.Trigger, obj.Trigger) || + this.Trigger.Equals(obj.Trigger)) && + (object.ReferenceEquals(this.Uid, obj.Uid) || + this.Uid.Equals(obj.Uid)) && + (object.ReferenceEquals(this.Workspaces, obj.Workspaces) || + this.Workspaces.SequenceEqual(obj.Workspaces)); + } } } \ No newline at end of file diff --git a/src/CycloneDX.Core/Models/Workspace.cs b/src/CycloneDX.Core/Models/Workspace.cs index ccc43f79..d76ac01d 100644 --- a/src/CycloneDX.Core/Models/Workspace.cs +++ b/src/CycloneDX.Core/Models/Workspace.cs @@ -18,6 +18,7 @@ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using System.Linq; using System.Text.Json.Serialization; using System.Xml.Serialization; using ProtoBuf; @@ -26,7 +27,7 @@ namespace CycloneDX.Models { [XmlType("workspace")] [ProtoContract] - public class Workspace + public class Workspace : IEquatable { [ProtoContract] public enum AccessModeType @@ -96,5 +97,38 @@ public enum AccessModeType [XmlElement("volume")] [ProtoMember(12)] public Volume Volume { get; set; } + + public override bool Equals(object obj) + { + return Equals(obj as Workspace); + } + + public bool Equals(Workspace obj) + { + return obj != null && + (this.AccessMode.Equals(obj.AccessMode)) && + (object.ReferenceEquals(this.Aliases, obj.Aliases) || + this.Aliases.SequenceEqual(obj.Aliases)) && + (object.ReferenceEquals(this.BomRef, obj.BomRef) || + this.BomRef.Equals(obj.BomRef)) && + (object.ReferenceEquals(this.Description, obj.Description) || + this.Description.Equals(obj.Description)) && + (object.ReferenceEquals(this.ManagedDateType, obj.ManagedDateType) || + this.ManagedDateType.Equals(obj.ManagedDateType, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.MountPath, obj.MountPath) || + this.MountPath.Equals(obj.MountPath, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Name, obj.Name) || + this.Name.Equals(obj.Name, StringComparison.InvariantCultureIgnoreCase)) && + (object.ReferenceEquals(this.Properties, obj.Properties) || + this.Properties.SequenceEqual(obj.Properties)) && + (object.ReferenceEquals(this.ResourceReferences, obj.ResourceReferences) || + this.ResourceReferences.Equals(obj.ResourceReferences)) && + (object.ReferenceEquals(this.Uid, obj.Uid) || + this.Uid.Equals(obj.Uid)) && + (object.ReferenceEquals(this.Volume, obj.Volume) || + this.Volume.Equals(obj.Volume)) && + (object.ReferenceEquals(this.VolumeRequest, obj.VolumeRequest) || + this.VolumeRequest.Equals(obj.VolumeRequest)); + } } } \ No newline at end of file