Skip to content

Commit

Permalink
Add properties on license (#262)
Browse files Browse the repository at this point in the history
  • Loading branch information
DarthHater authored and mr-zepol committed Jul 15, 2023
1 parent df381f7 commit 6be7bda
Show file tree
Hide file tree
Showing 9 changed files with 95 additions and 11 deletions.
22 changes: 19 additions & 3 deletions src/main/java/org/cyclonedx/model/License.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,20 @@
*/
package org.cyclonedx.model;

import java.util.List;
import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.annotation.JsonRootName;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;

@SuppressWarnings("unused")
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({"id", "name", "text", "url"})
@JsonPropertyOrder({"id", "name", "text", "url", "properties"})
@JsonRootName("license")
public class License extends ExtensibleElement {

Expand All @@ -43,6 +45,9 @@ public class License extends ExtensibleElement {
private AttachmentText attachmentText;
private String url;

@VersionFilter(versions = {"1.1", "1.2", "1.3", "1.4"})
private List<Property> properties;

public String getId() {
return id;
}
Expand All @@ -67,6 +72,16 @@ public void setUrl(String url) {
this.url = url;
}

@JacksonXmlElementWrapper(localName = "properties")
@JacksonXmlProperty(localName = "property")
public List<Property> getProperties() {
return properties;
}

public void setProperties(final List<Property> properties) {
this.properties = properties;
}

public AttachmentText getAttachmentText() {
return attachmentText;
}
Expand All @@ -83,11 +98,12 @@ public boolean equals(Object o) {
return Objects.equals(id, license.id) &&
Objects.equals(name, license.name) &&
Objects.equals(url, license.url) &&
Objects.equals(attachmentText, license.attachmentText);
Objects.equals(attachmentText, license.attachmentText) &&
Objects.equals(properties, license.properties);
}

@Override
public int hashCode() {
return Objects.hash(id, name, url, attachmentText);
return Objects.hash(id, name, url, attachmentText, properties);
}
}
2 changes: 2 additions & 0 deletions src/main/resources/bom-1.5.proto
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,8 @@ message License {
optional string bom_ref = 5;
// Licensing details describing the licensor/licensee, license type, renewal and expiration dates, and other important metadata
optional Licensing licensing = 6;
// Specifies optional, custom, properties
repeated Property properties = 7;
}

message Licensing {
Expand Down
9 changes: 9 additions & 0 deletions src/main/resources/bom-1.5.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -789,6 +789,15 @@
"description": "The timestamp indicating when the current license expires (if applicable)."
}
}
},
"properties": {
"type": "array",
"title": "Properties",
"description": "Provides the ability to document properties in a name-value store. This provides flexibility to include data not officially supported in the standard without having to use additional namespaces or create extensions. Unlike key-value stores, properties support duplicate names, each potentially having different values. Property names of interest to the general public are encouraged to be registered in the [CycloneDX Property Taxonomy](https://github.com/CycloneDX/cyclonedx-property-taxonomy). Formal registration is OPTIONAL.",
"additionalItems": false,
"items": {
"$ref": "#/definitions/property"
}
}
}
},
Expand Down
24 changes: 22 additions & 2 deletions src/test/java/org/cyclonedx/parsers/JsonParserTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import org.cyclonedx.model.Component;
import org.cyclonedx.model.Dependency;
import org.cyclonedx.model.ExternalReference;
import org.cyclonedx.model.License;
import org.cyclonedx.model.LicenseChoice;
import org.cyclonedx.model.Metadata;
import org.cyclonedx.model.OrganizationalContact;
import org.cyclonedx.model.OrganizationalEntity;
Expand Down Expand Up @@ -523,7 +525,10 @@ private void assertComponent(final Bom bom, final Version version) {
assertEquals(Component.Type.LIBRARY, component.getType());
assertEquals("pkg:maven/com.acme/jackson-databind@2.9.4", component.getPurl());
assertEquals(12, component.getHashes().size());
assertNotNull(component.getLicenseChoice().getExpression());

//Licenses
assertLicense(component.getLicenseChoice(), version);

assertEquals("Copyright Example Inc. All rights reserved.", component.getCopyright());
assertEquals("Acme Application", component.getSwid().getName());
assertEquals("9.1.1", component.getSwid().getVersion());
Expand All @@ -547,12 +552,27 @@ private void assertComponent(final Bom bom, final Version version) {
component.getEvidence().getLicenseChoice().getLicenses().get(0).getUrl());
}

private void assertSecurityContact(ExternalReference externalReference){
private void assertSecurityContact(ExternalReference externalReference) {
assertEquals(externalReference.getType(), ExternalReference.Type.SECURITY_CONTACT);
assertEquals(externalReference.getComment(), "test");
assertEquals(externalReference.getUrl(), "http://example.org/docs");
}

private void assertLicense(LicenseChoice licenseChoice, final Version version) {
assertNotNull(licenseChoice);
assertNull(licenseChoice.getExpression());

assertEquals(licenseChoice.getLicenses().size(), 1);
License license = licenseChoice.getLicenses().get(0);

if (version == Version.VERSION_15) {
assertEquals(license.getProperties().size(), 1);
}
else {
assertNull(license.getProperties());
}
}

private void assertMetadata(final Metadata metadata) {
assertNotNull(metadata);
assertNotNull(metadata.getTimestamp());
Expand Down
24 changes: 22 additions & 2 deletions src/test/java/org/cyclonedx/parsers/XmlParserTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import org.cyclonedx.model.Component;
import org.cyclonedx.model.Dependency;
import org.cyclonedx.model.ExternalReference;
import org.cyclonedx.model.License;
import org.cyclonedx.model.LicenseChoice;
import org.cyclonedx.model.Metadata;
import org.cyclonedx.model.OrganizationalContact;
import org.cyclonedx.model.OrganizationalEntity;
Expand Down Expand Up @@ -666,7 +668,10 @@ private void assertComponent(final Bom bom, final Version version) {
assertEquals(Component.Type.LIBRARY, component.getType());
assertEquals("pkg:maven/com.acme/jackson-databind@2.9.4", component.getPurl());
assertEquals(12, component.getHashes().size());
assertNotNull(component.getLicenseChoice().getExpression());

//Licenses
assertLicense(component.getLicenseChoice(), version);

assertEquals("Copyright Example Inc. All rights reserved.", component.getCopyright());
assertEquals("Acme Application", component.getSwid().getName());
assertEquals("9.1.1", component.getSwid().getVersion());
Expand All @@ -690,12 +695,27 @@ private void assertComponent(final Bom bom, final Version version) {
component.getEvidence().getLicenseChoice().getLicenses().get(0).getUrl());
}

private void assertSecurityContact(ExternalReference externalReference){
private void assertSecurityContact(ExternalReference externalReference) {
assertEquals(externalReference.getType(), ExternalReference.Type.SECURITY_CONTACT);
assertEquals(externalReference.getComment(), "test");
assertEquals(externalReference.getUrl(), "http://example.org/docs");
}

private void assertLicense(LicenseChoice licenseChoice, final Version version) {
assertNotNull(licenseChoice);
assertNull(licenseChoice.getExpression());

assertEquals(licenseChoice.getLicenses().size(), 1);
License license = licenseChoice.getLicenses().get(0);

if (version == Version.VERSION_15) {
assertEquals(license.getProperties().size(), 1);
}
else {
assertNull(license.getProperties());
}
}

private void assertMetadata(final Metadata metadata) {
assertNotNull(metadata);
assertNotNull(metadata.getTimestamp());
Expand Down
4 changes: 3 additions & 1 deletion src/test/resources/bom-1.4.json
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,9 @@
],
"licenses": [
{
"expression": "EPL-2.0 OR GPL-2.0-with-classpath-exception"
"license": {
"id": "Apache-2.0"
}
}
],
"copyright": "Copyright Example Inc. All rights reserved.",
Expand Down
4 changes: 3 additions & 1 deletion src/test/resources/bom-1.4.xml
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,9 @@
<hash alg="BLAKE3">26cdc7fb3fd65fc3b621a4ef70bc7d2489d5c19e70c76cf7ec20e538df0047cf</hash>
</hashes>
<licenses>
<expression>EPL-2.0 OR GPL-2.0-with-classpath-exception</expression>
<license>
<id>Apache-2.0</id>
</license>
</licenses>
<copyright>Copyright Example Inc. All rights reserved.</copyright>
<cpe>cpe:/a:example:myapplication:1.0.0</cpe>
Expand Down
10 changes: 9 additions & 1 deletion src/test/resources/bom-1.5.json
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,15 @@
],
"licenses": [
{
"expression": "EPL-2.0 OR GPL-2.0-with-classpath-exception"
"license": {
"id": "Apache-2.0",
"properties": [
{
"name": "Foo",
"value": "Bar"
}
]
}
}
],
"copyright": "Copyright Example Inc. All rights reserved.",
Expand Down
7 changes: 6 additions & 1 deletion src/test/resources/bom-1.5.xml
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,12 @@
<hash alg="BLAKE3">26cdc7fb3fd65fc3b621a4ef70bc7d2489d5c19e70c76cf7ec20e538df0047cf</hash>
</hashes>
<licenses>
<expression>EPL-2.0 OR GPL-2.0-with-classpath-exception</expression>
<license>
<id>Apache-2.0</id>
<properties>
<property name="Foo">Bar</property>
</properties>
</license>
</licenses>
<copyright>Copyright Example Inc. All rights reserved.</copyright>
<cpe>cpe:/a:example:myapplication:1.0.0</cpe>
Expand Down

0 comments on commit 6be7bda

Please sign in to comment.