From 3b3d58718fb24ce8220ddc7ddb15357c5c4e50d3 Mon Sep 17 00:00:00 2001 From: Dimitri John Ledkov Date: Wed, 28 May 2025 18:30:37 +0100 Subject: [PATCH 01/54] spdx-schema-v2.3.json: fix OPERATING-SYSTEM package intent For Wolfi container at cgr.dev/chainguard/wolfi-base, trivy for spdx json SBOM generates ```json { "name": "wolfi", "SPDXID": "SPDXRef-OperatingSystem-2bccf727fe0bc7f8", "versionInfo": "20230201", "downloadLocation": "NONE", "filesAnalyzed": false, "primaryPackagePurpose": "OPERATING-SYSTEM", "annotations": [ { "annotator": "Tool: trivy-0.62.1", "annotationDate": "2025-05-28T17:07:25Z", "annotationType": "OTHER", "comment": "Class: os-pkgs" }, { "annotator": "Tool: trivy-0.62.1", "annotationDate": "2025-05-28T17:07:25Z", "annotationType": "OTHER", "comment": "Type: wolfi" } ] } ``` Which fails validating with tools-java because "OPERATING-SYSTEM" value is with a dash, which matches the spec at https://spdx.github.io/spdx-spec/v2.3/package-information/#724-primary-package-purpose-field Given tools in wild follow the spec, imho it is relatively safe to update the schema here. Note we have PACKAGE_MANAGER PACKAGE-MANAGER saga before, so do help me validating any other tools that might be impacted, so far I see this schema file being the only one out of line. --- resources/spdx-schema-v2.3.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/spdx-schema-v2.3.json b/resources/spdx-schema-v2.3.json index 403d202..36c955a 100644 --- a/resources/spdx-schema-v2.3.json +++ b/resources/spdx-schema-v2.3.json @@ -413,7 +413,7 @@ "primaryPackagePurpose" : { "description" : "This field provides information about the primary purpose of the identified package. Package Purpose is intrinsic to how the package is being used rather than the content of the package.", "type" : "string", - "enum" : [ "OTHER", "INSTALL", "ARCHIVE", "FIRMWARE", "APPLICATION", "FRAMEWORK", "LIBRARY", "CONTAINER", "SOURCE", "DEVICE", "OPERATING_SYSTEM", "FILE" ] + "enum" : [ "OTHER", "INSTALL", "ARCHIVE", "FIRMWARE", "APPLICATION", "FRAMEWORK", "LIBRARY", "CONTAINER", "SOURCE", "DEVICE", "OPERATING-SYSTEM", "FILE" ] }, "releaseDate" : { "description" : "This field provides a place for recording the date the package was released.", From 751ec83dfe2e6d7f84bc9883d23945fdda010519 Mon Sep 17 00:00:00 2001 From: Arthit Suriyawongkul Date: Fri, 19 Sep 2025 10:29:02 +0100 Subject: [PATCH 02/54] Add dependabot Signed-off-by: Arthit Suriyawongkul --- .github/dependabot.yml | 8 ++++++++ pom.xml | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..3cddd8c --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,8 @@ +version: 2 +updates: + - package-ecosystem: "maven" + directory: "/" + schedule: + interval: "weekly" + labels: + - "dependencies" diff --git a/pom.xml b/pom.xml index 262e74c..92dd8c1 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,7 @@ https://sonarcloud.io spdx tools-java - 8.4.3 + 12.1.3 11 -Xdoclint:none From 4c30dff5da2d841fc8a3418969f4cbe2f0b08e6b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Sep 2025 17:32:58 +0000 Subject: [PATCH 03/54] Bump org.apache.maven.plugins:maven-source-plugin from 3.2.1 to 3.3.1 Bumps [org.apache.maven.plugins:maven-source-plugin](https://github.com/apache/maven-source-plugin) from 3.2.1 to 3.3.1. - [Release notes](https://github.com/apache/maven-source-plugin/releases) - [Commits](https://github.com/apache/maven-source-plugin/compare/maven-source-plugin-3.2.1...maven-source-plugin-3.3.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-source-plugin dependency-version: 3.3.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 92dd8c1..ee6bb64 100644 --- a/pom.xml +++ b/pom.xml @@ -67,7 +67,7 @@ org.apache.maven.plugins maven-source-plugin - 3.2.1 + 3.3.1 attach-sources From 370c1a28e9118a3ce0893ea1757a15754ad22890 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Sep 2025 16:02:11 +0000 Subject: [PATCH 04/54] Bump org.apache.maven.plugins:maven-compiler-plugin Bumps [org.apache.maven.plugins:maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.11.0 to 3.14.1. - [Release notes](https://github.com/apache/maven-compiler-plugin/releases) - [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.11.0...maven-compiler-plugin-3.14.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-compiler-plugin dependency-version: 3.14.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 92dd8c1..eae6f0a 100644 --- a/pom.xml +++ b/pom.xml @@ -252,7 +252,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.11.0 + 3.14.1 ${project.build.sourceEncoding} true From 84697949da749265bcf345590996c6dc7a28b4d5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Sep 2025 17:58:33 +0000 Subject: [PATCH 05/54] Bump org.spdx:spdx-tagvalue-store from 2.0.0 to 2.0.1 Bumps [org.spdx:spdx-tagvalue-store](https://github.com/spdx/spdx-java-tagvalue-store) from 2.0.0 to 2.0.1. - [Release notes](https://github.com/spdx/spdx-java-tagvalue-store/releases) - [Changelog](https://github.com/spdx/spdx-java-tagvalue-store/blob/master/RELEASE-CHECKLIST.md) - [Commits](https://github.com/spdx/spdx-java-tagvalue-store/compare/v2.0.0...v2.0.1) --- updated-dependencies: - dependency-name: org.spdx:spdx-tagvalue-store dependency-version: 2.0.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 61b6675..2d02f43 100644 --- a/pom.xml +++ b/pom.xml @@ -145,7 +145,7 @@ org.spdx spdx-tagvalue-store - 2.0.0 + 2.0.1 org.spdx From ce921e2677edca5bbf209ec667212aa52f27dfe8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Sep 2025 01:14:40 +0000 Subject: [PATCH 06/54] Bump org.spdx:spdx-maven-plugin from 1.0.2 to 1.0.3 Bumps [org.spdx:spdx-maven-plugin](https://github.com/spdx/spdx-maven-plugin) from 1.0.2 to 1.0.3. - [Release notes](https://github.com/spdx/spdx-maven-plugin/releases) - [Commits](https://github.com/spdx/spdx-maven-plugin/compare/v1.0.2...v1.0.3) --- updated-dependencies: - dependency-name: org.spdx:spdx-maven-plugin dependency-version: 1.0.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 61b6675..48e4de7 100644 --- a/pom.xml +++ b/pom.xml @@ -328,7 +328,7 @@ org.spdx spdx-maven-plugin - 1.0.2 + 1.0.3 build-spdx From 9699fee201f6b304e3ffc6af19a0a13daea3a47c Mon Sep 17 00:00:00 2001 From: Arthit Suriyawongkul Date: Sat, 27 Sep 2025 22:03:35 +0100 Subject: [PATCH 07/54] Update dependencies Signed-off-by: Arthit Suriyawongkul --- README.md | 2 ++ pom.xml | 24 ++++++++++++------------ 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 0c9b5e6..4c35262 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # SPDX Tools + +[![Maven Central Version](https://img.shields.io/maven-central/v/org.spdx/tools-java)](https://central.sonatype.com/artifact/org.spdx/tools-java) [![javadoc](https://javadoc.io/badge2/org.spdx/tools-java/javadoc.svg)](https://javadoc.io/doc/org.spdx/tools-java) A command-line utility for creating, converting, comparing, diff --git a/pom.xml b/pom.xml index 4a75eb7..d5cba73 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,7 @@ https://sonarcloud.io spdx tools-java - 12.1.3 + 12.1.6 11 -Xdoclint:none @@ -104,12 +104,12 @@ commons-io commons-io - 2.16.1 + 2.20.0 org.apache.commons commons-compress - 1.27.1 + 1.28.0 org.apache.ws.xmlschema @@ -125,22 +125,22 @@ org.spdx java-spdx-library - 2.0.0 + 2.0.1 org.spdx spdx-jackson-store - 2.0.2 + 2.0.3 org.spdx spdx-rdf-store - 2.0.0 + 2.0.1 org.spdx spdx-spreadsheet-store - 2.0.0 + 2.0.1 org.spdx @@ -150,12 +150,12 @@ org.spdx spdx-v3jsonld-store - 1.0.0 + 1.0.1 com.networknt json-schema-validator - 1.5.6 + 1.5.9 org.slf4j @@ -172,7 +172,7 @@ org.apache.jena jena-core - 5.2.0 + 5.5.0 compile @@ -232,7 +232,7 @@ org.apache.maven.plugins maven-enforcer-plugin - 3.2.1 + 3.6.1 enforce-java @@ -263,7 +263,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 2.9.1 + 2.10.4 true 8 From dcddeb4018c4b877385df35cb2c190f070b0ac5b Mon Sep 17 00:00:00 2001 From: Arthit Suriyawongkul Date: Sun, 28 Sep 2025 03:36:28 +0100 Subject: [PATCH 08/54] Update Maven Central link Signed-off-by: Arthit Suriyawongkul --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 4c35262..79dcb8e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # SPDX Tools - [![Maven Central Version](https://img.shields.io/maven-central/v/org.spdx/tools-java)](https://central.sonatype.com/artifact/org.spdx/tools-java) [![javadoc](https://javadoc.io/badge2/org.spdx/tools-java/javadoc.svg)](https://javadoc.io/doc/org.spdx/tools-java) @@ -28,7 +27,7 @@ This utility supports versions 2.0, 2.1, 2.2, 2.3 and 3.0.1 of the SPDX specific ## Getting Starting -The SPDX Tools binaries can be downloaded from the [releases page](https://github.com/spdx/tools-java/releases) under the respective release. The package is also available in [Maven Central](https://search.maven.org/artifact/org.spdx/tools-java) (organization org.spdx, artifact tools-java). +The SPDX Tools binaries can be downloaded from the [releases page](https://github.com/spdx/tools-java/releases) under the respective release. The package is also available in [Maven Central](https://central.sonatype.com/artifact/org.spdx/tools-java) (organization `org.spdx`, artifact `tools-java`). See the Syntax section below for the commands available. From a5a2d5c75f09f6b1f06b1927998a86a9b63105d6 Mon Sep 17 00:00:00 2001 From: Arthit Suriyawongkul Date: Sun, 28 Sep 2025 03:47:33 +0100 Subject: [PATCH 09/54] Move jena-core back to 5.2.0 Signed-off-by: Arthit Suriyawongkul --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d5cba73..b642863 100644 --- a/pom.xml +++ b/pom.xml @@ -172,7 +172,7 @@ org.apache.jena jena-core - 5.5.0 + 5.4.0 compile From 43d6d4347ea96852aeea010a4f3df0968495c3f2 Mon Sep 17 00:00:00 2001 From: Gary O'Neall Date: Sat, 4 Oct 2025 13:50:17 -0700 Subject: [PATCH 10/54] Remove redundant dependencies These dependencies are included as transitive dependencies through other SPDX library modules. Removing these from the POM file to avoid possible version conflicts. This commit also includes a fix to a minor typo. --- pom.xml | 12 ------------ src/main/java/org/spdx/tools/SpdxToolsHelper.java | 2 +- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/pom.xml b/pom.xml index b642863..24483bf 100644 --- a/pom.xml +++ b/pom.xml @@ -163,18 +163,6 @@ 2.0.17 true - - org.apache.poi - poi - 5.4.1 - compile - - - org.apache.jena - jena-core - 5.4.0 - compile - diff --git a/src/main/java/org/spdx/tools/SpdxToolsHelper.java b/src/main/java/org/spdx/tools/SpdxToolsHelper.java index 4c37030..b7127d3 100644 --- a/src/main/java/org/spdx/tools/SpdxToolsHelper.java +++ b/src/main/java/org/spdx/tools/SpdxToolsHelper.java @@ -389,7 +389,7 @@ public static org.spdx.library.model.v3_0_1.core.SpdxDocument getDocFromStore(IS throw new InvalidSPDXAnalysisException("No SPDX version 3 documents in model store"); } if (docs.size() > 1) { - throw new InvalidSPDXAnalysisException("Multiple SPDX version 3 documents in modelSTore. There can only be one SPDX document."); + throw new InvalidSPDXAnalysisException("Multiple SPDX version 3 documents in modelStore. There can only be one SPDX document."); } return docs.get(0); } From e7071e18b5dfb43c817b4fd18bc338e0e0f97087 Mon Sep 17 00:00:00 2001 From: Arthit Suriyawongkul Date: Sun, 28 Sep 2025 21:24:22 +0100 Subject: [PATCH 11/54] Delete CONTRIBUTING.md from Spdx-Java-Library repo Remove CONTRIBUTING.md in src/ subdir, it is from `Spdx-Java-Library` repo. Update CONTRIBUTING.md in root to use `tools-java` name instead of `spdx-tools`. Signed-off-by: Arthit Suriyawongkul --- CONTRIBUTING.md | 4 +-- src/main/java/org/spdx/tools/CONTRIBUTING.md | 27 -------------------- 2 files changed, 2 insertions(+), 29 deletions(-) delete mode 100644 src/main/java/org/spdx/tools/CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c4a6f5f..096ae67 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -22,11 +22,11 @@ If you would like to work on a fix for any issue, please assign the issue to you Patches ------- -The source code for `spdx-tools` is hosted on [github.com/spdx/tools-java](https://github.com/spdx/tools-java). Please review [open pull requests](https://github.com/spdx/tools-java/pulls) and [active branches](https://github.com/spdx/tools-java/branches) before committing time to a substantial revision. Work along similar lines may already be in progress. +The source code for `tools-java` is hosted on [github.com/spdx/tools-java](https://github.com/spdx/tools-java). Please review [open pull requests](https://github.com/spdx/tools-java/pulls) and [active branches](https://github.com/spdx/tools-java/branches) before committing time to a substantial revision. Work along similar lines may already be in progress. To submit a patch via GitHub, fork the repository, create a topic branch from `master` for your work, and send a pull request when ready. If you would prefer to send a patch or grant access to pull from your own Git repository, please contact the project's contributors by e-mail. -To contribute an implementation of a feature defined by a version of the SPDX specification later than the one supported by the current SPDX Tools release, clone the branch `spec/X.X`, where X.X is the major.minor version of the targeted specification (e.g. "3.0"). +To contribute an implementation of a feature defined by a version of the SPDX specification later than the one supported by the current SPDX Tools release, clone the branch `spec/X.X`, where X.X is the major.minor version of the targeted specification (e.g. "3.1"). Once implemented, submit a pull request with `spec/X.X` branch as the parent branch. diff --git a/src/main/java/org/spdx/tools/CONTRIBUTING.md b/src/main/java/org/spdx/tools/CONTRIBUTING.md deleted file mode 100644 index a41d4ff..0000000 --- a/src/main/java/org/spdx/tools/CONTRIBUTING.md +++ /dev/null @@ -1,27 +0,0 @@ -Contributing -============ - -Thank you for your interest in `Spdx-Java-Library`. The project is open-source software, and bug reports, suggestions, and most especially patches are welcome. - -Issues ------- - -`Spdx-Java-Library` has a [project page on GitHub](https://github.com/spdx/Spdx-Java-Library) where you can [create an issue](https://github.com/spdx/Spdx-Java-Library/issues/new/choose) to report a bug, make a suggestion, or propose a substantial change or improvement that you might like to make. You may also wish to contact the SPDX working group technical team through its mailing list, [spdx-tech@lists.spdx.org](mailto:spdx-tech@lists.spdx.org). - -If you would like to work on a fix for any issue, please assign the issue to yourself prior to creating a Pull Request. - -Pull Requests -------- - -The source code for `Spdx-Java-Library` is hosted on [github.com/spdx/Spdx-Java-Library](https://github.com/spdx/Spdx-Java-Library). Please review [open pull requests](https://github.com/spdx/Spdx-Java-Library/pulls) and [active branches](https://github.com/spdx/Spdx-Java-Library/branches) before committing time to a substantial revision. Work along similar lines may already be in progress. - -To submit a pull request via GitHub, fork the repository, create a topic branch from `master` for your work, and send a pull request when ready. If you would prefer to send a patch or grant access to pull from your own Git repository, please contact the project's contributors by e-mail. - -To contribute an implementation of a feature defined by a version of the SPDX specification later than the one supported by the current SPDX Tools release, clone the branch `spec/X.X`, where X.X is the major.minor version of the targeted specification (e.g. "3.0"). - -Once implemented, submit a pull request with `spec/X.X` branch as the parent branch. - -Licensing ---------- - -However you choose to contribute, please sign-off in each of your commits that you license your contributions under the terms of [the Developer Certificate of Origin](https://developercertificate.org/). Git has utilities for signing off on commits: `git commit -s` signs a current commit, and `git rebase --signoff ` retroactively signs a range of past commits. From 9d127a9c94b6880b85603ccaf59b1ff27e37ab8f Mon Sep 17 00:00:00 2001 From: Arthit Suriyawongkul Date: Sun, 28 Sep 2025 20:57:09 +0100 Subject: [PATCH 12/54] Add Javadoc build workflow Signed-off-by: Arthit Suriyawongkul --- .github/workflows/docs.yml | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 .github/workflows/docs.yml diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 0000000..ff52f75 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,36 @@ +name: Generate and publish API JavaDocs + +on: + push: + branches: [ master ] + +jobs: + docs: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + fetch-depth: 0 + + - name: Set up JDK + uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 + with: + distribution: 'temurin' + java-version: 17 + + - name: Cache Maven packages + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + with: + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + + - name: Generate docs + run: mvn javadoc:javadoc + + - name: Deploy docs + uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./target/reports/apidocs From f0c497ddadac14e8f45af0caf91a7066c2e5228c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 28 Sep 2025 02:56:31 +0000 Subject: [PATCH 13/54] Bump org.apache.maven.plugins:maven-gpg-plugin from 1.6 to 3.2.8 Bumps [org.apache.maven.plugins:maven-gpg-plugin](https://github.com/apache/maven-gpg-plugin) from 1.6 to 3.2.8. - [Release notes](https://github.com/apache/maven-gpg-plugin/releases) - [Commits](https://github.com/apache/maven-gpg-plugin/compare/maven-gpg-plugin-1.6...maven-gpg-plugin-3.2.8) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-gpg-plugin dependency-version: 3.2.8 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 24483bf..b457d8a 100644 --- a/pom.xml +++ b/pom.xml @@ -81,7 +81,7 @@ org.apache.maven.plugins maven-gpg-plugin - 1.6 + 3.2.8 sign-artifacts From ab405e8ad2d5966f4527129308551f441852bdfb Mon Sep 17 00:00:00 2001 From: Gary O'Neall Date: Mon, 6 Oct 2025 11:06:42 -0700 Subject: [PATCH 14/54] Switch publishing from Sonatype to Central --- pom.xml | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index b457d8a..ddbfbbc 100644 --- a/pom.xml +++ b/pom.xml @@ -43,13 +43,6 @@ Github Actions https://github.com/spdx/tools-java/actions - - - ossrh - spdx-spdx-tools - https://oss.sonatype.org/service/local/staging/deploy/maven2/ - - UTF-8 https://sonarcloud.io @@ -209,6 +202,15 @@ + + org.sonatype.central + central-publishing-maven-plugin + 0.7.0 + true + + central + + org.owasp dependency-check-maven From de71b804784e4671b9b47fa712ee8a4449ed2d9e Mon Sep 17 00:00:00 2001 From: Gary O'Neall Date: Mon, 6 Oct 2025 11:27:50 -0700 Subject: [PATCH 15/54] Update JavaDocs config Fixes #229 Also updates the Verify.java file to remove JavaDoc warnings and a few other minor cleanups --- pom.xml | 10 +++------- src/main/java/org/spdx/tools/Verify.java | 11 ++++------- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/pom.xml b/pom.xml index ddbfbbc..79fede0 100644 --- a/pom.xml +++ b/pom.xml @@ -253,19 +253,15 @@ org.apache.maven.plugins maven-javadoc-plugin - 2.10.4 + 3.11.3 true - 8 - ${env.JAVA_HOME}/bin/javadoc - -Xdoclint:none + true + all,-missing attach-javadocs - - ${javadoc.opts} - jar diff --git a/src/main/java/org/spdx/tools/Verify.java b/src/main/java/org/spdx/tools/Verify.java index 0942914..d4d050d 100644 --- a/src/main/java/org/spdx/tools/Verify.java +++ b/src/main/java/org/spdx/tools/Verify.java @@ -70,7 +70,7 @@ public static void main(String[] args) { System.exit(ERROR_STATUS); } if (args.length > MAX_ARGS) { - System.out.printf("Warning: Extra arguments will be ignored"); + System.out.println("Warning: Extra arguments will be ignored"); } SpdxToolsHelper.initialize(); List verify = null; @@ -104,20 +104,20 @@ public static void main(String[] args) { errors.add(verifyMsg); } } - if (errors.size() > 0) { + if (!errors.isEmpty()) { System.out.println("This SPDX Document is not valid due to:"); for (String errorMsg:errors) { System.out.print("\t" + errorMsg+"\n"); } } - if (warnings.size() > 0) { + if (!warnings.isEmpty()) { System.out.println("Warning: Deprecated license identifiers were found that should no longer be used.\n" + "References to the following deprecated license ID's should be updated:"); for (String warningMsg:warnings) { System.out.print("\t" + warningMsg+"\n"); } } - if (errors.size() == 0) { + if (errors.isEmpty()) { System.out.println("This SPDX Document is valid."); } else { System.exit(ERROR_STATUS); @@ -127,10 +127,7 @@ public static void main(String[] args) { /** * Verify a an SPDX file * @param filePath File path to the SPDX file to be verified - * @param fileType * @return A list of verification errors - if empty, the SPDX file is valid - * @throws InvalidFileNameException on invalid file name or file not found - * @throws IOException on IO error * @throws SpdxVerificationException where the SPDX file can not be parsed or the filename is invalid */ public static List verify(String filePath, SerFileType fileType) throws SpdxVerificationException { From 83fc970b9ad30865515255efb64b9081fae83084 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Oct 2025 16:16:15 +0000 Subject: [PATCH 16/54] Bump org.owasp:dependency-check-maven from 12.1.6 to 12.1.8 Bumps [org.owasp:dependency-check-maven](https://github.com/dependency-check/DependencyCheck) from 12.1.6 to 12.1.8. - [Release notes](https://github.com/dependency-check/DependencyCheck/releases) - [Changelog](https://github.com/dependency-check/DependencyCheck/blob/main/CHANGELOG.md) - [Commits](https://github.com/dependency-check/DependencyCheck/compare/v12.1.6...v12.1.8) --- updated-dependencies: - dependency-name: org.owasp:dependency-check-maven dependency-version: 12.1.8 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 79fede0..863dacf 100644 --- a/pom.xml +++ b/pom.xml @@ -48,7 +48,7 @@ https://sonarcloud.io spdx tools-java - 12.1.6 + 12.1.8 11 -Xdoclint:none From 1b5ec335eea26482b5f78cbd0589ac800281752b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Oct 2025 16:21:20 +0000 Subject: [PATCH 17/54] Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.11.3 to 3.12.0 Bumps [org.apache.maven.plugins:maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.11.3 to 3.12.0. - [Release notes](https://github.com/apache/maven-javadoc-plugin/releases) - [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.11.3...maven-javadoc-plugin-3.12.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-javadoc-plugin dependency-version: 3.12.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 79fede0..a31cafc 100644 --- a/pom.xml +++ b/pom.xml @@ -253,7 +253,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.11.3 + 3.12.0 true true From 6fb32b711bbd2ac6a2950044b45e28a2b3651ff3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Oct 2025 16:21:13 +0000 Subject: [PATCH 18/54] Bump org.apache.maven.plugins:maven-enforcer-plugin from 3.6.1 to 3.6.2 Bumps [org.apache.maven.plugins:maven-enforcer-plugin](https://github.com/apache/maven-enforcer) from 3.6.1 to 3.6.2. - [Release notes](https://github.com/apache/maven-enforcer/releases) - [Commits](https://github.com/apache/maven-enforcer/compare/enforcer-3.6.1...enforcer-3.6.2) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-enforcer-plugin dependency-version: 3.6.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e2ec9e6..ba34074 100644 --- a/pom.xml +++ b/pom.xml @@ -222,7 +222,7 @@ org.apache.maven.plugins maven-enforcer-plugin - 3.6.1 + 3.6.2 enforce-java From b51b10dc5f1e9f46c3f78a43cc56fe6c0d2e5778 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Oct 2025 16:13:23 +0000 Subject: [PATCH 19/54] Bump org.apache.maven.plugins:maven-release-plugin from 3.0.1 to 3.1.1 Bumps [org.apache.maven.plugins:maven-release-plugin](https://github.com/apache/maven-release) from 3.0.1 to 3.1.1. - [Release notes](https://github.com/apache/maven-release/releases) - [Commits](https://github.com/apache/maven-release/compare/maven-release-3.0.1...maven-release-3.1.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-release-plugin dependency-version: 3.1.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ba34074..021f73c 100644 --- a/pom.xml +++ b/pom.xml @@ -354,7 +354,7 @@ org.apache.maven.plugins maven-release-plugin - 3.0.1 + 3.1.1 v@{project.version} release From 979c34cac6f45eace562e301ca0a901d5be0d012 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Oct 2025 16:15:28 +0000 Subject: [PATCH 20/54] Bump org.sonatype.central:central-publishing-maven-plugin Bumps [org.sonatype.central:central-publishing-maven-plugin](https://github.com/sonatype/central-publishing-maven-plugin) from 0.7.0 to 0.9.0. - [Commits](https://github.com/sonatype/central-publishing-maven-plugin/commits) --- updated-dependencies: - dependency-name: org.sonatype.central:central-publishing-maven-plugin dependency-version: 0.9.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 021f73c..1c72fba 100644 --- a/pom.xml +++ b/pom.xml @@ -205,7 +205,7 @@ org.sonatype.central central-publishing-maven-plugin - 0.7.0 + 0.9.0 true central From cd8332cab3ac40d47ee92603939c7544ec36e179 Mon Sep 17 00:00:00 2001 From: Gary O'Neall Date: Wed, 15 Oct 2025 10:38:18 -0700 Subject: [PATCH 21/54] Suppress false positives in dependency track report --- dependency-check-supress.xml | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/dependency-check-supress.xml b/dependency-check-supress.xml index 442d77a..0eb63bd 100644 --- a/dependency-check-supress.xml +++ b/dependency-check-supress.xml @@ -1,4 +1,19 @@ - + + + ^pkg:maven/com\.ibm\.icu/icu4j@.*$ + CVE-2025-5222 + + + + ^pkg:maven/org\.spdx/spdx-java-model-2_X@.*$ + cpe:/a:x.org:x.org + \ No newline at end of file From cece6e2de1a4cbaf7259998107bff04f5243a3d8 Mon Sep 17 00:00:00 2001 From: Gary O'Neall Date: Wed, 15 Oct 2025 10:49:31 -0700 Subject: [PATCH 22/54] [maven-release-plugin] prepare release v2.0.2 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 1c72fba..59639da 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ org.spdx tools-java - 2.0.2-SNAPSHOT + 2.0.2 jar tools-java @@ -32,7 +32,7 @@ https://github.com/spdx/tools-java scm:git:git@github.com:spdx/tools-java.git scm:git:git@github.com:spdx/tools-java.git - master + v2.0.2 Github From c34ce2254bd39e35255ff956d0891669225b627b Mon Sep 17 00:00:00 2001 From: Gary O'Neall Date: Wed, 15 Oct 2025 10:49:36 -0700 Subject: [PATCH 23/54] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 59639da..a47a2b1 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ org.spdx tools-java - 2.0.2 + 2.0.3-SNAPSHOT jar tools-java @@ -32,7 +32,7 @@ https://github.com/spdx/tools-java scm:git:git@github.com:spdx/tools-java.git scm:git:git@github.com:spdx/tools-java.git - v2.0.2 + master Github From 23bd470259f55641eb72b0c5d733edac014a4554 Mon Sep 17 00:00:00 2001 From: Gary O'Neall Date: Mon, 27 Oct 2025 11:50:14 -0700 Subject: [PATCH 24/54] Update README with current tools version --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 79dcb8e..2037d3b 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ If you are a developer, there are examples in the [examples folder](examples/org The command line interface of the SPDX Tools can be used like this: - java -jar tools-java-2.0.1-jar-with-dependencies.jar + java -jar tools-java-2.0.2-jar-with-dependencies.jar ## SPDX format converters From d6fc9a505f90b7ed4ab23e5e21453ccf40f2b39b Mon Sep 17 00:00:00 2001 From: Gary O'Neall Date: Thu, 30 Oct 2025 15:26:00 -0700 Subject: [PATCH 25/54] Draft example Java file to generate a full SPDX V3 JSONLD file --- .../ExistingSpdxDocumentV2Compat.java | 4 +- .../org/spdx/examples/FullSpdxV3Example.java | 308 ++++++++++++++++++ tools-java.iml | 8 + 3 files changed, 318 insertions(+), 2 deletions(-) create mode 100644 examples/org/spdx/examples/FullSpdxV3Example.java create mode 100644 tools-java.iml diff --git a/examples/org/spdx/examples/ExistingSpdxDocumentV2Compat.java b/examples/org/spdx/examples/ExistingSpdxDocumentV2Compat.java index 584fdce..093dd7b 100644 --- a/examples/org/spdx/examples/ExistingSpdxDocumentV2Compat.java +++ b/examples/org/spdx/examples/ExistingSpdxDocumentV2Compat.java @@ -30,9 +30,9 @@ * for this example is assumed to be JSON (e.g. the output of the SimpleSpdxDocumentV2Compat example). * Different format can be used by using the associated store rather than the spdx-jackson store * (e.g. spdx-spreadsheet-store, spdx-tagvalue-store, or the spdx-rdf-store). - * + *

* This example depends on the Spdx-Java-Library and the spdx-java-jackson store libraries - * + *

* @author Gary O'Neall */ public class ExistingSpdxDocumentV2Compat { diff --git a/examples/org/spdx/examples/FullSpdxV3Example.java b/examples/org/spdx/examples/FullSpdxV3Example.java new file mode 100644 index 0000000..b2fd183 --- /dev/null +++ b/examples/org/spdx/examples/FullSpdxV3Example.java @@ -0,0 +1,308 @@ +package org.spdx.examples; + + +import org.spdx.core.DefaultModelStore; +import org.spdx.core.IModelCopyManager; +import org.spdx.core.InvalidSPDXAnalysisException; +import org.spdx.library.LicenseInfoFactory; +import org.spdx.library.ModelCopyManager; +import org.spdx.library.SpdxModelFactory; +import org.spdx.library.model.v2.SpdxConstantsCompatV2; +import org.spdx.library.model.v3_0_1.SpdxConstantsV3; +import org.spdx.library.model.v3_0_1.SpdxModelClassFactoryV3; +import org.spdx.library.model.v3_0_1.core.*; +import org.spdx.library.model.v3_0_1.simplelicensing.AnyLicenseInfo; +import org.spdx.library.model.v3_0_1.software.*; +import org.spdx.storage.IModelStore; +import org.spdx.storage.ISerializableModelStore; +import org.spdx.storage.simple.InMemSpdxStore; +import org.spdx.v3jsonldstore.JsonLDStore; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; + +/** + * This class attempts to implement all the SPDX specification classes and most of the properties. + *

+ * It will generate a resulting serialization that can be used as a full serialization example. + *

+ *

+ * This example is current as of the version 3.0.1 of the SPDX Specification + *

+ */ +public class FullSpdxV3Example { + + static final DateTimeFormatter SPDX_DATE_FORMATTER = DateTimeFormatter.ofPattern(SpdxConstantsCompatV2.SPDX_DATE_FORMAT); + /** + * @param args args[0] is the file path for the output serialized file + */ + public static void main(String[] args) throws Exception { + if (args.length != 1) { + usage(); + System.exit(1); + } + File outFile = new File(args[0]); + if (outFile.exists()) { + System.out.printf("%s already exists.\n", args[0]); + System.exit(1); + } + if (!outFile.createNewFile()) { + System.out.printf("Unable to create file %s\n", args[0]); + System.exit(1); + } + if (!outFile.canWrite()) { + System.out.printf("Can not write to file %s\n", args[0]); + System.exit(1); + } + SpdxModelFactory.init(); + IModelCopyManager copyManager = new ModelCopyManager(); + try (ISerializableModelStore modelStore = new JsonLDStore(new InMemSpdxStore())) { + String prefix = "https://spdx.github.io/spdx-spec/v3.0.1/examples/full-example-eaa46bdcfa20#"; + DefaultModelStore.initialize(modelStore, prefix, copyManager); + CreationInfo creationInfo = SpdxModelClassFactoryV3.createCreationInfo( + modelStore, prefix + "garyagent", "Gary O'Neall", + copyManager); + SpdxDocument doc = creationInfo.createSpdxDocument(prefix + "document") + .setDataLicense(LicenseInfoFactory.getListedLicenseById("CC0")) + .addNamespaceMap(creationInfo.createNamespaceMap(modelStore.getNextId(IModelStore.IdType.Anonymous)) + .setNamespace(prefix) + .setPrefix("example") + .build()) + .addProfileConformance(ProfileIdentifierType.CORE) + .addProfileConformance(ProfileIdentifierType.SOFTWARE) + .addProfileConformance(ProfileIdentifierType.BUILD) + .addProfileConformance(ProfileIdentifierType.AI) + .addProfileConformance(ProfileIdentifierType.DATASET) + .addProfileConformance(ProfileIdentifierType.SECURITY) + .addProfileConformance(ProfileIdentifierType.EXPANDED_LICENSING) + .build(); + addCoreClasses(prefix, doc); + Sbom sbom = addSoftwareClasses(prefix, doc); + try (OutputStream outStream = new FileOutputStream(outFile)) { + modelStore.serialize(outStream); + } + } + } + + private static void addCoreClasses(String prefix, SpdxDocument doc) throws InvalidSPDXAnalysisException { + // Agent - Abstract, already in creation info + // Annotation + doc.getElements().add(doc.createAnnotation(prefix + "docannotation") + .setStatement("This document is for example purposes only") + .setAnnotationType(AnnotationType.OTHER) + .setSubject(doc) + .build()); + // Artifact - Abstract - used in software package and several others + // Bom - will be used as an AI BOM and software BOM + // Bundle + doc.getElements().add(doc.createBundle(prefix + "bundle") + .setComment("This is just an example of a concrete Bundle class - the elements are not used elsewhere in the SPDX document") + .setContext("Custom Licenses") + .addElement(doc.createCustomLicense(prefix + "LicenseRef-CustomLicense1") + .setLicenseText("This is a custom license text number one.") + .build()) + .addElement(doc.createCustomLicense(prefix + "LicenseRef-CustomLicense2") + .setLicenseText("This is a custom license text number two.") + .build()) + .build()); + // CreationInfo - Already created + // DictionaryEntry - TODO: Change to make sure it has been created + // Element - Abstract + // ElementCollection - Abstract + // ExternalIdentifier - TODO: Change to make sure it has been created + // Organization + doc.getCreationInfo().getCreatedBys().add(doc.createOrganization(prefix + "spdxorg") + .setName("System Package Data Exchange (SPDX)") + .build()); + // ExternalMap + String orgLocation = "https://external/organization/spdxdata"; + String orgPrefix = orgLocation + "#"; + String orgUri = orgPrefix + "org"; + ExternalOrganization externalOrg = new ExternalOrganization(doc.getModelStore(), + orgUri, doc.getCopyManager(), + true, orgLocation); + doc.getCreationInfo().getCreatedBys().add(externalOrg); + doc.getSpdxImports().add(doc.createExternalMap(doc.getModelStore().getNextId(IModelStore.IdType.Anonymous)) + .setExternalSpdxId(orgUri) + .setLocationHint(orgLocation) + .build()); + // Hash - Used in file + // IndividualElement - Used in software package originated by + // IntegrityMethod - Used in file and package + // LifecycleScopedRelationship - TODO: Change to make sure it has been created + // NamespaceMap - Used in doc already + // PackageVerificationCode - Going to ignore - deprecated + // Person - Used in creation info + // PositiveIntegerRange - TODO: Change to make sure it has been created + // Relationship - Used in software + // SoftwareAgent + doc.getCreationInfo().getCreatedBys().add(doc.createSoftwareAgent(prefix + "softwareagent") + .setName("SPDX Spec Github CI") + .build()); + // SpdxDocument - already used + // ExternalRef + // Tool + doc.getCreationInfo().getCreatedUsings().add(doc.createTool(prefix + "creationtool") + .setName("tools-java") + .setComment("Created by the FullSpdxV3Example.java utility in tools-java") + .addExternalRef(doc.createExternalRef(doc.getModelStore().getNextId(IModelStore.IdType.Anonymous)) + .setExternalRefType(ExternalRefType.MAVEN_CENTRAL) + .addLocator("org.spdx:tools-java") + .build()) + .build()); + + } + + private static Sbom addSoftwareClasses(String prefix, SpdxDocument doc) throws InvalidSPDXAnalysisException { + // Sbom + Sbom sbom = doc.createSbom(prefix + "aibom") + .setName("AI SBOM") + .addSbomType(SbomType.ANALYZED) + .addProfileConformance(ProfileIdentifierType.CORE) + .addProfileConformance(ProfileIdentifierType.SOFTWARE) + .addProfileConformance(ProfileIdentifierType.BUILD) + .addProfileConformance(ProfileIdentifierType.SECURITY) + .addProfileConformance(ProfileIdentifierType.EXPANDED_LICENSING) + .build(); + doc.getElements().add(sbom); + doc.getRootElements().add(sbom); + // Package + SpdxPackage pkg = doc.createSpdxPackage(prefix + "tools-java") + .setName("tools-java") + .setPrimaryPurpose(SoftwarePurpose.APPLICATION) + .addAdditionalPurpose(SoftwarePurpose.LIBRARY) + .addAttributionText("Maintained by the SPDX Community") + .setBuiltTime(LocalDateTime.of(2025, 10, 15, 9, 10) + .format(SPDX_DATE_FORMATTER)) + // ContentIdentifier + .addContentIdentifier(doc.createContentIdentifier(doc.getModelStore().getNextId(IModelStore.IdType.Anonymous)) + .setContentIdentifierType(ContentIdentifierType.GITOID) + .setContentIdentifierValue("23bd470259f55641eb72b0c5d733edac014a4554") + .build()) + .setCopyrightText("Copyright (c) Source Auditor Inc.") + .setDescription("A command-line utility for creating, converting, comparing, and validating SPDX documents across multiple formats.") + .setDownloadLocation("https://github.com/spdx/tools-java/releases/download/v2.0.2/tools-java-2.0.2.zip") + .addExternalIdentifier(doc.createExternalIdentifier(doc.getModelStore().getNextId(IModelStore.IdType.Anonymous)) + .setExternalIdentifierType(ExternalIdentifierType.URL_SCHEME) + .setIdentifier("https://github.com/spdx/tools-java") + .setIssuingAuthority("GitHub") + .build()) + .addExternalRef(doc.createExternalRef(doc.getModelStore().getNextId(IModelStore.IdType.Anonymous)) + .setExternalRefType(ExternalRefType.MAVEN_CENTRAL) + .addLocator("org.spdx:tools-java:jar:2.0.2") + .build()) + .setPackageUrl("pkg:maven/org.spdx/tools-java@2.0.2") + .setPackageVersion("2.0.2") + .setReleaseTime(LocalDateTime.of(2025, 10, 15, 11, 50) + .format(SPDX_DATE_FORMATTER)) + .setSourceInfo("This package came from the original source - the official SPDX GitHub repo and build process") + .addStandardName("SPDX Version 2.X and SPDX Version 3.0") + .setHomePage("https://github.com/spdx/tools-java") + .addOriginatedBy(new SpdxOrganization()) + .setSuppliedBy(new SpdxOrganization()) + .setSummary("A command-line utility for creating, converting, comparing, and validating SPDX documents across multiple formats.") + .addSupportLevel(SupportType.LIMITED_SUPPORT) + .setValidUntilTime(LocalDateTime.of(2027, 10, 15, 9, 10) + .format(SPDX_DATE_FORMATTER)) + .addVerifiedUsing(doc.createHash(doc.getModelStore().getNextId(IModelStore.IdType.Anonymous)) + .setAlgorithm(HashAlgorithm.SHA256) + .setHashValue("c37ce759c3867780d55791a1804101d288fa921e77ed791e6c053fd5d7513d0d") + .build()) + .build(); + doc.getElements().add(pkg); + sbom.getElements().add(pkg); + sbom.getRootElements().add(pkg); + // File + SpdxFile sourceFile = doc.createSpdxFile(prefix + "example-source") + .setPrimaryPurpose(SoftwarePurpose.SOURCE) + .setContentType("text/plain") + .setCopyrightText("Copyright (c) 2025 Source Auditor Inc.") + .setFileKind(FileKindType.FILE) + .setName("./examples/org/spdx/examples/FullSpdxV3Example.java") + .build(); + sbom.getElements().add(sourceFile); + doc.getElements().add(sourceFile); + // Relationships - declared license, concluded license, generated from + doc.getElements().add(doc.createRelationship(prefix + "example-source-to-pkg") + .setRelationshipType(RelationshipType.GENERATES) + .setFrom(sourceFile) + .addTo(pkg) + .build()); + AnyLicenseInfo declared = LicenseInfoFactory.parseSPDXLicenseString("Apache-2.0", + doc.getModelStore(), prefix, doc.getCopyManager(), new ArrayList<>()); + AnyLicenseInfo concluded = LicenseInfoFactory.parseSPDXLicenseString("Apache-2.0", + doc.getModelStore(), prefix, doc.getCopyManager(), new ArrayList<>()); + doc.getElements().add(doc.createRelationship(prefix + "source-declared") + .setRelationshipType(RelationshipType.HAS_DECLARED_LICENSE) + .setFrom(sourceFile) + .addTo(declared) + .build()); + doc.getElements().add(doc.createRelationship(prefix + "source-concluded") + .setRelationshipType(RelationshipType.HAS_CONCLUDED_LICENSE) + .setFrom(sourceFile) + .addTo(concluded) + .build()); + doc.getElements().add(doc.createRelationship(prefix + "pkg-declared") + .setRelationshipType(RelationshipType.HAS_DECLARED_LICENSE) + .setFrom(pkg) + .addTo(declared) + .build()); + doc.getElements().add(doc.createRelationship(prefix + "pkg-concluded") + .setRelationshipType(RelationshipType.HAS_CONCLUDED_LICENSE) + .setFrom(pkg) + .addTo(concluded) + .build()); + // Snippet + Snippet snippet = doc.createSnippet(prefix + "snippet") + .addAttributionText("Example code created by Gary O'Neall") + .setDescription("Main method for the FullSpdxV3Example.java") + .setCopyrightText("Copyright (c) 2025 Source Auditor Inc.") + .setByteRange(doc.createPositiveIntegerRange(doc.getModelStore().getNextId(IModelStore.IdType.Anonymous)) + .setBeginIntegerRange(43) + .setEndIntegerRange(89) + .build()) + .setLineRange(doc.createPositiveIntegerRange(doc.getModelStore().getNextId(IModelStore.IdType.Anonymous)) + .setBeginIntegerRange(1548) + .setEndIntegerRange(3955) + .build()) + .setName("main(String[] args)") + .setSnippetFromFile(sourceFile) + .build(); + doc.getElements().add(snippet); + sbom.getElements().add(snippet); + doc.getElements().add(doc.createRelationship(prefix + "snippet-declared") + .setRelationshipType(RelationshipType.HAS_DECLARED_LICENSE) + .setFrom(snippet) + .addTo(declared) + .build()); + doc.getElements().add(doc.createRelationship(prefix + "snippet-concluded") + .setRelationshipType(RelationshipType.HAS_CONCLUDED_LICENSE) + .setFrom(snippet) + .addTo(concluded) + .build()); + // SoftwareArtifact - Abstract + return sbom; + } + + + private static void addAIandDataClasses(String prefix, SpdxDocument doc) throws InvalidSPDXAnalysisException { + Bom aiBom = doc.createBom(prefix + "aibom") + .setName("AI SBOM") + .addProfileConformance(ProfileIdentifierType.CORE) + .addProfileConformance(ProfileIdentifierType.SOFTWARE) + .addProfileConformance(ProfileIdentifierType.AI) + .addProfileConformance(ProfileIdentifierType.DATASET) + .build(); + doc.getElements().add(aiBom); + doc.getRootElements().add(aiBom); + } + + private static void usage() { + System.out.println("Generates an SPDX JSON-LD file containing all of the supported classes."); + System.out.println("Usage: FullSpdxV3Example outputfile"); + } +} diff --git a/tools-java.iml b/tools-java.iml new file mode 100644 index 0000000..ae72666 --- /dev/null +++ b/tools-java.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file From 6919563e8bf5f7c3090209d619febe688905cc53 Mon Sep 17 00:00:00 2001 From: Gary O'Neall Date: Sun, 2 Nov 2025 13:56:32 -0800 Subject: [PATCH 26/54] Complete SPDX V3 example generation The following classes are not included: Extension - due to validation issue ExploitCatalogVulnAssessmentRelationship - due to an inconsistency with the locator property between the Java generated code and the current JSON schema Signed-off-by: Gary O'Neall --- .../org/spdx/examples/FullSpdxV3Example.java | 982 ++++++++++++++---- .../spdx/examples/SpdxExtensionExample.java | 28 + src/main/java/org/spdx/tools/Verify.java | 6 +- 3 files changed, 790 insertions(+), 226 deletions(-) create mode 100644 examples/org/spdx/examples/SpdxExtensionExample.java diff --git a/examples/org/spdx/examples/FullSpdxV3Example.java b/examples/org/spdx/examples/FullSpdxV3Example.java index b2fd183..2a42eb6 100644 --- a/examples/org/spdx/examples/FullSpdxV3Example.java +++ b/examples/org/spdx/examples/FullSpdxV3Example.java @@ -1,6 +1,13 @@ package org.spdx.examples; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.networknt.schema.JsonSchema; +import com.networknt.schema.JsonSchemaFactory; +import com.networknt.schema.SpecVersion; +import com.networknt.schema.ValidationMessage; import org.spdx.core.DefaultModelStore; import org.spdx.core.IModelCopyManager; import org.spdx.core.InvalidSPDXAnalysisException; @@ -8,22 +15,36 @@ import org.spdx.library.ModelCopyManager; import org.spdx.library.SpdxModelFactory; import org.spdx.library.model.v2.SpdxConstantsCompatV2; -import org.spdx.library.model.v3_0_1.SpdxConstantsV3; import org.spdx.library.model.v3_0_1.SpdxModelClassFactoryV3; +import org.spdx.library.model.v3_0_1.ai.AIPackage; +import org.spdx.library.model.v3_0_1.ai.EnergyUnitType; +import org.spdx.library.model.v3_0_1.ai.SafetyRiskAssessmentType; +import org.spdx.library.model.v3_0_1.build.Build; import org.spdx.library.model.v3_0_1.core.*; +import org.spdx.library.model.v3_0_1.dataset.ConfidentialityLevelType; +import org.spdx.library.model.v3_0_1.dataset.DatasetAvailabilityType; +import org.spdx.library.model.v3_0_1.dataset.DatasetPackage; +import org.spdx.library.model.v3_0_1.dataset.DatasetType; +import org.spdx.library.model.v3_0_1.expandedlicensing.ExtendableLicense; +import org.spdx.library.model.v3_0_1.extension.Extension; +import org.spdx.library.model.v3_0_1.security.*; import org.spdx.library.model.v3_0_1.simplelicensing.AnyLicenseInfo; +import org.spdx.library.model.v3_0_1.simplelicensing.SimpleLicensingText; import org.spdx.library.model.v3_0_1.software.*; import org.spdx.storage.IModelStore; -import org.spdx.storage.ISerializableModelStore; import org.spdx.storage.simple.InMemSpdxStore; +import org.spdx.tools.Verify; import org.spdx.v3jsonldstore.JsonLDStore; -import java.io.File; -import java.io.FileOutputStream; -import java.io.OutputStream; +import java.io.*; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import static org.spdx.tools.Verify.JSON_SCHEMA_RESOURCE_V3; + /** * This class attempts to implement all the SPDX specification classes and most of the properties. @@ -37,6 +58,709 @@ public class FullSpdxV3Example { static final DateTimeFormatter SPDX_DATE_FORMATTER = DateTimeFormatter.ofPattern(SpdxConstantsCompatV2.SPDX_DATE_FORMAT); + static final ObjectMapper JSON_MAPPER = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT); + + static class ExampleBuilder { + private String prefix = null; + private SpdxDocument doc = null; + private Sbom sBom = null; + private Bom aiBom = null; + private SpdxPackage pkg = null; + + public ExampleBuilder(String prefix, SpdxDocument doc) { + this.prefix = prefix; + this.doc = doc; + } + + void build() throws InvalidSPDXAnalysisException { + addCoreClasses(); + addSoftwareClasses(); + addAIandDataClasses(); + addSecurityClasses(); + addSimpleLicensingClasses(); + addExpandedLicensingClasses(); + addBuildClasses(); + addExtensionClasses(); + } + + private String getNextAnonId() throws InvalidSPDXAnalysisException { + return doc.getModelStore().getNextId(IModelStore.IdType.Anonymous); + } + + private void addExtensionClasses() throws InvalidSPDXAnalysisException { + // SpdxExtensionExample extension = new SpdxExtensionExample(doc.getModelStore(), prefix + "extension", doc.getCopyManager(), true, prefix); + // This currently causes a schema validation issue and depends on a fix in the v3JsonLD store + // extension.setExtensionProperty("Extension property value"); + // TODO: Add this back in after validation issues are addressed + Extension extension = doc.createCdxPropertiesExtension(prefix + "extension") + .addCdxProperty(doc.createCdxPropertyEntry(getNextAnonId()) + .setCdxPropName("cdxProperty") + .setCdxPropValue("value") + .build()) + .build(); + doc.getExtensions().add(extension); + } + + private void addBuildClasses() throws InvalidSPDXAnalysisException { + Build build = doc.createBuild(prefix + "build") + .setBuildType("https://github.com/spdx/tools-java/blob/master/pom.xml") + .setComment("Builds use the maven-release-plugin") + .setBuildStartTime(LocalDateTime.of(2025, 10, 15, 11, 42) + .format(SPDX_DATE_FORMATTER)) + .setBuildEndTime(LocalDateTime.of(2025, 10, 15, 11, 50) + .format(SPDX_DATE_FORMATTER)) + .addConfigSourceDigest(doc.createHash(getNextAnonId()) + .setAlgorithm(HashAlgorithm.SHA256) + .setHashValue("cc75cc9bfad1fb047f15fd60fe48806a9614c17bfee073e79e5ac3bd3e5d5271 ") + .build()) + .addConfigSourceEntrypoint("release") + .addConfigSourceUri("https://repo1.maven.org/maven2/org/spdx/tools-java/2.0.2/tools-java-2.0.2.pom") + .addEnvironment(doc.createDictionaryEntry(getNextAnonId()) + .setKey("OS") + .setValue("Windows11") + .build()) + .addParameter(doc.createDictionaryEntry(getNextAnonId()) + .setKey("Next Snapshot Version") + .setValue("2.0.3-SNAPSHOT") + .build()) + .build(); + + // hasInput relationship + SpdxFile pomFile = doc.createSpdxFile(prefix + "pomfile") + .setName("pom.xml") + .setFileKind(FileKindType.FILE) + .addVerifiedUsing(doc.createHash(getNextAnonId()) + .setAlgorithm(HashAlgorithm.SHA256) + .setHashValue("cc75cc9bfad1fb047f15fd60fe48806a9614c17bfee073e79e5ac3bd3e5d5271") + .build()) + .build(); + doc.getElements().add(pomFile); + sBom.getElements().add(pomFile); + SpdxFile srcDir = doc.createSpdxFile(prefix + "src") + .setName("src") + .setFileKind(FileKindType.DIRECTORY) + .build(); + doc.getElements().add(srcDir); + sBom.getElements().add(srcDir); + Relationship hasInput = doc.createLifecycleScopedRelationship(prefix + "hasinput") + .setRelationshipType(RelationshipType.HAS_INPUT) + .setCompleteness(RelationshipCompleteness.INCOMPLETE) + .setScope(LifecycleScopeType.BUILD) + .setFrom(build) + .addTo(srcDir) + .addTo(pomFile) + .build(); + doc.getElements().add(hasInput); + SpdxFile jarWithDependencies = doc.createSpdxFile(prefix + "jarwdeps") + .setName("tools-java-2.0.2-jar-with-dependencies.jar") + .setFileKind(FileKindType.FILE) + .addVerifiedUsing(doc.createHash(getNextAnonId()) + .setAlgorithm(HashAlgorithm.SHA256) + .setHashValue("3b326e4ea0e901d71a58627ca14c7d7ec36fc7bdb01308a78de99de2171c7904") + .build()) + .build(); + doc.getElements().add(jarWithDependencies); + Relationship hasOutput = doc.createRelationship(prefix + "hasoutput") + .setRelationshipType(RelationshipType.HAS_OUTPUT) + .setCompleteness(RelationshipCompleteness.INCOMPLETE) + .setFrom(build) + .addTo(jarWithDependencies) + .build(); + doc.getElements().add(hasOutput); + } + + private void addExpandedLicensingClasses() throws InvalidSPDXAnalysisException { + // ConjunctiveLicenseSet + AnyLicenseInfo complexLicense = doc.createConjunctiveLicenseSet(prefix + "complexlicense") + // CustomLicense + .addMember(doc.createCustomLicense(prefix + "LicenseRef-customlicense1") + .setLicenseText("This is the license text for my custom license") + .setName("Gary's Custom License") + .addSeeAlso("https://example.com") + .build()) + // OrLaterOperator + .addMember(doc.createOrLaterOperator(prefix + "complexorlater") + // ListedLicense + .setSubjectLicense(doc.createListedLicense("https://spdx.org/licenses/EPL-1.0") + .setName("Eclipse Public License 1.0") + .setLicenseText("Eclipse Public License - v 1.0\n\nTHE ACCOMPANYING PROGRAM IS PROVIDED" + + " UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE (\"AGREEMENT\"). ANY USE, REPRODUCTION " + + "OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENTS ACCEPTANCE OF THIS AGREEMENT.\n\n1. " + + "DEFINITIONS\n\n\"Contribution\" means:\n a) in the case of the initial Contributor...") + .setIsFsfLibre(true) + .setComment("EPL replaced the CPL on 28 June 2005.") + .addSeeAlso("https://opensource.org/licenses/EPL-1.0") + .build()) + .build()) + // DisjunctiveLicenseSet + .addMember(doc.createDisjunctiveLicenseSet(prefix + "complexdisjunctive") + // WithAdditionOperator + .addMember(doc.createWithAdditionOperator(prefix + "complexwith") + .setSubjectExtendableLicense((ExtendableLicense) LicenseInfoFactory.parseSPDXLicenseString("GPL-2.0-or-later")) + // ListedLicenseException + .setSubjectAddition(doc.createListedLicenseException("http://spdx.org/licenses/Autoconf-exception-2.0") + .setName("Autoconf exception 2.0") + .setComment("Typically used with GPL-2.0-only or GPL-2.0-or-later") + .setAdditionText("As a special exception, the Free Software Foundation gives unlimited " + + "permission to copy, distribute and modify the ...") + .addSeeAlso("http://ftp.gnu.org/gnu/autoconf/autoconf-2.59.tar.gz") + .build()) + .build()) + .addMember(doc.createWithAdditionOperator(prefix + "complexwithcustomaddition") + .setSubjectExtendableLicense((ExtendableLicense) LicenseInfoFactory.parseSPDXLicenseString("Apache-2.0")) + // CustomLicenseAddition + .setSubjectAddition(doc.createCustomLicenseAddition(prefix + "complexcustomaddition") + .setName("My License Addition") + .setAdditionText("Custom addition text - just for me") + .addSeeAlso("https://example.com") + .build()) + .build()) + // ExtendableLicense - Abstract + // IndividualLicensingInfo - used by listed license + // License - Abstract + .addMember(LicenseInfoFactory.parseSPDXLicenseString("MIT")) + .build()) + .build(); + doc.getElements().add(complexLicense); + } + + private void addSimpleLicensingClasses() throws InvalidSPDXAnalysisException { + // SimpleLicensingText + String simpleLicenseId = "LicenseRef-simpletext"; + String simpleAdditionId = "LicenseRef-simpleaddition"; + SimpleLicensingText slt = doc.createSimpleLicensingText(prefix + simpleLicenseId) + .setLicenseText("This is the license text to go with my license expression") + .build(); + doc.getElements().add(slt); + SimpleLicensingText simpleaddition = doc.createSimpleLicensingText(prefix + simpleAdditionId) + .setLicenseText("This is the custom addition text") + .build(); + doc.getElements().add(simpleaddition); + // LicenseExpression + doc.getElements().add(doc.createLicenseExpression(prefix + "licenseexpression") + .setLicenseExpression("Apache-2.0 AND " + simpleLicenseId + " WITH " + simpleAdditionId) + .addCustomIdToUri(doc.createDictionaryEntry(getNextAnonId()) + .setKey(simpleLicenseId) + .setValue(prefix + simpleLicenseId) + .build()) + .addCustomIdToUri(doc.createDictionaryEntry(getNextAnonId()) + .setKey(simpleAdditionId) + .setValue(prefix + simpleAdditionId) + .build()) + .build()); + // AnyLicenseInfo - Abstract + } + + private void addSecurityClasses() throws InvalidSPDXAnalysisException { + // First - let's add a dependeny with a known vulnerability + SpdxPackage log4j = doc.createSpdxPackage(prefix + "log4j") + .setName("Apache Log4j 2") + .setPackageVersion("2.14.1") + .setPackageUrl("pkg:maven/org.apache.logging.log4j/log4j-core@2.14.1") + .addExternalIdentifier(doc.createExternalIdentifier(getNextAnonId()) + .setExternalIdentifierType(ExternalIdentifierType.CPE23) + .setIssuingAuthority("NVD") + .setIdentifier("cpe:2.3:a:apache:log4j:2.14.1:-:*:*:*:*:*:*") + .build()) + .build(); + doc.getElements().add(log4j); + sBom.getElements().add(log4j); + Relationship depRelationship = doc.createRelationship(prefix + "log4jdep") + .setFrom(pkg) + .addTo(log4j) + .setRelationshipType(RelationshipType.HAS_DYNAMIC_LINK) + .setCompleteness(RelationshipCompleteness.INCOMPLETE) + .build(); + doc.getElements().add(depRelationship); + sBom.getElements().add(depRelationship); + // Since we don't want the vulnerabilities to be in the more static SBOMs, let's create a different collection + Bundle securityBundle = doc.createBundle(prefix + "securitybundle") + .setContext("Security information related to "+sBom.getObjectUri()) + .build(); + // Vulnerability + Vulnerability vuln = doc.createVulnerability(prefix + "log4jvuln") + .setSummary("Apache Log4j2 versions 2.0-alpha1 through 2.16.0 did not protect from uncontrolled recursion from self-referential lookups.") + .setDescription("Apache Log4j2 versions 2.0-alpha1 through 2.16.0 (excluding 2.12.3 and 2.3.1) did not " + + "protect from uncontrolled recursion from self-referential lookups. This allows an attacker " + + "with control over ...") + .setPublishedTime(LocalDateTime.of(2021, 12, 18, 0, 0) + .format(SPDX_DATE_FORMATTER)) + .addExternalIdentifier(doc.createExternalIdentifier(getNextAnonId()) + .setExternalIdentifierType(ExternalIdentifierType.CVE) + .setIdentifier("CVE-2021-45105") + .addIdentifierLocator("https://www.cve.org/CVERecord?id=CVE-2021-45105") + .build()) + .addExternalRef(doc.createExternalRef(getNextAnonId()) + .setExternalRefType(ExternalRefType.SECURITY_ADVISORY) + .addLocator("https://nvd.nist.gov/vuln/detail/CVE-2021-45105") + .build()) + .build(); + doc.getElements().add(vuln); + securityBundle.getElements().add(vuln); + Relationship log4jVulnRel = doc.createRelationship(prefix + "log4jvulnrelationship") + .setRelationshipType(RelationshipType.HAS_ASSOCIATED_VULNERABILITY) + .setCompleteness(RelationshipCompleteness.INCOMPLETE) + .setFrom(log4j) + .addTo(vuln) + .build(); + doc.getElements().add(log4jVulnRel); + securityBundle.getElements().add(log4jVulnRel); + Relationship pkgVulnRel = doc.createRelationship(prefix + "pkgvulnrelationship") + .setRelationshipType(RelationshipType.HAS_ASSOCIATED_VULNERABILITY) + .setCompleteness(RelationshipCompleteness.INCOMPLETE) + .setFrom(pkg) + .addTo(vuln) + .build(); + doc.getElements().add(pkgVulnRel); + securityBundle.getElements().add(pkgVulnRel); + // CvssV2VulnAssessmentRelationship + Agent supplierAgent = doc.createAgent(prefix + "assessmentagent") + .setName("Supplier of Assessments") + .setComment("This would be the supplier of the vulnerability assessments") + .build(); + CvssV2VulnAssessmentRelationship cvssV2 = doc.createCvssV2VulnAssessmentRelationship(prefix + "cvssv2vuln") + .setRelationshipType(RelationshipType.HAS_ASSESSMENT_FOR) + .setFrom(vuln) + .addTo(log4j) + .setScore(5.0) + .setVectorString("(AV:N/AC:M/Au:N/C:P/I:N/A:N)") + .setAssessedElement(log4j) + .setSuppliedBy(supplierAgent) + .setPublishedTime(LocalDateTime.of(2023, 9, 18, 0, 0) + .format(SPDX_DATE_FORMATTER)) + .build(); + doc.getElements().add(cvssV2); + securityBundle.getElements().add(cvssV2); + // CvssV3VulnAssessmentRelationship + CvssV3VulnAssessmentRelationship cvssV3 = doc.createCvssV3VulnAssessmentRelationship(prefix + "cvssv3vuln") + .setRelationshipType(RelationshipType.HAS_ASSESSMENT_FOR) + .setFrom(vuln) + .addTo(log4j) + .setScore(5.0) + .setSeverity(CvssSeverityType.CRITICAL) + .setVectorString("CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H") + .setAssessedElement(log4j) + .setSuppliedBy(supplierAgent) + .setPublishedTime(LocalDateTime.of(2023, 9, 18, 0, 0) + .format(SPDX_DATE_FORMATTER)) + .build(); + doc.getElements().add(cvssV3); + securityBundle.getElements().add(cvssV3); + // CvssV4VulnAssessmentRelationship + CvssV4VulnAssessmentRelationship cvssV4 = doc.createCvssV4VulnAssessmentRelationship(prefix + "cvssv4vuln") + .setRelationshipType(RelationshipType.HAS_ASSESSMENT_FOR) + .setFrom(vuln) + .addTo(log4j) + .setScore(5.0) + .setSeverity(CvssSeverityType.CRITICAL) + .setVectorString("(AV:N/AC:M/Au:N/C:P/I:N/A:N)") + .setAssessedElement(log4j) + .setSuppliedBy(supplierAgent) + .setPublishedTime(LocalDateTime.of(2023, 9, 18, 0, 0) + .format(SPDX_DATE_FORMATTER)) + .build(); + doc.getElements().add(cvssV4); + securityBundle.getElements().add(cvssV4); + // EpssVulnAssessmentRelationship + EpssVulnAssessmentRelationship epss = doc.createEpssVulnAssessmentRelationship(prefix + "epss") + .setRelationshipType(RelationshipType.HAS_ASSESSMENT_FOR) + .setFrom(vuln) + .addTo(log4j) + .setProbability(0.01) + .setPercentile(0.4) + .setAssessedElement(log4j) + .setSuppliedBy(supplierAgent) + .setPublishedTime(LocalDateTime.of(2023, 9, 18, 0, 0) + .format(SPDX_DATE_FORMATTER)) + .build(); + doc.getElements().add(epss); + securityBundle.getElements().add(epss); + // ExploitCatalogVulnAssessmentRelationship + //TODO: The schema has "locator" for the field while the generated Java code has "securityLocator" + //Need to regenerate the library then uncomment the example below +// ExploitCatalogVulnAssessmentRelationship excat = doc.createExploitCatalogVulnAssessmentRelationship(prefix + "exploitcat") +// .setRelationshipType(RelationshipType.HAS_ASSESSMENT_FOR) +// .setFrom(vuln) +// .addTo(log4j) +// .setCatalogType(ExploitCatalogType.KEV) +// .setSecurityLocator("https://www.cisa.gov/known-exploited-vulnerabilities-catalog") +// .setExploited(true) +// .setAssessedElement(log4j) +// .setSuppliedBy(supplierAgent) +// .setPublishedTime(LocalDateTime.of(2023, 9, 18, 0, 0) +// .format(SPDX_DATE_FORMATTER)) +// .build(); +// doc.getElements().add(excat); +// securityBundle.getElements().add(excat); + + // SsvcVulnAssessmentRelationship + SsvcVulnAssessmentRelationship ssvs = doc.createSsvcVulnAssessmentRelationship(prefix + "ssvs") + .setRelationshipType(RelationshipType.HAS_ASSESSMENT_FOR) + .setFrom(vuln) + .addTo(log4j) + .setDecisionType(SsvcDecisionType.ACT) + .setAssessedElement(log4j) + .setSuppliedBy(supplierAgent) + .setPublishedTime(LocalDateTime.of(2023, 9, 18, 0, 0) + .format(SPDX_DATE_FORMATTER)) + .build(); + doc.getElements().add(ssvs); + securityBundle.getElements().add(ssvs); + // VexAffectedVulnAssessmentRelationship + VexAffectedVulnAssessmentRelationship vexAffected = doc.createVexAffectedVulnAssessmentRelationship(prefix + "vexaffected") + .setRelationshipType(RelationshipType.AFFECTS) + .setFrom(vuln) + .addTo(log4j) + .setActionStatement("Upgrade to version 2.20 or later") + .setAssessedElement(log4j) + .setSuppliedBy(supplierAgent) + .setPublishedTime(LocalDateTime.of(2023, 9, 18, 0, 0) + .format(SPDX_DATE_FORMATTER)) + .build(); + doc.getElements().add(vexAffected); + securityBundle.getElements().add(vexAffected); + // VexFixedVulnAssessmentRelationship + VexFixedVulnAssessmentRelationship vexFixed = doc.createVexFixedVulnAssessmentRelationship(prefix + "vexfixed") + .setRelationshipType(RelationshipType.AFFECTS) + .setFrom(vuln) + .addTo(pkg) + .setAssessedElement(log4j) + .setSuppliedBy(supplierAgent) + .setPublishedTime(LocalDateTime.of(2023, 9, 18, 0, 0) + .format(SPDX_DATE_FORMATTER)) + .build(); + doc.getElements().add(vexFixed); + securityBundle.getElements().add(vexFixed); + // VexNotAffectedVulnAssessmentRelationship + VexNotAffectedVulnAssessmentRelationship vexNotAffected = doc.createVexNotAffectedVulnAssessmentRelationship(prefix + "vexnotaffected") + .setRelationshipType(RelationshipType.AFFECTS) + .setFrom(vuln) + .addTo(pkg) + .setJustificationType(VexJustificationType.INLINE_MITIGATIONS_ALREADY_EXIST) + .setImpactStatement("No longer using this vulnerable part of this library.") + .setAssessedElement(log4j) + .setSuppliedBy(supplierAgent) + .setPublishedTime(LocalDateTime.of(2023, 9, 18, 0, 0) + .format(SPDX_DATE_FORMATTER)) + .build(); + doc.getElements().add(vexNotAffected); + securityBundle.getElements().add(vexNotAffected); + // VexUnderInvestigationVulnAssessmentRelationship + VexUnderInvestigationVulnAssessmentRelationship vexUnderInvestigation = doc.createVexUnderInvestigationVulnAssessmentRelationship(prefix + "vexunderinvestigation") + .setRelationshipType(RelationshipType.AFFECTS) + .setFrom(vuln) + .addTo(pkg) + .setAssessedElement(log4j) + .setSuppliedBy(supplierAgent) + .setPublishedTime(LocalDateTime.of(2023, 9, 18, 0, 0) + .format(SPDX_DATE_FORMATTER)) + .build(); + doc.getElements().add(vexUnderInvestigation); + securityBundle.getElements().add(vexUnderInvestigation); + // VexVulnAssessmentRelationship - Abstract + // VulnAssessmentRelationship - Abstract + } + + private void addCoreClasses() throws InvalidSPDXAnalysisException { + // Agent - Abstract, already in creation info + // Annotation + doc.getElements().add(doc.createAnnotation(prefix + "docannotation") + .setStatement("This document is for example purposes only") + .setAnnotationType(AnnotationType.OTHER) + .setSubject(doc) + .build()); + // Artifact - Abstract - used in software package and several others + // Bom - will be used as an AI BOM and software BOM + // Bundle + doc.getElements().add(doc.createBundle(prefix + "bundle") + .setComment("This is just an example of a concrete Bundle class - the elements are not used elsewhere in the SPDX document") + .setContext("Custom Licenses") + .addElement(doc.createCustomLicense(prefix + "LicenseRef-CustomLicense1") + .setLicenseText("This is a custom license text number one.") + .build()) + .addElement(doc.createCustomLicense(prefix + "LicenseRef-CustomLicense2") + .setLicenseText("This is a custom license text number two.") + .build()) + .build()); + // CreationInfo - Already created + // DictionaryEntry - Used in several places including SimpleLicensing + // Element - Abstract + // ElementCollection - Abstract + // ExternalIdentifier - Used in Security profile + // Organization + doc.getCreationInfo().getCreatedBys().add(doc.createOrganization(prefix + "spdxorg") + .setName("System Package Data Exchange (SPDX)") + .build()); + // ExternalMap + String orgLocation = "https://external/organization/spdxdata"; + String orgPrefix = orgLocation + "#"; + String orgUri = orgPrefix + "org"; + ExternalOrganization externalOrg = new ExternalOrganization(doc.getModelStore(), + orgUri, doc.getCopyManager(), + true, orgLocation); + doc.getCreationInfo().getCreatedBys().add(externalOrg); + doc.getSpdxImports().add(doc.createExternalMap(getNextAnonId()) + .setExternalSpdxId(orgUri) + .setLocationHint(orgLocation) + .build()); + // Hash - Used in file + // IndividualElement - Used in software package originated by + // IntegrityMethod - Used in file and package + // LifecycleScopedRelationship + // NamespaceMap - Used in doc already + // PackageVerificationCode - Going to ignore - deprecated + // Person - Used in creation info + // PositiveIntegerRange - Used in snippets + // Relationship - Used in software + // SoftwareAgent + doc.getCreationInfo().getCreatedBys().add(doc.createSoftwareAgent(prefix + "softwareagent") + .setName("SPDX Spec Github CI") + .build()); + // SpdxDocument - already used + // ExternalRef + // Tool + doc.getCreationInfo().getCreatedUsings().add(doc.createTool(prefix + "creationtool") + .setName("tools-java") + .setComment("Created by the FullSpdxV3Example.java utility in tools-java") + .addExternalRef(doc.createExternalRef(getNextAnonId()) + .setExternalRefType(ExternalRefType.MAVEN_CENTRAL) + .addLocator("org.spdx:tools-java") + .build()) + .build()); + + } + + private void addSoftwareClasses() throws InvalidSPDXAnalysisException { + // Sbom + sBom = doc.createSbom(prefix + "sbom") + .setName("AI SBOM") + .addSbomType(SbomType.ANALYZED) + .addProfileConformance(ProfileIdentifierType.CORE) + .addProfileConformance(ProfileIdentifierType.SOFTWARE) + .addProfileConformance(ProfileIdentifierType.BUILD) + .addProfileConformance(ProfileIdentifierType.SECURITY) + .addProfileConformance(ProfileIdentifierType.EXPANDED_LICENSING) + .build(); + doc.getElements().add(sBom); + doc.getRootElements().add(sBom); + // Package + pkg = doc.createSpdxPackage(prefix + "tools-java") + .setName("tools-java") + .setPrimaryPurpose(SoftwarePurpose.APPLICATION) + .addAdditionalPurpose(SoftwarePurpose.LIBRARY) + .addAttributionText("Maintained by the SPDX Community") + .setBuiltTime(LocalDateTime.of(2025, 10, 15, 9, 10) + .format(SPDX_DATE_FORMATTER)) + // ContentIdentifier + .addContentIdentifier(doc.createContentIdentifier(getNextAnonId()) + .setContentIdentifierType(ContentIdentifierType.GITOID) + .setContentIdentifierValue("23bd470259f55641eb72b0c5d733edac014a4554") + .build()) + .setCopyrightText("Copyright (c) Source Auditor Inc.") + .setDescription("A command-line utility for creating, converting, comparing, and validating SPDX documents across multiple formats.") + .setDownloadLocation("https://github.com/spdx/tools-java/releases/download/v2.0.2/tools-java-2.0.2.zip") + .addExternalIdentifier(doc.createExternalIdentifier(getNextAnonId()) + .setExternalIdentifierType(ExternalIdentifierType.URL_SCHEME) + .setIdentifier("https://github.com/spdx/tools-java") + .setIssuingAuthority("GitHub") + .build()) + .addExternalRef(doc.createExternalRef(getNextAnonId()) + .setExternalRefType(ExternalRefType.MAVEN_CENTRAL) + .addLocator("org.spdx:tools-java:jar:2.0.2") + .build()) + .setPackageUrl("pkg:maven/org.spdx/tools-java@2.0.2") + .setPackageVersion("2.0.2") + .setReleaseTime(LocalDateTime.of(2025, 10, 15, 11, 50) + .format(SPDX_DATE_FORMATTER)) + .setSourceInfo("This package came from the original source - the official SPDX GitHub repo and build process") + .addStandardName("SPDX Version 2.X and SPDX Version 3.0") + .setHomePage("https://github.com/spdx/tools-java") + .addOriginatedBy(new SpdxOrganization()) + .setSuppliedBy(new SpdxOrganization()) + .setSummary("A command-line utility for creating, converting, comparing, and validating SPDX documents across multiple formats.") + .addSupportLevel(SupportType.LIMITED_SUPPORT) + .setValidUntilTime(LocalDateTime.of(2027, 10, 15, 9, 10) + .format(SPDX_DATE_FORMATTER)) + .addVerifiedUsing(doc.createHash(getNextAnonId()) + .setAlgorithm(HashAlgorithm.SHA256) + .setHashValue("c37ce759c3867780d55791a1804101d288fa921e77ed791e6c053fd5d7513d0d") + .build()) + .build(); + doc.getElements().add(pkg); + sBom.getElements().add(pkg); + sBom.getRootElements().add(pkg); + // File + SpdxFile sourceFile = doc.createSpdxFile(prefix + "example-source") + .setPrimaryPurpose(SoftwarePurpose.SOURCE) + .setContentType("text/plain") + .setCopyrightText("Copyright (c) 2025 Source Auditor Inc.") + .setFileKind(FileKindType.FILE) + .setName("./examples/org/spdx/examples/FullSpdxV3Example.java") + .build(); + sBom.getElements().add(sourceFile); + doc.getElements().add(sourceFile); + // Relationships - declared license, concluded license, generated from + doc.getElements().add(doc.createRelationship(prefix + "example-source-to-pkg") + .setRelationshipType(RelationshipType.GENERATES) + .setFrom(sourceFile) + .addTo(pkg) + .setCompleteness(RelationshipCompleteness.INCOMPLETE) + .build()); + AnyLicenseInfo declared = LicenseInfoFactory.parseSPDXLicenseString("Apache-2.0", + doc.getModelStore(), prefix, doc.getCopyManager(), new ArrayList<>()); + AnyLicenseInfo concluded = LicenseInfoFactory.parseSPDXLicenseString("Apache-2.0", + doc.getModelStore(), prefix, doc.getCopyManager(), new ArrayList<>()); + doc.getElements().add(doc.createRelationship(prefix + "source-declared") + .setRelationshipType(RelationshipType.HAS_DECLARED_LICENSE) + .setFrom(sourceFile) + .addTo(declared) + .setCompleteness(RelationshipCompleteness.NO_ASSERTION) + .build()); + doc.getElements().add(doc.createRelationship(prefix + "source-concluded") + .setRelationshipType(RelationshipType.HAS_CONCLUDED_LICENSE) + .setFrom(sourceFile) + .addTo(concluded) + .setCompleteness(RelationshipCompleteness.COMPLETE) + .build()); + doc.getElements().add(doc.createRelationship(prefix + "pkg-declared") + .setRelationshipType(RelationshipType.HAS_DECLARED_LICENSE) + .setFrom(pkg) + .addTo(declared) + .setCompleteness(RelationshipCompleteness.NO_ASSERTION) + .build()); + doc.getElements().add(doc.createRelationship(prefix + "pkg-concluded") + .setRelationshipType(RelationshipType.HAS_CONCLUDED_LICENSE) + .setFrom(pkg) + .addTo(concluded) + .setCompleteness(RelationshipCompleteness.COMPLETE) + .build()); + // Snippet + Snippet snippet = doc.createSnippet(prefix + "snippet") + .addAttributionText("Example code created by Gary O'Neall") + .setDescription("Main method for the FullSpdxV3Example.java") + .setCopyrightText("Copyright (c) 2025 Source Auditor Inc.") + .setByteRange(doc.createPositiveIntegerRange(getNextAnonId()) + .setBeginIntegerRange(43) + .setEndIntegerRange(89) + .build()) + .setLineRange(doc.createPositiveIntegerRange(getNextAnonId()) + .setBeginIntegerRange(1548) + .setEndIntegerRange(3955) + .build()) + .setName("main(String[] args)") + .setSnippetFromFile(sourceFile) + .build(); + doc.getElements().add(snippet); + sBom.getElements().add(snippet); + doc.getElements().add(doc.createRelationship(prefix + "snippet-declared") + .setRelationshipType(RelationshipType.HAS_DECLARED_LICENSE) + .setFrom(snippet) + .addTo(declared) + .setCompleteness(RelationshipCompleteness.COMPLETE) + .build()); + doc.getElements().add(doc.createRelationship(prefix + "snippet-concluded") + .setRelationshipType(RelationshipType.HAS_CONCLUDED_LICENSE) + .setFrom(snippet) + .addTo(concluded) + .setCompleteness(RelationshipCompleteness.COMPLETE) + .build()); + // SoftwareArtifact - Abstract + } + + private void addAIandDataClasses() throws InvalidSPDXAnalysisException { + aiBom = doc.createBom(prefix + "aibom") + .setName("AI SBOM") + .addProfileConformance(ProfileIdentifierType.CORE) + .addProfileConformance(ProfileIdentifierType.SOFTWARE) + .addProfileConformance(ProfileIdentifierType.AI) + .addProfileConformance(ProfileIdentifierType.DATASET) + .build(); + doc.getElements().add(aiBom); + doc.getRootElements().add(aiBom); + // DatasetPackage + DatasetPackage dataset = doc.createDatasetPackage(prefix + "dataset") + .addAnonymizationMethodUsed("Perturbation") + .setConfidentialityLevel(ConfidentialityLevelType.GREEN) + .setDataCollectionProcess("WWW data under open licenses") + .setDataCollectionProcess("Crawler") + .addDataPreprocessing("Anonymization using perturbation of sensitive data") + .setDatasetAvailability(DatasetAvailabilityType.QUERY) + .setDatasetNoise("Includes data input by humans - subject to error") + .setDatasetSize(4000000) + .addDatasetType(DatasetType.TEXT) + .setDatasetUpdateMechanism("Automated crawler") + .setHasSensitivePersonalInformation(PresenceType.NO) + .setIntendedUse("LLM training") + .addKnownBias("Typical human bias representative from the global WWW") + .addSensor(doc.createDictionaryEntry(getNextAnonId()) + .setKey("crawler") + .setValue("webcrawler") + .build()) + .setBuiltTime(LocalDateTime.of(2025, 10, 15, 11, 50) + .format(SPDX_DATE_FORMATTER)) + .addOriginatedBy(doc.createOrganization(prefix + "dataorg") + .setName("Data Corp.") + .build()) + .setReleaseTime(LocalDateTime.of(2025, 10, 22, 8, 50) + .format(SPDX_DATE_FORMATTER)) + .setDownloadLocation("https://com.data-corp.data/mydata") + .setPrimaryPurpose(SoftwarePurpose.DATA) + .build(); + doc.getElements().add(dataset); + aiBom.getElements().add(dataset); + // AIPackage + AIPackage aiPackage = doc.createAIPackage(prefix + "aipackage") + .setAutonomyType(PresenceType.YES) + .addDomain("Automotive") + // EnergyConsumption + .setEnergyConsumption(doc.createEnergyConsumption(getNextAnonId()) + // EnergyConsumptionDescription + .addFinetuningEnergyConsumption(doc.createEnergyConsumptionDescription(getNextAnonId()) + .setEnergyQuantity(150.0) + .setEnergyUnit(EnergyUnitType.KILOWATT_HOUR) + .build()) + .addInferenceEnergyConsumption(doc.createEnergyConsumptionDescription(getNextAnonId()) + .setEnergyQuantity(0.7) + .setEnergyUnit(EnergyUnitType.KILOWATT_HOUR) + .build()) + .addTrainingEnergyConsumption(doc.createEnergyConsumptionDescription(getNextAnonId()) + .setEnergyQuantity(15000.3) + .setEnergyUnit(EnergyUnitType.KILOWATT_HOUR) + .build()) + .build()) + .addHyperparameter(doc.createDictionaryEntry(getNextAnonId()) + .setKey("Hidden layers") + .setValue("14") + .build()) + .setInformationAboutApplication("Used in self driving cars") + .setInformationAboutTraining("Trained from data collected from auto cameras, sensors and WWW") + .setLimitation("Limited by amount of situations encountered from autos used for training") + .addMetric(doc.createDictionaryEntry(getNextAnonId()) + .setKey("Operator Interventions") + .setValue("432") + .build()) + .addMetricDecisionThreshold(doc.createDictionaryEntry(getNextAnonId()) + .setKey("Operator Interventions") + .setValue("100") + .build()) + .addModelDataPreprocessing("1. data cleaning") + .addModelExplainability("Behaviors from the auto driving car when observed from a safety driver") + .setSafetyRiskAssessment(SafetyRiskAssessmentType.SERIOUS) + .addStandardCompliance("UL 4600") + .addTypeOfModel("LLM") + .setUseSensitivePersonalInformation(PresenceType.NO) + .build(); + doc.getElements().add(aiPackage); + aiBom.getElements().add(aiPackage); + Relationship usesData = doc.createRelationship(prefix + "usesdata") + .setRelationshipType(RelationshipType.TRAINED_ON) + .setFrom(dataset) + .addTo(aiPackage) + .setCompleteness(RelationshipCompleteness.INCOMPLETE) + .build(); + } + } + /** * @param args args[0] is the file path for the output serialized file */ @@ -60,9 +784,11 @@ public static void main(String[] args) throws Exception { } SpdxModelFactory.init(); IModelCopyManager copyManager = new ModelCopyManager(); - try (ISerializableModelStore modelStore = new JsonLDStore(new InMemSpdxStore())) { - String prefix = "https://spdx.github.io/spdx-spec/v3.0.1/examples/full-example-eaa46bdcfa20#"; - DefaultModelStore.initialize(modelStore, prefix, copyManager); + try (JsonLDStore modelStore = new JsonLDStore(new InMemSpdxStore())) { + modelStore.setUseExternalListedElements(true); + String defaultDocUri = "https://spdx.github.io/spdx-spec/v3.0.1/examples/full-example-eaa46bdcfa20"; + String prefix = defaultDocUri + "#"; + DefaultModelStore.initialize(modelStore, defaultDocUri, copyManager); CreationInfo creationInfo = SpdxModelClassFactoryV3.createCreationInfo( modelStore, prefix + "garyagent", "Gary O'Neall", copyManager); @@ -80,227 +806,37 @@ public static void main(String[] args) throws Exception { .addProfileConformance(ProfileIdentifierType.SECURITY) .addProfileConformance(ProfileIdentifierType.EXPANDED_LICENSING) .build(); - addCoreClasses(prefix, doc); - Sbom sbom = addSoftwareClasses(prefix, doc); + doc.setIdPrefix(prefix); + ExampleBuilder builder = new ExampleBuilder(prefix, doc); + builder.build(); + + List warnings = doc.verify(); try (OutputStream outStream = new FileOutputStream(outFile)) { modelStore.serialize(outStream); } + JsonSchemaFactory jsonSchemaFactory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V202012); + JsonSchema schema; + try (InputStream is = Verify.class.getResourceAsStream("/" + JSON_SCHEMA_RESOURCE_V3)) { + schema = jsonSchemaFactory.getSchema(is); + } + JsonNode root; + try (InputStream is = new FileInputStream(outFile)) { + root = JSON_MAPPER.readTree(is); + } + Set messages = schema.validate(root); + for (ValidationMessage msg:messages) { + warnings.add(msg.toString()); + } + if (!warnings.isEmpty()) { + System.out.println("Generated document contains the following warnings:"); + for (String warning:warnings) { + System.out.print("\t"); + System.out.println(warning); + } + } } } - private static void addCoreClasses(String prefix, SpdxDocument doc) throws InvalidSPDXAnalysisException { - // Agent - Abstract, already in creation info - // Annotation - doc.getElements().add(doc.createAnnotation(prefix + "docannotation") - .setStatement("This document is for example purposes only") - .setAnnotationType(AnnotationType.OTHER) - .setSubject(doc) - .build()); - // Artifact - Abstract - used in software package and several others - // Bom - will be used as an AI BOM and software BOM - // Bundle - doc.getElements().add(doc.createBundle(prefix + "bundle") - .setComment("This is just an example of a concrete Bundle class - the elements are not used elsewhere in the SPDX document") - .setContext("Custom Licenses") - .addElement(doc.createCustomLicense(prefix + "LicenseRef-CustomLicense1") - .setLicenseText("This is a custom license text number one.") - .build()) - .addElement(doc.createCustomLicense(prefix + "LicenseRef-CustomLicense2") - .setLicenseText("This is a custom license text number two.") - .build()) - .build()); - // CreationInfo - Already created - // DictionaryEntry - TODO: Change to make sure it has been created - // Element - Abstract - // ElementCollection - Abstract - // ExternalIdentifier - TODO: Change to make sure it has been created - // Organization - doc.getCreationInfo().getCreatedBys().add(doc.createOrganization(prefix + "spdxorg") - .setName("System Package Data Exchange (SPDX)") - .build()); - // ExternalMap - String orgLocation = "https://external/organization/spdxdata"; - String orgPrefix = orgLocation + "#"; - String orgUri = orgPrefix + "org"; - ExternalOrganization externalOrg = new ExternalOrganization(doc.getModelStore(), - orgUri, doc.getCopyManager(), - true, orgLocation); - doc.getCreationInfo().getCreatedBys().add(externalOrg); - doc.getSpdxImports().add(doc.createExternalMap(doc.getModelStore().getNextId(IModelStore.IdType.Anonymous)) - .setExternalSpdxId(orgUri) - .setLocationHint(orgLocation) - .build()); - // Hash - Used in file - // IndividualElement - Used in software package originated by - // IntegrityMethod - Used in file and package - // LifecycleScopedRelationship - TODO: Change to make sure it has been created - // NamespaceMap - Used in doc already - // PackageVerificationCode - Going to ignore - deprecated - // Person - Used in creation info - // PositiveIntegerRange - TODO: Change to make sure it has been created - // Relationship - Used in software - // SoftwareAgent - doc.getCreationInfo().getCreatedBys().add(doc.createSoftwareAgent(prefix + "softwareagent") - .setName("SPDX Spec Github CI") - .build()); - // SpdxDocument - already used - // ExternalRef - // Tool - doc.getCreationInfo().getCreatedUsings().add(doc.createTool(prefix + "creationtool") - .setName("tools-java") - .setComment("Created by the FullSpdxV3Example.java utility in tools-java") - .addExternalRef(doc.createExternalRef(doc.getModelStore().getNextId(IModelStore.IdType.Anonymous)) - .setExternalRefType(ExternalRefType.MAVEN_CENTRAL) - .addLocator("org.spdx:tools-java") - .build()) - .build()); - - } - - private static Sbom addSoftwareClasses(String prefix, SpdxDocument doc) throws InvalidSPDXAnalysisException { - // Sbom - Sbom sbom = doc.createSbom(prefix + "aibom") - .setName("AI SBOM") - .addSbomType(SbomType.ANALYZED) - .addProfileConformance(ProfileIdentifierType.CORE) - .addProfileConformance(ProfileIdentifierType.SOFTWARE) - .addProfileConformance(ProfileIdentifierType.BUILD) - .addProfileConformance(ProfileIdentifierType.SECURITY) - .addProfileConformance(ProfileIdentifierType.EXPANDED_LICENSING) - .build(); - doc.getElements().add(sbom); - doc.getRootElements().add(sbom); - // Package - SpdxPackage pkg = doc.createSpdxPackage(prefix + "tools-java") - .setName("tools-java") - .setPrimaryPurpose(SoftwarePurpose.APPLICATION) - .addAdditionalPurpose(SoftwarePurpose.LIBRARY) - .addAttributionText("Maintained by the SPDX Community") - .setBuiltTime(LocalDateTime.of(2025, 10, 15, 9, 10) - .format(SPDX_DATE_FORMATTER)) - // ContentIdentifier - .addContentIdentifier(doc.createContentIdentifier(doc.getModelStore().getNextId(IModelStore.IdType.Anonymous)) - .setContentIdentifierType(ContentIdentifierType.GITOID) - .setContentIdentifierValue("23bd470259f55641eb72b0c5d733edac014a4554") - .build()) - .setCopyrightText("Copyright (c) Source Auditor Inc.") - .setDescription("A command-line utility for creating, converting, comparing, and validating SPDX documents across multiple formats.") - .setDownloadLocation("https://github.com/spdx/tools-java/releases/download/v2.0.2/tools-java-2.0.2.zip") - .addExternalIdentifier(doc.createExternalIdentifier(doc.getModelStore().getNextId(IModelStore.IdType.Anonymous)) - .setExternalIdentifierType(ExternalIdentifierType.URL_SCHEME) - .setIdentifier("https://github.com/spdx/tools-java") - .setIssuingAuthority("GitHub") - .build()) - .addExternalRef(doc.createExternalRef(doc.getModelStore().getNextId(IModelStore.IdType.Anonymous)) - .setExternalRefType(ExternalRefType.MAVEN_CENTRAL) - .addLocator("org.spdx:tools-java:jar:2.0.2") - .build()) - .setPackageUrl("pkg:maven/org.spdx/tools-java@2.0.2") - .setPackageVersion("2.0.2") - .setReleaseTime(LocalDateTime.of(2025, 10, 15, 11, 50) - .format(SPDX_DATE_FORMATTER)) - .setSourceInfo("This package came from the original source - the official SPDX GitHub repo and build process") - .addStandardName("SPDX Version 2.X and SPDX Version 3.0") - .setHomePage("https://github.com/spdx/tools-java") - .addOriginatedBy(new SpdxOrganization()) - .setSuppliedBy(new SpdxOrganization()) - .setSummary("A command-line utility for creating, converting, comparing, and validating SPDX documents across multiple formats.") - .addSupportLevel(SupportType.LIMITED_SUPPORT) - .setValidUntilTime(LocalDateTime.of(2027, 10, 15, 9, 10) - .format(SPDX_DATE_FORMATTER)) - .addVerifiedUsing(doc.createHash(doc.getModelStore().getNextId(IModelStore.IdType.Anonymous)) - .setAlgorithm(HashAlgorithm.SHA256) - .setHashValue("c37ce759c3867780d55791a1804101d288fa921e77ed791e6c053fd5d7513d0d") - .build()) - .build(); - doc.getElements().add(pkg); - sbom.getElements().add(pkg); - sbom.getRootElements().add(pkg); - // File - SpdxFile sourceFile = doc.createSpdxFile(prefix + "example-source") - .setPrimaryPurpose(SoftwarePurpose.SOURCE) - .setContentType("text/plain") - .setCopyrightText("Copyright (c) 2025 Source Auditor Inc.") - .setFileKind(FileKindType.FILE) - .setName("./examples/org/spdx/examples/FullSpdxV3Example.java") - .build(); - sbom.getElements().add(sourceFile); - doc.getElements().add(sourceFile); - // Relationships - declared license, concluded license, generated from - doc.getElements().add(doc.createRelationship(prefix + "example-source-to-pkg") - .setRelationshipType(RelationshipType.GENERATES) - .setFrom(sourceFile) - .addTo(pkg) - .build()); - AnyLicenseInfo declared = LicenseInfoFactory.parseSPDXLicenseString("Apache-2.0", - doc.getModelStore(), prefix, doc.getCopyManager(), new ArrayList<>()); - AnyLicenseInfo concluded = LicenseInfoFactory.parseSPDXLicenseString("Apache-2.0", - doc.getModelStore(), prefix, doc.getCopyManager(), new ArrayList<>()); - doc.getElements().add(doc.createRelationship(prefix + "source-declared") - .setRelationshipType(RelationshipType.HAS_DECLARED_LICENSE) - .setFrom(sourceFile) - .addTo(declared) - .build()); - doc.getElements().add(doc.createRelationship(prefix + "source-concluded") - .setRelationshipType(RelationshipType.HAS_CONCLUDED_LICENSE) - .setFrom(sourceFile) - .addTo(concluded) - .build()); - doc.getElements().add(doc.createRelationship(prefix + "pkg-declared") - .setRelationshipType(RelationshipType.HAS_DECLARED_LICENSE) - .setFrom(pkg) - .addTo(declared) - .build()); - doc.getElements().add(doc.createRelationship(prefix + "pkg-concluded") - .setRelationshipType(RelationshipType.HAS_CONCLUDED_LICENSE) - .setFrom(pkg) - .addTo(concluded) - .build()); - // Snippet - Snippet snippet = doc.createSnippet(prefix + "snippet") - .addAttributionText("Example code created by Gary O'Neall") - .setDescription("Main method for the FullSpdxV3Example.java") - .setCopyrightText("Copyright (c) 2025 Source Auditor Inc.") - .setByteRange(doc.createPositiveIntegerRange(doc.getModelStore().getNextId(IModelStore.IdType.Anonymous)) - .setBeginIntegerRange(43) - .setEndIntegerRange(89) - .build()) - .setLineRange(doc.createPositiveIntegerRange(doc.getModelStore().getNextId(IModelStore.IdType.Anonymous)) - .setBeginIntegerRange(1548) - .setEndIntegerRange(3955) - .build()) - .setName("main(String[] args)") - .setSnippetFromFile(sourceFile) - .build(); - doc.getElements().add(snippet); - sbom.getElements().add(snippet); - doc.getElements().add(doc.createRelationship(prefix + "snippet-declared") - .setRelationshipType(RelationshipType.HAS_DECLARED_LICENSE) - .setFrom(snippet) - .addTo(declared) - .build()); - doc.getElements().add(doc.createRelationship(prefix + "snippet-concluded") - .setRelationshipType(RelationshipType.HAS_CONCLUDED_LICENSE) - .setFrom(snippet) - .addTo(concluded) - .build()); - // SoftwareArtifact - Abstract - return sbom; - } - - - private static void addAIandDataClasses(String prefix, SpdxDocument doc) throws InvalidSPDXAnalysisException { - Bom aiBom = doc.createBom(prefix + "aibom") - .setName("AI SBOM") - .addProfileConformance(ProfileIdentifierType.CORE) - .addProfileConformance(ProfileIdentifierType.SOFTWARE) - .addProfileConformance(ProfileIdentifierType.AI) - .addProfileConformance(ProfileIdentifierType.DATASET) - .build(); - doc.getElements().add(aiBom); - doc.getRootElements().add(aiBom); - } - private static void usage() { System.out.println("Generates an SPDX JSON-LD file containing all of the supported classes."); System.out.println("Usage: FullSpdxV3Example outputfile"); diff --git a/examples/org/spdx/examples/SpdxExtensionExample.java b/examples/org/spdx/examples/SpdxExtensionExample.java new file mode 100644 index 0000000..135a80e --- /dev/null +++ b/examples/org/spdx/examples/SpdxExtensionExample.java @@ -0,0 +1,28 @@ +package org.spdx.examples; + +import org.spdx.core.IModelCopyManager; +import org.spdx.core.InvalidSPDXAnalysisException; +import org.spdx.library.model.v3_0_1.extension.Extension; +import org.spdx.storage.IModelStore; +import org.spdx.storage.PropertyDescriptor; + +import javax.annotation.Nullable; +import java.util.Optional; + +public class SpdxExtensionExample extends Extension { + + static final PropertyDescriptor EXTENSION_PROPERTY_DESCRIPTOR = new PropertyDescriptor("extensionProp", "https://my/extension/namespace/"); + + public SpdxExtensionExample(IModelStore modelStore, String objectUri, @Nullable IModelCopyManager copyManager, boolean create, String idPrefix) throws InvalidSPDXAnalysisException { + super(modelStore, objectUri, copyManager, create, idPrefix); + } + + public SpdxExtensionExample setExtensionProperty(String value) throws InvalidSPDXAnalysisException { + setPropertyValue(EXTENSION_PROPERTY_DESCRIPTOR, value); + return this; + } + + public Optional getExtensionProperty() throws InvalidSPDXAnalysisException { + return getStringPropertyValue(EXTENSION_PROPERTY_DESCRIPTOR); + } +} diff --git a/src/main/java/org/spdx/tools/Verify.java b/src/main/java/org/spdx/tools/Verify.java index d4d050d..10a91ca 100644 --- a/src/main/java/org/spdx/tools/Verify.java +++ b/src/main/java/org/spdx/tools/Verify.java @@ -54,9 +54,9 @@ public class Verify { static final int MIN_ARGS = 1; static final int MAX_ARGS = 2; static final int ERROR_STATUS = 1; - private static final String JSON_SCHEMA_RESOURCE_V2_3 = "resources/spdx-schema-v2.3.json"; - private static final String JSON_SCHEMA_RESOURCE_V2_2 = "resources/spdx-schema-v2.2.json"; - private static final String JSON_SCHEMA_RESOURCE_V3 = "resources/spdx-schema-v3.0.1.json"; + public static final String JSON_SCHEMA_RESOURCE_V2_3 = "resources/spdx-schema-v2.3.json"; + public static final String JSON_SCHEMA_RESOURCE_V2_2 = "resources/spdx-schema-v2.2.json"; + public static final String JSON_SCHEMA_RESOURCE_V3 = "resources/spdx-schema-v3.0.1.json"; static final ObjectMapper JSON_MAPPER = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT); From 5d1ce1f12e5481bd4d28749cdfa14f102dae59f0 Mon Sep 17 00:00:00 2001 From: Gary O'Neall Date: Mon, 27 Oct 2025 12:13:13 -0700 Subject: [PATCH 27/54] Update com.networknt:json-schema-validator from 1.5.9 to 2.0.0 Includes updates for breaking changes to the API --- pom.xml | 2 +- src/main/java/org/spdx/tools/Verify.java | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/pom.xml b/pom.xml index a47a2b1..7c55138 100644 --- a/pom.xml +++ b/pom.xml @@ -148,7 +148,7 @@ com.networknt json-schema-validator - 1.5.9 + 2.0.0 org.slf4j diff --git a/src/main/java/org/spdx/tools/Verify.java b/src/main/java/org/spdx/tools/Verify.java index 10a91ca..b19d119 100644 --- a/src/main/java/org/spdx/tools/Verify.java +++ b/src/main/java/org/spdx/tools/Verify.java @@ -40,10 +40,10 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; -import com.networknt.schema.JsonSchema; -import com.networknt.schema.JsonSchemaFactory; -import com.networknt.schema.SpecVersion.VersionFlag; -import com.networknt.schema.ValidationMessage; +import com.networknt.schema.Schema; +import com.networknt.schema.SchemaRegistry; +import com.networknt.schema.SpecificationVersion; +import com.networknt.schema.Error; /** * Verifies an SPDX document and lists any verification errors @@ -172,17 +172,18 @@ public static List verify(String filePath, SerFileType fileType) throws } else { jsonSchemaResource = JSON_SCHEMA_RESOURCE_V3; } - JsonSchemaFactory jsonSchemaFactory = JsonSchemaFactory.getInstance(VersionFlag.V202012); - JsonSchema schema; + SchemaRegistry schemaRegistry = + SchemaRegistry.withDefaultDialect(SpecificationVersion.DRAFT_2020_12); + Schema schema; try (InputStream is = Verify.class.getResourceAsStream("/" + jsonSchemaResource)) { - schema = jsonSchemaFactory.getSchema(is); + schema = schemaRegistry.getSchema(is); } JsonNode root; try (InputStream is = new FileInputStream(file)) { root = JSON_MAPPER.readTree(is); } - Set messages = schema.validate(root); - for (ValidationMessage msg:messages) { + List messages = schema.validate(root); + for (Error msg:messages) { retval.add(msg.toString()); } } catch (IOException e) { From 63ebf7d7e8e6d447de6c1defb6a4ef57aedf9f97 Mon Sep 17 00:00:00 2001 From: Arthit Suriyawongkul Date: Sun, 2 Nov 2025 23:34:26 +0000 Subject: [PATCH 28/54] README: Update link of SPDX Online Tools - Updated label of link to SPDX Online Tools - Updated SPDX Tools version references from 2.0.1 to 2.0.2 in examples Signed-off-by: Arthit Suriyawongkul --- README.md | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 2037d3b..e1258bf 100644 --- a/README.md +++ b/README.md @@ -54,18 +54,18 @@ The following converter tools support SPDX format: Example to convert a SPDX file from Tag to RDF format: - java -jar tools-java-2.0.1-jar-with-dependencies.jar Convert ../testResources/SPDXTagExample-v2.2.spdx TagToRDF.rdf + java -jar tools-java-2.0.2-jar-with-dependencies.jar Convert ../testResources/SPDXTagExample-v2.2.spdx TagToRDF.rdf The file formats can optionally be provided as the 3rd and 4th parameter for the input and output formats respectively. An optional 5th option `excludeLicenseDetails` will not copy the listed license properties to the output file. The following example will copy a JSON format to an RDF Turtle format without including the listed license properties: - java -jar tools-java-2.0.1-jar-with-dependencies.jar Convert ../testResources/SPDXTagExample-v2.2.spdx TagToRDF.ttl TAG RDFTTL excludeLicenseDetails + java -jar tools-java-2.0.2-jar-with-dependencies.jar Convert ../testResources/SPDXTagExample-v2.2.spdx TagToRDF.ttl TAG RDFTTL excludeLicenseDetails To convert from SPDX 2 to SPDX 3.0.1: * use the file extension `.jsonld.json` or `.jsonld`; * or add the options for the from and to file types: - java -jar tools-java-2.0.1-jar-with-dependencies.jar Convert hello.spdx hello.spdx.json TAG JSONLD + java -jar tools-java-2.0.2-jar-with-dependencies.jar Convert hello.spdx hello.spdx.json TAG JSONLD ## Compare utilities @@ -75,13 +75,13 @@ The following tools can be used to compare one or more SPDX documents: Example to compare multiple SPDX files provided in RDF format and provide a spreadsheet with the results: - java -jar tools-java-2.0.1-jar-with-dependencies.jar CompareDocs output.xlsx doc1 doc2 ... docN + java -jar tools-java-2.0.2-jar-with-dependencies.jar CompareDocs output.xlsx doc1 doc2 ... docN * CompareMultipleSpdxDocs with directory Example to compare all SPDX documents in a directory "/home/me/spdxdocs" and provide a spreadsheet with the results: - java -jar tools-java-2.0.1-jar-with-dependencies.jar CompareDocs output.xlsx /home/me/spdxdocs + java -jar tools-java-2.0.2-jar-with-dependencies.jar CompareDocs output.xlsx /home/me/spdxdocs ## SPDX Viewer @@ -91,7 +91,7 @@ The following tool can be used to "Pretty Print" an SPDX document. Sample usage: - java -jar tools-java-2.0.1-jar-with-dependencies.jar SPDXViewer ../testResources/SPDXRdfExample-v2.2.spdx.rdf + java -jar tools-java-2.0.2-jar-with-dependencies.jar SPDXViewer ../testResources/SPDXRdfExample-v2.2.spdx.rdf ## Verifier @@ -101,7 +101,7 @@ The following tool can be used to verify an SPDX document: Sample usage: - java -jar tools-java-2.0.1-jar-with-dependencies.jar Verify ../testResources/SPDXRdfExample-v2.2.spdx.rdf + java -jar tools-java-2.0.2-jar-with-dependencies.jar Verify ../testResources/SPDXRdfExample-v2.2.spdx.rdf ## Generators @@ -111,11 +111,13 @@ The following tool can be used to generate an SPDX verification code from a dire Sample usage: - java -jar tools-java-2.0.1-jar-with-dependencies.jar GenerateVerificationCode sourceDirectory [ignoredFilesRegex] + java -jar tools-java-2.0.2-jar-with-dependencies.jar GenerateVerificationCode sourceDirectory [ignoredFilesRegex] ## SPDX Validation Tool -The SPDX Workgroup provides an online interface to validate, compare, and convert SPDX documents in addition to the command line options above. The [SPDX Validation Tool](https://tools.spdx.org/app/validate/) is an all-in-one portal to upload and parse SPDX documents for validation, comparison and conversion and search the SPDX license list. +The SPDX Workgroup provides an online interface to validate, compare, and convert SPDX documents in addition to the command line options above. + +The [SPDX Online Tools](https://tools.spdx.org/) is an all-in-one portal to upload and parse SPDX documents for validation, comparison and conversion and search the SPDX license list. ## License From 5be9011b2245d0eae332129f5487e30e2ef53841 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Nov 2025 16:22:45 +0000 Subject: [PATCH 29/54] Bump org.apache.ws.xmlschema:xmlschema-core from 2.3.1 to 2.3.2 Bumps org.apache.ws.xmlschema:xmlschema-core from 2.3.1 to 2.3.2. --- updated-dependencies: - dependency-name: org.apache.ws.xmlschema:xmlschema-core dependency-version: 2.3.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7c55138..be74737 100644 --- a/pom.xml +++ b/pom.xml @@ -107,7 +107,7 @@ org.apache.ws.xmlschema xmlschema-core - 2.3.1 + 2.3.2 junit From 4633af2817fb088de7aba3b0393745b28e583dd3 Mon Sep 17 00:00:00 2001 From: Arthit Suriyawongkul Date: Mon, 3 Nov 2025 19:25:35 +0000 Subject: [PATCH 30/54] Fix deprecated isLicenseCommmentsEquals (3 m) -> isLicenseCommentsEquals (2 m) Signed-off-by: Arthit Suriyawongkul --- src/main/java/org/spdx/tools/Verify.java | 1 - src/main/java/org/spdx/tools/compare/PackageSheet.java | 2 +- src/main/java/org/spdx/tools/compare/SnippetSheet.java | 2 +- testResources/sourcefiles/PackageSheet.java | 2 +- testResources/sourcefiles/SnippetSheet.java | 2 +- 5 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/spdx/tools/Verify.java b/src/main/java/org/spdx/tools/Verify.java index b19d119..80b4f75 100644 --- a/src/main/java/org/spdx/tools/Verify.java +++ b/src/main/java/org/spdx/tools/Verify.java @@ -26,7 +26,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; -import java.util.Set; import com.fasterxml.jackson.core.JsonParseException; diff --git a/src/main/java/org/spdx/tools/compare/PackageSheet.java b/src/main/java/org/spdx/tools/compare/PackageSheet.java index 67a6159..f0c5c5e 100644 --- a/src/main/java/org/spdx/tools/compare/PackageSheet.java +++ b/src/main/java/org/spdx/tools/compare/PackageSheet.java @@ -296,7 +296,7 @@ private void addPackageToSheet(SpdxPackageComparer comparer, } Row licenseCommentRow = this.addRow(); licenseCommentRow.createCell(FIELD_COL).setCellValue(LICENSE_COMMENT_FIELD_TEXT); - if (comparer.isLicenseCommmentsEquals()) { + if (comparer.isLicenseCommentsEquals()) { setCellEqualValue(licenseCommentRow.createCell(EQUALS_COL), allDocsPresent); } else { setCellDifferentValue(licenseCommentRow.createCell(EQUALS_COL)); diff --git a/src/main/java/org/spdx/tools/compare/SnippetSheet.java b/src/main/java/org/spdx/tools/compare/SnippetSheet.java index 6f50d6c..d7ea26d 100644 --- a/src/main/java/org/spdx/tools/compare/SnippetSheet.java +++ b/src/main/java/org/spdx/tools/compare/SnippetSheet.java @@ -196,7 +196,7 @@ private void addSnippetToSheet(SpdxSnippetComparer comparer, } Row licenseCommentRow = this.addRow(); licenseCommentRow.createCell(FIELD_COL).setCellValue(LICENSE_COMMENT_FIELD_TEXT); - if (comparer.isLicenseCommmentsEquals()) { + if (comparer.isLicenseCommentsEquals()) { setCellEqualValue(licenseCommentRow.createCell(EQUALS_COL), allDocsPresent); } else { setCellDifferentValue(licenseCommentRow.createCell(EQUALS_COL)); diff --git a/testResources/sourcefiles/PackageSheet.java b/testResources/sourcefiles/PackageSheet.java index c99e9f8..fddb1f0 100644 --- a/testResources/sourcefiles/PackageSheet.java +++ b/testResources/sourcefiles/PackageSheet.java @@ -294,7 +294,7 @@ private void addPackageToSheet(SpdxPackageComparer comparer, } Row licenseCommentRow = this.addRow(); licenseCommentRow.createCell(FIELD_COL).setCellValue(LICENSE_COMMENT_FIELD_TEXT); - if (comparer.isLicenseCommmentsEquals()) { + if (comparer.isLicenseCommentsEquals()) { setCellEqualValue(licenseCommentRow.createCell(EQUALS_COL), allDocsPresent); } else { setCellDifferentValue(licenseCommentRow.createCell(EQUALS_COL)); diff --git a/testResources/sourcefiles/SnippetSheet.java b/testResources/sourcefiles/SnippetSheet.java index e9a0c45..ebf81c6 100644 --- a/testResources/sourcefiles/SnippetSheet.java +++ b/testResources/sourcefiles/SnippetSheet.java @@ -196,7 +196,7 @@ private void addSnippetToSheet(SpdxSnippetComparer comparer, } Row licenseCommentRow = this.addRow(); licenseCommentRow.createCell(FIELD_COL).setCellValue(LICENSE_COMMENT_FIELD_TEXT); - if (comparer.isLicenseCommmentsEquals()) { + if (comparer.isLicenseCommentsEquals()) { setCellEqualValue(licenseCommentRow.createCell(EQUALS_COL), allDocsPresent); } else { setCellDifferentValue(licenseCommentRow.createCell(EQUALS_COL)); From e6ffecf0c97d0681cfbd1726e9fb083adc31d0b3 Mon Sep 17 00:00:00 2001 From: Arthit Suriyawongkul Date: Mon, 3 Nov 2025 19:35:13 +0000 Subject: [PATCH 31/54] Add javadoc for SpdxToolsHelper Signed-off-by: Arthit Suriyawongkul --- .../java/org/spdx/tools/SpdxToolsHelper.java | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/spdx/tools/SpdxToolsHelper.java b/src/main/java/org/spdx/tools/SpdxToolsHelper.java index b7127d3..dfa9402 100644 --- a/src/main/java/org/spdx/tools/SpdxToolsHelper.java +++ b/src/main/java/org/spdx/tools/SpdxToolsHelper.java @@ -58,6 +58,9 @@ */ public class SpdxToolsHelper { + /** + * Supported serialization file types + */ public enum SerFileType { JSON, RDFXML, XML, XLS, XLSX, YAML, TAG, RDFTTL, JSONLD } @@ -84,6 +87,9 @@ public enum SerFileType { } /** + * Determine the appropriate in memory based model store which supports + * serialization for the fileType + * * @param fileType * file type for the store * @return the appropriate in memory based model store which supports @@ -129,6 +135,8 @@ public static ISerializableModelStore fileTypeToStore(SerFileType fileType) } /** + * Determine the file type based on the file name and extension + * * @param file * @return the file type based on the file name and file extension * @throws InvalidFileNameException @@ -188,6 +196,8 @@ public static SerFileType fileToFileType(File file) } /** + * Determine the file type based on the file extension or string + * * @param str * @return the file type based on the file extension or string */ @@ -197,6 +207,9 @@ public static SerFileType strToFileType(String str) { } /** + * Deserializes an SPDX document from a file, + * compatible with SPDX version 2 + * * @param file * file containing an SPDX document with the standard file * extension for the serialization formats @@ -215,6 +228,9 @@ public static SpdxDocument deserializeDocumentCompatV2(File file) return readDocumentFromFileCompatV2(store, file); } /** + * Deserializes an SPDX document from a file, + * compatible with SPDX version 2 + * * @param file * file containing an SPDX document in one of the supported * SerFileTypes @@ -235,6 +251,8 @@ public static SpdxDocument deserializeDocumentCompatV2(File file, } /** + * Deserializes an SPDX document from a file + * * @param file * file containing an SPDX document with the standard file * extension for the serialization formats @@ -253,6 +271,8 @@ public static org.spdx.library.model.v3_0_1.core.SpdxDocument deserializeDocumen return readDocumentFromFileV3(store, file); } /** + * Deserializes an SPDX document from a file + * * @param file * file containing an SPDX document in one of the supported * SerFileTypes @@ -308,6 +328,8 @@ public static void deserializeFile(ISerializableModelStore store, File file) thr } /** + * Is the store supporting SPDX version 3 + * * @param store model store * @return true of the model store support SPDX spec version 3 */ @@ -316,6 +338,8 @@ public static boolean supportsV3(ISerializableModelStore store) { } /** + * Is the store supporting SPDX version 2 + * * @param store model store * @return true of the model store support SPDX spec version 2 */ @@ -358,7 +382,9 @@ public static CoreModelObject readDocumentFromFile(ISerializableModelStore store } /** - * Reads an SPDX Document from a file + * Reads an SPDX Document from a file, + * compatible with SPDX version 2 + * * @param store Store where the document is to be stored * @param file File to read the store from * @return SPDX Document from the store @@ -375,6 +401,8 @@ public static SpdxDocument readDocumentFromFileCompatV2(ISerializableModelStore } /** + * Gets an SPDX document from the model store + * * @param store model store * @return returns a document if a single document is found in the model store * @throws InvalidSPDXAnalysisException @@ -395,6 +423,9 @@ public static org.spdx.library.model.v3_0_1.core.SpdxDocument getDocFromStore(IS } /** + * Gets an SPDX document from the model store, + * compatible with SPDX version 2 + * * @param store model store * @return returns a document if a single document is found in the model store * @throws InvalidSPDXAnalysisException From 9de3ae23b079a369da46a4c25ad542cf90a8c409 Mon Sep 17 00:00:00 2001 From: Gary O'Neall Date: Thu, 6 Nov 2025 17:26:26 -0800 Subject: [PATCH 32/54] Fix full SPDX example Various fixes including removing duplicate SPDX IDs Added ExpandedLicensingExample Signed-off-by: Gary O'Neall --- .../examples/ExpandedLicenseExampleV3.java | 180 ++++++++++++++++++ .../org/spdx/examples/FullSpdxV3Example.java | 108 ++++++----- .../spdx/examples/SpdxExtensionExample.java | 9 + 3 files changed, 251 insertions(+), 46 deletions(-) create mode 100644 examples/org/spdx/examples/ExpandedLicenseExampleV3.java diff --git a/examples/org/spdx/examples/ExpandedLicenseExampleV3.java b/examples/org/spdx/examples/ExpandedLicenseExampleV3.java new file mode 100644 index 0000000..573bdde --- /dev/null +++ b/examples/org/spdx/examples/ExpandedLicenseExampleV3.java @@ -0,0 +1,180 @@ +package org.spdx.examples; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.networknt.schema.Error; +import com.networknt.schema.Schema; +import com.networknt.schema.SchemaRegistry; +import com.networknt.schema.SpecificationVersion; +import org.spdx.core.DefaultModelStore; +import org.spdx.core.IModelCopyManager; +import org.spdx.library.LicenseInfoFactory; +import org.spdx.library.ModelCopyManager; +import org.spdx.library.SpdxModelFactory; +import org.spdx.library.model.v3_0_1.SpdxModelClassFactoryV3; +import org.spdx.library.model.v3_0_1.core.CreationInfo; +import org.spdx.library.model.v3_0_1.core.Element; +import org.spdx.library.model.v3_0_1.core.ProfileIdentifierType; +import org.spdx.library.model.v3_0_1.core.SpdxDocument; +import org.spdx.library.model.v3_0_1.expandedlicensing.ExtendableLicense; +import org.spdx.library.model.v3_0_1.simplelicensing.AnyLicenseInfo; +import org.spdx.storage.IModelStore; +import org.spdx.storage.simple.InMemSpdxStore; +import org.spdx.tools.Verify; +import org.spdx.v3jsonldstore.JsonLDStore; + +import java.io.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import static org.spdx.tools.Verify.JSON_SCHEMA_RESOURCE_V3; + +/** + * Simple example serializing a single expanded license + */ +public class ExpandedLicenseExampleV3 { + + static final ObjectMapper JSON_MAPPER = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT); + + /** + * @param args args[0] is the file path for the output serialized file + */ + public static void main(String[] args) throws Exception { + if (args.length != 1) { + usage(); + System.exit(1); + } + File outFile = new File(args[0]); + if (outFile.exists()) { + System.out.printf("%s already exists.\n", args[0]); + System.exit(1); + } + if (!outFile.createNewFile()) { + System.out.printf("Unable to create file %s\n", args[0]); + System.exit(1); + } + if (!outFile.canWrite()) { + System.out.printf("Can not write to file %s\n", args[0]); + System.exit(1); + } + SpdxModelFactory.init(); + IModelCopyManager copyManager = new ModelCopyManager(); + try (JsonLDStore modelStore = new JsonLDStore(new InMemSpdxStore())) { + modelStore.setUseExternalListedElements(true); // setting this to false will include all the listed license details in the document + String defaultDocUri = "https://spdx.github.io/spdx-spec/v3.0.1/examples/complex-license-eaa46bdcfa20"; + String prefix = defaultDocUri + "#"; + DefaultModelStore.initialize(modelStore, defaultDocUri, copyManager); + CreationInfo creationInfo = SpdxModelClassFactoryV3.createCreationInfo( + modelStore, prefix + "garyagent", "Gary O'Neall", + copyManager); + SpdxDocument doc = creationInfo.createSpdxDocument(prefix + "document") + .setDataLicense(LicenseInfoFactory.getListedLicenseById("CC0")) + .addNamespaceMap(creationInfo.createNamespaceMap(modelStore.getNextId(IModelStore.IdType.Anonymous)) + .setNamespace(prefix) + .setPrefix("example") + .build()) + .addProfileConformance(ProfileIdentifierType.CORE) + .addProfileConformance(ProfileIdentifierType.SOFTWARE) + .addProfileConformance(ProfileIdentifierType.EXPANDED_LICENSING) + .build(); + doc.setIdPrefix(prefix); + AnyLicenseInfo complexLicense = doc.createConjunctiveLicenseSet(prefix + "complexlicense") + // CustomLicense + .addMember(doc.createCustomLicense(prefix + "LicenseRef-customlicense1") + .setLicenseText("This is the license text for my custom license") + .setName("Gary's Custom License") + .addSeeAlso("https://example.com") + .build()) + // OrLaterOperator + .addMember(doc.createOrLaterOperator(prefix + "complexorlater") + // ListedLicense + .setSubjectLicense(doc.createListedLicense("http://spdx.org/licenses/EPL-1.0") + .setName("Eclipse Public License 1.0") + .setLicenseText("Eclipse Public License - v 1.0\n\nTHE ACCOMPANYING PROGRAM IS PROVIDED" + + " UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE (\"AGREEMENT\"). ANY USE, REPRODUCTION " + + "OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENTS ACCEPTANCE OF THIS AGREEMENT.\n\n1. " + + "DEFINITIONS\n\n\"Contribution\" means:\n a) in the case of the initial Contributor...") + .setIsFsfLibre(true) + .setComment("EPL replaced the CPL on 28 June 2005.") + .addSeeAlso("https://opensource.org/licenses/EPL-1.0") + .build()) + .build()) + // DisjunctiveLicenseSet + .addMember(doc.createDisjunctiveLicenseSet(prefix + "complexdisjunctive") + // WithAdditionOperator + .addMember(doc.createWithAdditionOperator(prefix + "complexwith") + .setSubjectExtendableLicense((ExtendableLicense) LicenseInfoFactory.parseSPDXLicenseString("GPL-2.0-or-later")) + // ListedLicenseException + .setSubjectAddition(doc.createListedLicenseException("http://spdx.org/licenses/Autoconf-exception-2.0") + .setName("Autoconf exception 2.0") + .setComment("Typically used with GPL-2.0-only or GPL-2.0-or-later") + .setAdditionText("As a special exception, the Free Software Foundation gives unlimited " + + "permission to copy, distribute and modify the ...") + .addSeeAlso("http://ftp.gnu.org/gnu/autoconf/autoconf-2.59.tar.gz") + .build()) + .build()) + .addMember(doc.createWithAdditionOperator(prefix + "complexwithcustomaddition") + .setSubjectExtendableLicense((ExtendableLicense) LicenseInfoFactory.parseSPDXLicenseString("Apache-2.0")) + // CustomLicenseAddition + .setSubjectAddition(doc.createCustomLicenseAddition(prefix + "complexcustomaddition") + .setName("My License Addition") + .setAdditionText("Custom addition text - just for me") + .addSeeAlso("https://example.com") + .build()) + .build()) + // ExtendableLicense - Abstract + // IndividualLicensingInfo - used by listed license + // License - Abstract + .addMember(LicenseInfoFactory.parseSPDXLicenseString("MIT")) + .build()) + .build(); + doc.getRootElements().add(complexLicense); + doc.getElements().add(complexLicense); + List warnings = new ArrayList<>(); + Collection docElements = doc.getElements(); + SpdxModelFactory.getSpdxObjects(modelStore, copyManager, null, null, prefix).forEach( + modelObject -> { + if (modelObject instanceof Element) { + Element element = (Element)modelObject; + if (!docElements.contains(element) && !element.equals(doc)) { + warnings.add("Element not in the document elements: " + element.getObjectUri()); + docElements.add(element); + } + } + } + ); + warnings.addAll(complexLicense.verify()); + try (OutputStream outStream = new FileOutputStream(outFile)) { + modelStore.serialize(outStream, doc); + } + SchemaRegistry schemaRegistry = + SchemaRegistry.withDefaultDialect(SpecificationVersion.DRAFT_2020_12); + Schema schema; + try (InputStream is = Verify.class.getResourceAsStream("/" + JSON_SCHEMA_RESOURCE_V3)) { + schema = schemaRegistry.getSchema(is); + } + JsonNode root; + try (InputStream is = new FileInputStream(outFile)) { + root = JSON_MAPPER.readTree(is); + } + List messages = schema.validate(root); + for (Error msg:messages) { + warnings.add(msg.toString()); + } + if (!warnings.isEmpty()) { + System.out.println("Generated document contains the following warnings:"); + for (String warning:warnings) { + System.out.print("\t"); + System.out.println(warning); + } + } + } + } + + private static void usage() { + System.out.println("Generates an SPDX JSON-LD file containing all of the supported classes."); + System.out.println("Usage: FullSpdxV3Example outputfile"); + } +} diff --git a/examples/org/spdx/examples/FullSpdxV3Example.java b/examples/org/spdx/examples/FullSpdxV3Example.java index 2a42eb6..25dee99 100644 --- a/examples/org/spdx/examples/FullSpdxV3Example.java +++ b/examples/org/spdx/examples/FullSpdxV3Example.java @@ -1,13 +1,12 @@ package org.spdx.examples; - import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; -import com.networknt.schema.JsonSchema; -import com.networknt.schema.JsonSchemaFactory; -import com.networknt.schema.SpecVersion; -import com.networknt.schema.ValidationMessage; +import com.networknt.schema.Error; +import com.networknt.schema.Schema; +import com.networknt.schema.SchemaRegistry; +import com.networknt.schema.SpecificationVersion; import org.spdx.core.DefaultModelStore; import org.spdx.core.IModelCopyManager; import org.spdx.core.InvalidSPDXAnalysisException; @@ -26,7 +25,6 @@ import org.spdx.library.model.v3_0_1.dataset.DatasetPackage; import org.spdx.library.model.v3_0_1.dataset.DatasetType; import org.spdx.library.model.v3_0_1.expandedlicensing.ExtendableLicense; -import org.spdx.library.model.v3_0_1.extension.Extension; import org.spdx.library.model.v3_0_1.security.*; import org.spdx.library.model.v3_0_1.simplelicensing.AnyLicenseInfo; import org.spdx.library.model.v3_0_1.simplelicensing.SimpleLicensingText; @@ -39,9 +37,7 @@ import java.io.*; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; +import java.util.*; import static org.spdx.tools.Verify.JSON_SCHEMA_RESOURCE_V3; @@ -61,10 +57,9 @@ public class FullSpdxV3Example { static final ObjectMapper JSON_MAPPER = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT); static class ExampleBuilder { - private String prefix = null; - private SpdxDocument doc = null; + private final String prefix; + private final SpdxDocument doc; private Sbom sBom = null; - private Bom aiBom = null; private SpdxPackage pkg = null; public ExampleBuilder(String prefix, SpdxDocument doc) { @@ -88,17 +83,19 @@ private String getNextAnonId() throws InvalidSPDXAnalysisException { } private void addExtensionClasses() throws InvalidSPDXAnalysisException { - // SpdxExtensionExample extension = new SpdxExtensionExample(doc.getModelStore(), prefix + "extension", doc.getCopyManager(), true, prefix); - // This currently causes a schema validation issue and depends on a fix in the v3JsonLD store - // extension.setExtensionProperty("Extension property value"); - // TODO: Add this back in after validation issues are addressed - Extension extension = doc.createCdxPropertiesExtension(prefix + "extension") + //TODO: The following is causing a schema validation error - uncomment when resolved +// ModelRegistry.getModelRegistry().registerExtensionType("Extension.example", +// SpdxExtensionExample.class); +// SpdxExtensionExample extension = new SpdxExtensionExample(doc.getModelStore(), +// prefix + "extension", doc.getCopyManager(), true, prefix); +// extension.setExtensionProperty("Extension property value"); +// doc.getExtensions().add(extension); + doc.getExtensions().add(doc.createCdxPropertiesExtension(getNextAnonId()) .addCdxProperty(doc.createCdxPropertyEntry(getNextAnonId()) - .setCdxPropName("cdxProperty") - .setCdxPropValue("value") + .setCdxPropName("CDXProperty") + .setCdxPropValue("Property Value") .build()) - .build(); - doc.getExtensions().add(extension); + .build()); } private void addBuildClasses() throws InvalidSPDXAnalysisException { @@ -173,7 +170,7 @@ private void addExpandedLicensingClasses() throws InvalidSPDXAnalysisException // ConjunctiveLicenseSet AnyLicenseInfo complexLicense = doc.createConjunctiveLicenseSet(prefix + "complexlicense") // CustomLicense - .addMember(doc.createCustomLicense(prefix + "LicenseRef-customlicense1") + .addMember(doc.createCustomLicense(prefix + "LicenseRef-customlicense3") .setLicenseText("This is the license text for my custom license") .setName("Gary's Custom License") .addSeeAlso("https://example.com") @@ -181,7 +178,7 @@ private void addExpandedLicensingClasses() throws InvalidSPDXAnalysisException // OrLaterOperator .addMember(doc.createOrLaterOperator(prefix + "complexorlater") // ListedLicense - .setSubjectLicense(doc.createListedLicense("https://spdx.org/licenses/EPL-1.0") + .setSubjectLicense(doc.createListedLicense("http://spdx.org/licenses/EPL-1.0") .setName("Eclipse Public License 1.0") .setLicenseText("Eclipse Public License - v 1.0\n\nTHE ACCOMPANYING PROGRAM IS PROVIDED" + " UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE (\"AGREEMENT\"). ANY USE, REPRODUCTION " + @@ -378,20 +375,20 @@ private void addSecurityClasses() throws InvalidSPDXAnalysisException { // ExploitCatalogVulnAssessmentRelationship //TODO: The schema has "locator" for the field while the generated Java code has "securityLocator" //Need to regenerate the library then uncomment the example below -// ExploitCatalogVulnAssessmentRelationship excat = doc.createExploitCatalogVulnAssessmentRelationship(prefix + "exploitcat") -// .setRelationshipType(RelationshipType.HAS_ASSESSMENT_FOR) -// .setFrom(vuln) -// .addTo(log4j) -// .setCatalogType(ExploitCatalogType.KEV) -// .setSecurityLocator("https://www.cisa.gov/known-exploited-vulnerabilities-catalog") -// .setExploited(true) -// .setAssessedElement(log4j) -// .setSuppliedBy(supplierAgent) -// .setPublishedTime(LocalDateTime.of(2023, 9, 18, 0, 0) -// .format(SPDX_DATE_FORMATTER)) -// .build(); -// doc.getElements().add(excat); -// securityBundle.getElements().add(excat); + ExploitCatalogVulnAssessmentRelationship excat = doc.createExploitCatalogVulnAssessmentRelationship(prefix + "exploitcat") + .setRelationshipType(RelationshipType.HAS_ASSESSMENT_FOR) + .setFrom(vuln) + .addTo(log4j) + .setCatalogType(ExploitCatalogType.KEV) + .setSecurityLocator("https://www.cisa.gov/known-exploited-vulnerabilities-catalog") + .setExploited(true) + .setAssessedElement(log4j) + .setSuppliedBy(supplierAgent) + .setPublishedTime(LocalDateTime.of(2023, 9, 18, 0, 0) + .format(SPDX_DATE_FORMATTER)) + .build(); + doc.getElements().add(excat); + securityBundle.getElements().add(excat); // SsvcVulnAssessmentRelationship SsvcVulnAssessmentRelationship ssvs = doc.createSsvcVulnAssessmentRelationship(prefix + "ssvs") @@ -527,7 +524,6 @@ private void addCoreClasses() throws InvalidSPDXAnalysisException { .addLocator("org.spdx:tools-java") .build()) .build()); - } private void addSoftwareClasses() throws InvalidSPDXAnalysisException { @@ -668,7 +664,7 @@ private void addSoftwareClasses() throws InvalidSPDXAnalysisException { } private void addAIandDataClasses() throws InvalidSPDXAnalysisException { - aiBom = doc.createBom(prefix + "aibom") + Bom aiBom = doc.createBom(prefix + "aibom") .setName("AI SBOM") .addProfileConformance(ProfileIdentifierType.CORE) .addProfileConformance(ProfileIdentifierType.SOFTWARE) @@ -758,6 +754,8 @@ private void addAIandDataClasses() throws InvalidSPDXAnalysisException { .addTo(aiPackage) .setCompleteness(RelationshipCompleteness.INCOMPLETE) .build(); + doc.getElements().add(usesData); + aiBom.getElements().add(usesData); } } @@ -809,22 +807,40 @@ public static void main(String[] args) throws Exception { doc.setIdPrefix(prefix); ExampleBuilder builder = new ExampleBuilder(prefix, doc); builder.build(); + List warnings = new ArrayList<>(); + // Add all the elements to the doc to make sure everything gets serialized + Collection docElements = doc.getElements(); + SpdxModelFactory.getSpdxObjects(modelStore, copyManager, null, null, prefix).forEach( + modelObject -> { + if (modelObject instanceof Element) { + Element element = (Element)modelObject; + if (!docElements.contains(element) && !element.equals(doc)) { + warnings.add("Element not in the document elements: " + element.getObjectUri()); + docElements.add(element); + } + } + } + ); - List warnings = doc.verify(); + // Verify using the SPDX Java Library + warnings.addAll(doc.verify()); try (OutputStream outStream = new FileOutputStream(outFile)) { - modelStore.serialize(outStream); + modelStore.serialize(outStream, doc); } - JsonSchemaFactory jsonSchemaFactory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V202012); - JsonSchema schema; + + // Validate using the schema + SchemaRegistry schemaRegistry = + SchemaRegistry.withDefaultDialect(SpecificationVersion.DRAFT_2020_12); + Schema schema; try (InputStream is = Verify.class.getResourceAsStream("/" + JSON_SCHEMA_RESOURCE_V3)) { - schema = jsonSchemaFactory.getSchema(is); + schema = schemaRegistry.getSchema(is); } JsonNode root; try (InputStream is = new FileInputStream(outFile)) { root = JSON_MAPPER.readTree(is); } - Set messages = schema.validate(root); - for (ValidationMessage msg:messages) { + List messages = schema.validate(root); + for (Error msg:messages) { warnings.add(msg.toString()); } if (!warnings.isEmpty()) { diff --git a/examples/org/spdx/examples/SpdxExtensionExample.java b/examples/org/spdx/examples/SpdxExtensionExample.java index 135a80e..f75d8c9 100644 --- a/examples/org/spdx/examples/SpdxExtensionExample.java +++ b/examples/org/spdx/examples/SpdxExtensionExample.java @@ -17,6 +17,10 @@ public SpdxExtensionExample(IModelStore modelStore, String objectUri, @Nullable super(modelStore, objectUri, copyManager, create, idPrefix); } + public SpdxExtensionExample(IModelStore modelStore, String objectUri, @Nullable IModelCopyManager copyManager, boolean create, String specVersion, String idPrefix) throws InvalidSPDXAnalysisException { + super(modelStore, objectUri, copyManager, create, idPrefix); + } + public SpdxExtensionExample setExtensionProperty(String value) throws InvalidSPDXAnalysisException { setPropertyValue(EXTENSION_PROPERTY_DESCRIPTOR, value); return this; @@ -25,4 +29,9 @@ public SpdxExtensionExample setExtensionProperty(String value) throws InvalidSPD public Optional getExtensionProperty() throws InvalidSPDXAnalysisException { return getStringPropertyValue(EXTENSION_PROPERTY_DESCRIPTOR); } + + @Override + public String getType() { + return "Extension.example"; + } } From d5a923a0875a9092b45e8f63e083f1d42911e4c4 Mon Sep 17 00:00:00 2001 From: Gary O'Neall Date: Fri, 7 Nov 2025 11:59:34 -0800 Subject: [PATCH 33/54] Add missing file copyright notice Co-authored-by: Arthit Suriyawongkul --- examples/org/spdx/examples/ExpandedLicenseExampleV3.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/examples/org/spdx/examples/ExpandedLicenseExampleV3.java b/examples/org/spdx/examples/ExpandedLicenseExampleV3.java index 573bdde..030b1b2 100644 --- a/examples/org/spdx/examples/ExpandedLicenseExampleV3.java +++ b/examples/org/spdx/examples/ExpandedLicenseExampleV3.java @@ -1,3 +1,12 @@ +/** + * SPDX-FileContributor: Gary O'Neall + * SPDX-FileCopyrightText: Copyright (c) 2025 Source Auditor Inc. + * SPDX-FileType: SOURCE + * SPDX-License-Identifier: Apache-2.0 + * + * Example of serializing a single expanded license + */ + package org.spdx.examples; import com.fasterxml.jackson.databind.JsonNode; From f6cf5a9573a07ab1bcaf738391e1e077fc52ad12 Mon Sep 17 00:00:00 2001 From: Gary O'Neall Date: Fri, 7 Nov 2025 11:59:49 -0800 Subject: [PATCH 34/54] Add missing file copyright notice Co-authored-by: Arthit Suriyawongkul --- examples/org/spdx/examples/FullSpdxV3Example.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/examples/org/spdx/examples/FullSpdxV3Example.java b/examples/org/spdx/examples/FullSpdxV3Example.java index 25dee99..fd1b269 100644 --- a/examples/org/spdx/examples/FullSpdxV3Example.java +++ b/examples/org/spdx/examples/FullSpdxV3Example.java @@ -1,3 +1,12 @@ +/** + * SPDX-FileContributor: Gary O'Neall + * SPDX-FileCopyrightText: Copyright (c) 2025 Source Auditor Inc. + * SPDX-FileType: SOURCE + * SPDX-License-Identifier: Apache-2.0 + * + * Full example of an SPDX document using all classes + */ + package org.spdx.examples; import com.fasterxml.jackson.databind.JsonNode; From c17e8333f8e7369a51fb01416689b17fd65569fb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Nov 2025 17:40:53 +0000 Subject: [PATCH 35/54] Bump org.apache.maven.plugins:maven-release-plugin from 3.1.1 to 3.2.0 Bumps [org.apache.maven.plugins:maven-release-plugin](https://github.com/apache/maven-release) from 3.1.1 to 3.2.0. - [Release notes](https://github.com/apache/maven-release/releases) - [Commits](https://github.com/apache/maven-release/compare/maven-release-3.1.1...maven-release-3.2.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-release-plugin dependency-version: 3.2.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index be74737..279090a 100644 --- a/pom.xml +++ b/pom.xml @@ -354,7 +354,7 @@ org.apache.maven.plugins maven-release-plugin - 3.1.1 + 3.2.0 v@{project.version} release From 0ebc386130c9a818cc7f8e75445720e5f9b8abd7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Nov 2025 17:40:59 +0000 Subject: [PATCH 36/54] Bump commons-io:commons-io from 2.20.0 to 2.21.0 Bumps [commons-io:commons-io](https://github.com/apache/commons-io) from 2.20.0 to 2.21.0. - [Changelog](https://github.com/apache/commons-io/blob/master/RELEASE-NOTES.txt) - [Commits](https://github.com/apache/commons-io/compare/rel/commons-io-2.20.0...rel/commons-io-2.21.0) --- updated-dependencies: - dependency-name: commons-io:commons-io dependency-version: 2.21.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 279090a..27ae85d 100644 --- a/pom.xml +++ b/pom.xml @@ -97,7 +97,7 @@ commons-io commons-io - 2.20.0 + 2.21.0 org.apache.commons From 7a2ea0fb8542a7e86d39a864253b29f1fbecc84e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Nov 2025 16:01:13 +0000 Subject: [PATCH 37/54] Bump org.owasp:dependency-check-maven from 12.1.8 to 12.1.9 Bumps [org.owasp:dependency-check-maven](https://github.com/dependency-check/DependencyCheck) from 12.1.8 to 12.1.9. - [Release notes](https://github.com/dependency-check/DependencyCheck/releases) - [Changelog](https://github.com/dependency-check/DependencyCheck/blob/main/CHANGELOG.md) - [Commits](https://github.com/dependency-check/DependencyCheck/compare/v12.1.8...v12.1.9) --- updated-dependencies: - dependency-name: org.owasp:dependency-check-maven dependency-version: 12.1.9 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 27ae85d..7335130 100644 --- a/pom.xml +++ b/pom.xml @@ -48,7 +48,7 @@ https://sonarcloud.io spdx tools-java - 12.1.8 + 12.1.9 11 -Xdoclint:none From 3bee0a45fea5223894f9d2d8cd52fe5c9c4a30cb Mon Sep 17 00:00:00 2001 From: Gary O'Neall Date: Thu, 6 Nov 2025 17:31:05 -0800 Subject: [PATCH 38/54] Add faster schema Reference: https://github.com/JPEWdev/shacl2code/pull/56 Signed-off-by: Gary O'Neall --- resources/spdx-schema-v3.0.1.json | 4416 +++++++++++++++++------------ 1 file changed, 2606 insertions(+), 1810 deletions(-) diff --git a/resources/spdx-schema-v3.0.1.json b/resources/spdx-schema-v3.0.1.json index 5a030b4..13f4636 100644 --- a/resources/spdx-schema-v3.0.1.json +++ b/resources/spdx-schema-v3.0.1.json @@ -10,42 +10,56 @@ }, "required": ["@context"], - "oneOf": [ - { - "type": "object", - "properties": { - "@graph": { - "description": "Top level container for JSON-LD objects", - "type": "array", - "items": { - "type": "object", - "$ref": "#/$defs/AnyClass", - "unevaluatedProperties": false - } + "if": { + "type": "object", + "required": ["@graph"] + }, + "then": { + "type": "object", + "properties": { + "@graph": { + "description": "Top level container for JSON-LD objects", + "type": "array", + "items": { + "type": "object", + "$ref": "#/$defs/AnyClass", + "unevaluatedProperties": false } - }, - "required": ["@graph"] + } }, - { "$ref": "#/$defs/AnyClass" } - ], + "required": ["@graph"] + }, + "else": { + "$ref": "#/$defs/AnyClass" + }, "unevaluatedProperties": false, "$defs": { "ai_EnergyConsumption": { - "allOf": [ - { - "type": "object", - "properties": { - "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, - "type": { - "oneOf": [ - { "const": "ai_EnergyConsumption" } - ] - } + "if": { + "type": "object", + "properties": { + "type": { + "const": "ai_EnergyConsumption" } }, - { "$ref": "#/$defs/ai_EnergyConsumption_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, + "type": { "type": "string" } + } + }, + { "$ref": "#/$defs/ai_EnergyConsumption_props" } + ] + }, + "else": { + "const": "Not a ai_EnergyConsumption" + } }, "ai_EnergyConsumption_derived": { "anyOf": [ @@ -66,7 +80,7 @@ "type": "object", "properties": { "ai_finetuningEnergyConsumption": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -76,7 +90,7 @@ ] }, "ai_inferenceEnergyConsumption": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -86,7 +100,7 @@ ] }, "ai_trainingEnergyConsumption": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -100,29 +114,39 @@ ] }, "prop_ai_EnergyConsumption_ai_finetuningEnergyConsumption": { - "$ref": "#/$defs/ai_EnergyConsumptionDescription_derived" + "$ref": "#/$defs/ai_EnergyConsumptionDescription_derived" }, "prop_ai_EnergyConsumption_ai_inferenceEnergyConsumption": { - "$ref": "#/$defs/ai_EnergyConsumptionDescription_derived" + "$ref": "#/$defs/ai_EnergyConsumptionDescription_derived" }, "prop_ai_EnergyConsumption_ai_trainingEnergyConsumption": { - "$ref": "#/$defs/ai_EnergyConsumptionDescription_derived" + "$ref": "#/$defs/ai_EnergyConsumptionDescription_derived" }, "ai_EnergyConsumptionDescription": { - "allOf": [ - { - "type": "object", - "properties": { - "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, - "type": { - "oneOf": [ - { "const": "ai_EnergyConsumptionDescription" } - ] - } + "if": { + "type": "object", + "properties": { + "type": { + "const": "ai_EnergyConsumptionDescription" } }, - { "$ref": "#/$defs/ai_EnergyConsumptionDescription_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, + "type": { "type": "string" } + } + }, + { "$ref": "#/$defs/ai_EnergyConsumptionDescription_props" } + ] + }, + "else": { + "const": "Not a ai_EnergyConsumptionDescription" + } }, "ai_EnergyConsumptionDescription_derived": { "anyOf": [ @@ -157,38 +181,48 @@ ] }, "prop_ai_EnergyConsumptionDescription_ai_energyQuantity": { - "oneOf": [ - { - "type": "number" - }, - { - "type": "string", - "pattern": "^-?[0-9]+(\\.[0-9]*)?$" - } - ] + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "pattern": "^-?[0-9]+(\\.[0-9]*)?$" + } + ] }, "prop_ai_EnergyConsumptionDescription_ai_energyUnit": { - "enum": [ - "kilowattHour", - "megajoule", - "other" - ] + "enum": [ + "kilowattHour", + "megajoule", + "other" + ] }, "ai_EnergyUnitType": { - "allOf": [ - { - "type": "object", - "properties": { - "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, - "type": { - "oneOf": [ - { "const": "ai_EnergyUnitType" } - ] - } + "if": { + "type": "object", + "properties": { + "type": { + "const": "ai_EnergyUnitType" } }, - { "$ref": "#/$defs/ai_EnergyUnitType_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, + "type": { "type": "string" } + } + }, + { "$ref": "#/$defs/ai_EnergyUnitType_props" } + ] + }, + "else": { + "const": "Not a ai_EnergyUnitType" + } }, "ai_EnergyUnitType_derived": { "anyOf": [ @@ -216,20 +250,30 @@ ] }, "ai_SafetyRiskAssessmentType": { - "allOf": [ - { - "type": "object", - "properties": { - "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, - "type": { - "oneOf": [ - { "const": "ai_SafetyRiskAssessmentType" } - ] - } + "if": { + "type": "object", + "properties": { + "type": { + "const": "ai_SafetyRiskAssessmentType" } }, - { "$ref": "#/$defs/ai_SafetyRiskAssessmentType_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, + "type": { "type": "string" } + } + }, + { "$ref": "#/$defs/ai_SafetyRiskAssessmentType_props" } + ] + }, + "else": { + "const": "Not a ai_SafetyRiskAssessmentType" + } }, "ai_SafetyRiskAssessmentType_derived": { "anyOf": [ @@ -258,20 +302,30 @@ ] }, "AnnotationType": { - "allOf": [ - { - "type": "object", - "properties": { - "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, - "type": { - "oneOf": [ - { "const": "AnnotationType" } - ] - } + "if": { + "type": "object", + "properties": { + "type": { + "const": "AnnotationType" } }, - { "$ref": "#/$defs/AnnotationType_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, + "type": { "type": "string" } + } + }, + { "$ref": "#/$defs/AnnotationType_props" } + ] + }, + "else": { + "const": "Not a AnnotationType" + } }, "AnnotationType_derived": { "anyOf": [ @@ -298,20 +352,30 @@ ] }, "CreationInfo": { - "allOf": [ - { - "type": "object", - "properties": { - "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, - "type": { - "oneOf": [ - { "const": "CreationInfo" } - ] - } + "if": { + "type": "object", + "properties": { + "type": { + "const": "CreationInfo" } }, - { "$ref": "#/$defs/CreationInfo_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, + "type": { "type": "string" } + } + }, + { "$ref": "#/$defs/CreationInfo_props" } + ] + }, + "else": { + "const": "Not a CreationInfo" + } }, "CreationInfo_derived": { "anyOf": [ @@ -338,7 +402,7 @@ "$ref": "#/$defs/prop_CreationInfo_created" }, "createdBy": { - "oneOf": [ + "anyOf": [ { "type": "array", "minItems": 1, @@ -349,7 +413,7 @@ ] }, "createdUsing": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -371,44 +435,54 @@ ] }, "prop_CreationInfo_comment": { - "type": "string" + "type": "string" }, "prop_CreationInfo_created": { - "type": "string", - "allOf": [ - { - "pattern": "^[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](Z|[+-][0-9]{2}:[0-9]{2})$" - }, - { - "pattern": "^\\d\\d\\d\\d-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\dZ$" - } - ] + "type": "string", + "allOf": [ + { + "pattern": "^[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](Z|[+-][0-9]{2}:[0-9]{2})$" + }, + { + "pattern": "^\\d\\d\\d\\d-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\dZ$" + } + ] }, "prop_CreationInfo_createdBy": { - "$ref": "#/$defs/Agent_derived" + "$ref": "#/$defs/Agent_derived" }, "prop_CreationInfo_createdUsing": { - "$ref": "#/$defs/Tool_derived" + "$ref": "#/$defs/Tool_derived" }, "prop_CreationInfo_specVersion": { - "pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$", - "type": "string" + "pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$", + "type": "string" }, "DictionaryEntry": { - "allOf": [ - { - "type": "object", - "properties": { - "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, - "type": { - "oneOf": [ - { "const": "DictionaryEntry" } - ] - } + "if": { + "type": "object", + "properties": { + "type": { + "const": "DictionaryEntry" } }, - { "$ref": "#/$defs/DictionaryEntry_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, + "type": { "type": "string" } + } + }, + { "$ref": "#/$defs/DictionaryEntry_props" } + ] + }, + "else": { + "const": "Not a DictionaryEntry" + } }, "DictionaryEntry_derived": { "anyOf": [ @@ -442,10 +516,10 @@ ] }, "prop_DictionaryEntry_key": { - "type": "string" + "type": "string" }, "prop_DictionaryEntry_value": { - "type": "string" + "type": "string" }, "Element_derived": { "anyOf": [ @@ -520,7 +594,7 @@ "$ref": "#/$defs/prop_Element_description" }, "extension": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -530,7 +604,7 @@ ] }, "externalIdentifier": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -540,7 +614,7 @@ ] }, "externalRef": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -556,7 +630,7 @@ "$ref": "#/$defs/prop_Element_summary" }, "verifiedUsing": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -573,31 +647,31 @@ ] }, "prop_Element_comment": { - "type": "string" + "type": "string" }, "prop_Element_creationInfo": { - "$ref": "#/$defs/CreationInfo_derived" + "$ref": "#/$defs/CreationInfo_derived" }, "prop_Element_description": { - "type": "string" + "type": "string" }, "prop_Element_extension": { - "$ref": "#/$defs/extension_Extension_derived" + "$ref": "#/$defs/extension_Extension_derived" }, "prop_Element_externalIdentifier": { - "$ref": "#/$defs/ExternalIdentifier_derived" + "$ref": "#/$defs/ExternalIdentifier_derived" }, "prop_Element_externalRef": { - "$ref": "#/$defs/ExternalRef_derived" + "$ref": "#/$defs/ExternalRef_derived" }, "prop_Element_name": { - "type": "string" + "type": "string" }, "prop_Element_summary": { - "type": "string" + "type": "string" }, "prop_Element_verifiedUsing": { - "$ref": "#/$defs/IntegrityMethod_derived" + "$ref": "#/$defs/IntegrityMethod_derived" }, "ElementCollection_derived": { "anyOf": [ @@ -621,7 +695,7 @@ "type": "object", "properties": { "element": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -631,7 +705,7 @@ ] }, "profileConformance": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -641,7 +715,7 @@ ] }, "rootElement": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -655,40 +729,50 @@ ] }, "prop_ElementCollection_element": { - "$ref": "#/$defs/Element_derived" + "$ref": "#/$defs/Element_derived" }, "prop_ElementCollection_profileConformance": { - "enum": [ - "ai", - "build", - "core", - "dataset", - "expandedLicensing", - "extension", - "lite", - "security", - "simpleLicensing", - "software" - ] + "enum": [ + "ai", + "build", + "core", + "dataset", + "expandedLicensing", + "extension", + "lite", + "security", + "simpleLicensing", + "software" + ] }, "prop_ElementCollection_rootElement": { - "$ref": "#/$defs/Element_derived" + "$ref": "#/$defs/Element_derived" }, "ExternalIdentifier": { - "allOf": [ - { - "type": "object", - "properties": { - "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, - "type": { - "oneOf": [ - { "const": "ExternalIdentifier" } - ] - } + "if": { + "type": "object", + "properties": { + "type": { + "const": "ExternalIdentifier" } }, - { "$ref": "#/$defs/ExternalIdentifier_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, + "type": { "type": "string" } + } + }, + { "$ref": "#/$defs/ExternalIdentifier_props" } + ] + }, + "else": { + "const": "Not a ExternalIdentifier" + } }, "ExternalIdentifier_derived": { "anyOf": [ @@ -718,7 +802,7 @@ "$ref": "#/$defs/prop_ExternalIdentifier_identifier" }, "identifierLocator": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -739,47 +823,57 @@ ] }, "prop_ExternalIdentifier_comment": { - "type": "string" + "type": "string" }, "prop_ExternalIdentifier_externalIdentifierType": { - "enum": [ - "cpe22", - "cpe23", - "cve", - "email", - "gitoid", - "other", - "packageUrl", - "securityOther", - "swhid", - "swid", - "urlScheme" - ] + "enum": [ + "cpe22", + "cpe23", + "cve", + "email", + "gitoid", + "other", + "packageUrl", + "securityOther", + "swhid", + "swid", + "urlScheme" + ] }, "prop_ExternalIdentifier_identifier": { - "type": "string" + "type": "string" }, "prop_ExternalIdentifier_identifierLocator": { - "$ref": "#/$defs/anyURI" + "$ref": "#/$defs/anyURI" }, "prop_ExternalIdentifier_issuingAuthority": { - "type": "string" + "type": "string" }, "ExternalIdentifierType": { - "allOf": [ - { - "type": "object", - "properties": { - "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, - "type": { - "oneOf": [ - { "const": "ExternalIdentifierType" } - ] - } + "if": { + "type": "object", + "properties": { + "type": { + "const": "ExternalIdentifierType" } }, - { "$ref": "#/$defs/ExternalIdentifierType_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, + "type": { "type": "string" } + } + }, + { "$ref": "#/$defs/ExternalIdentifierType_props" } + ] + }, + "else": { + "const": "Not a ExternalIdentifierType" + } }, "ExternalIdentifierType_derived": { "anyOf": [ @@ -815,20 +909,30 @@ ] }, "ExternalMap": { - "allOf": [ - { - "type": "object", - "properties": { - "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, - "type": { - "oneOf": [ - { "const": "ExternalMap" } - ] - } + "if": { + "type": "object", + "properties": { + "type": { + "const": "ExternalMap" } }, - { "$ref": "#/$defs/ExternalMap_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, + "type": { "type": "string" } + } + }, + { "$ref": "#/$defs/ExternalMap_props" } + ] + }, + "else": { + "const": "Not a ExternalMap" + } }, "ExternalMap_derived": { "anyOf": [ @@ -858,7 +962,7 @@ "$ref": "#/$defs/prop_ExternalMap_locationHint" }, "verifiedUsing": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -875,32 +979,42 @@ ] }, "prop_ExternalMap_definingArtifact": { - "$ref": "#/$defs/Artifact_derived" + "$ref": "#/$defs/Artifact_derived" }, "prop_ExternalMap_externalSpdxId": { - "$ref": "#/$defs/anyURI" + "$ref": "#/$defs/anyURI" }, "prop_ExternalMap_locationHint": { - "$ref": "#/$defs/anyURI" + "$ref": "#/$defs/anyURI" }, "prop_ExternalMap_verifiedUsing": { - "$ref": "#/$defs/IntegrityMethod_derived" + "$ref": "#/$defs/IntegrityMethod_derived" }, "ExternalRef": { - "allOf": [ - { - "type": "object", - "properties": { - "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, - "type": { - "oneOf": [ - { "const": "ExternalRef" } - ] - } + "if": { + "type": "object", + "properties": { + "type": { + "const": "ExternalRef" } }, - { "$ref": "#/$defs/ExternalRef_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, + "type": { "type": "string" } + } + }, + { "$ref": "#/$defs/ExternalRef_props" } + ] + }, + "else": { + "const": "Not a ExternalRef" + } }, "ExternalRef_derived": { "anyOf": [ @@ -930,7 +1044,7 @@ "$ref": "#/$defs/prop_ExternalRef_externalRefType" }, "locator": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -944,80 +1058,90 @@ ] }, "prop_ExternalRef_comment": { - "type": "string" + "type": "string" }, "prop_ExternalRef_contentType": { - "pattern": "^[^\\/]+\\/[^\\/]+$", - "type": "string" + "pattern": "^[^\\/]+\\/[^\\/]+$", + "type": "string" }, "prop_ExternalRef_externalRefType": { - "enum": [ - "altDownloadLocation", - "altWebPage", - "binaryArtifact", - "bower", - "buildMeta", - "buildSystem", - "certificationReport", - "chat", - "componentAnalysisReport", - "cwe", - "documentation", - "dynamicAnalysisReport", - "eolNotice", - "exportControlAssessment", - "funding", - "issueTracker", - "license", - "mailingList", - "mavenCentral", - "metrics", - "npm", - "nuget", - "other", - "privacyAssessment", - "productMetadata", - "purchaseOrder", - "qualityAssessmentReport", - "releaseHistory", - "releaseNotes", - "riskAssessment", - "runtimeAnalysisReport", - "secureSoftwareAttestation", - "securityAdversaryModel", - "securityAdvisory", - "securityFix", - "securityOther", - "securityPenTestReport", - "securityPolicy", - "securityThreatModel", - "socialMedia", - "sourceArtifact", - "staticAnalysisReport", - "support", - "vcs", - "vulnerabilityDisclosureReport", - "vulnerabilityExploitabilityAssessment" - ] + "enum": [ + "altDownloadLocation", + "altWebPage", + "binaryArtifact", + "bower", + "buildMeta", + "buildSystem", + "certificationReport", + "chat", + "componentAnalysisReport", + "cwe", + "documentation", + "dynamicAnalysisReport", + "eolNotice", + "exportControlAssessment", + "funding", + "issueTracker", + "license", + "mailingList", + "mavenCentral", + "metrics", + "npm", + "nuget", + "other", + "privacyAssessment", + "productMetadata", + "purchaseOrder", + "qualityAssessmentReport", + "releaseHistory", + "releaseNotes", + "riskAssessment", + "runtimeAnalysisReport", + "secureSoftwareAttestation", + "securityAdversaryModel", + "securityAdvisory", + "securityFix", + "securityOther", + "securityPenTestReport", + "securityPolicy", + "securityThreatModel", + "socialMedia", + "sourceArtifact", + "staticAnalysisReport", + "support", + "vcs", + "vulnerabilityDisclosureReport", + "vulnerabilityExploitabilityAssessment" + ] }, "prop_ExternalRef_locator": { - "type": "string" + "type": "string" }, "ExternalRefType": { - "allOf": [ - { - "type": "object", - "properties": { - "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, - "type": { - "oneOf": [ - { "const": "ExternalRefType" } - ] - } + "if": { + "type": "object", + "properties": { + "type": { + "const": "ExternalRefType" } }, - { "$ref": "#/$defs/ExternalRefType_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, + "type": { "type": "string" } + } + }, + { "$ref": "#/$defs/ExternalRefType_props" } + ] + }, + "else": { + "const": "Not a ExternalRefType" + } }, "ExternalRefType_derived": { "anyOf": [ @@ -1088,20 +1212,30 @@ ] }, "HashAlgorithm": { - "allOf": [ - { - "type": "object", - "properties": { - "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, - "type": { - "oneOf": [ - { "const": "HashAlgorithm" } - ] - } + "if": { + "type": "object", + "properties": { + "type": { + "const": "HashAlgorithm" } }, - { "$ref": "#/$defs/HashAlgorithm_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, + "type": { "type": "string" } + } + }, + { "$ref": "#/$defs/HashAlgorithm_props" } + ] + }, + "else": { + "const": "Not a HashAlgorithm" + } }, "HashAlgorithm_derived": { "anyOf": [ @@ -1148,21 +1282,31 @@ ] }, "IndividualElement": { - "allOf": [ - { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "IndividualElement" } - ] - } - }, - "required": ["spdxId"] + "if": { + "type": "object", + "properties": { + "type": { + "const": "IndividualElement" + } }, - { "$ref": "#/$defs/IndividualElement_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/IndividualElement_props" } + ] + }, + "else": { + "const": "Not a IndividualElement" + } }, "IndividualElement_derived": { "anyOf": [ @@ -1216,23 +1360,33 @@ ] }, "prop_IntegrityMethod_comment": { - "type": "string" + "type": "string" }, "LifecycleScopeType": { - "allOf": [ - { - "type": "object", - "properties": { - "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, - "type": { - "oneOf": [ - { "const": "LifecycleScopeType" } - ] - } + "if": { + "type": "object", + "properties": { + "type": { + "const": "LifecycleScopeType" } }, - { "$ref": "#/$defs/LifecycleScopeType_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, + "type": { "type": "string" } + } + }, + { "$ref": "#/$defs/LifecycleScopeType_props" } + ] + }, + "else": { + "const": "Not a LifecycleScopeType" + } }, "LifecycleScopeType_derived": { "anyOf": [ @@ -1263,20 +1417,30 @@ ] }, "NamespaceMap": { - "allOf": [ - { - "type": "object", - "properties": { - "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, - "type": { - "oneOf": [ - { "const": "NamespaceMap" } - ] - } + "if": { + "type": "object", + "properties": { + "type": { + "const": "NamespaceMap" } }, - { "$ref": "#/$defs/NamespaceMap_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, + "type": { "type": "string" } + } + }, + { "$ref": "#/$defs/NamespaceMap_props" } + ] + }, + "else": { + "const": "Not a NamespaceMap" + } }, "NamespaceMap_derived": { "anyOf": [ @@ -1311,26 +1475,36 @@ ] }, "prop_NamespaceMap_namespace": { - "$ref": "#/$defs/anyURI" + "$ref": "#/$defs/anyURI" }, "prop_NamespaceMap_prefix": { - "type": "string" + "type": "string" }, "PackageVerificationCode": { - "allOf": [ - { - "type": "object", - "properties": { - "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, - "type": { - "oneOf": [ - { "const": "PackageVerificationCode" } - ] - } + "if": { + "type": "object", + "properties": { + "type": { + "const": "PackageVerificationCode" } }, - { "$ref": "#/$defs/PackageVerificationCode_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, + "type": { "type": "string" } + } + }, + { "$ref": "#/$defs/PackageVerificationCode_props" } + ] + }, + "else": { + "const": "Not a PackageVerificationCode" + } }, "PackageVerificationCode_derived": { "anyOf": [ @@ -1357,7 +1531,7 @@ "$ref": "#/$defs/prop_PackageVerificationCode_hashValue" }, "packageVerificationCodeExcludedFile": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -1375,52 +1549,62 @@ ] }, "prop_PackageVerificationCode_algorithm": { - "enum": [ - "adler32", - "blake2b256", - "blake2b384", - "blake2b512", - "blake3", - "crystalsDilithium", - "crystalsKyber", - "falcon", - "md2", - "md4", - "md5", - "md6", - "other", - "sha1", - "sha224", - "sha256", - "sha384", - "sha3_224", - "sha3_256", - "sha3_384", - "sha3_512", - "sha512" - ] + "enum": [ + "adler32", + "blake2b256", + "blake2b384", + "blake2b512", + "blake3", + "crystalsDilithium", + "crystalsKyber", + "falcon", + "md2", + "md4", + "md5", + "md6", + "other", + "sha1", + "sha224", + "sha256", + "sha384", + "sha3_224", + "sha3_256", + "sha3_384", + "sha3_512", + "sha512" + ] }, "prop_PackageVerificationCode_hashValue": { - "type": "string" + "type": "string" }, "prop_PackageVerificationCode_packageVerificationCodeExcludedFile": { - "type": "string" + "type": "string" }, "PositiveIntegerRange": { - "allOf": [ - { - "type": "object", - "properties": { - "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, - "type": { - "oneOf": [ - { "const": "PositiveIntegerRange" } - ] - } + "if": { + "type": "object", + "properties": { + "type": { + "const": "PositiveIntegerRange" } }, - { "$ref": "#/$defs/PositiveIntegerRange_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, + "type": { "type": "string" } + } + }, + { "$ref": "#/$defs/PositiveIntegerRange_props" } + ] + }, + "else": { + "const": "Not a PositiveIntegerRange" + } }, "PositiveIntegerRange_derived": { "anyOf": [ @@ -1455,28 +1639,38 @@ ] }, "prop_PositiveIntegerRange_beginIntegerRange": { - "type": "integer", - "minimum": 1 + "type": "integer", + "minimum": 1 }, "prop_PositiveIntegerRange_endIntegerRange": { - "type": "integer", - "minimum": 1 + "type": "integer", + "minimum": 1 }, "PresenceType": { - "allOf": [ - { - "type": "object", - "properties": { - "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, - "type": { - "oneOf": [ - { "const": "PresenceType" } - ] - } + "if": { + "type": "object", + "properties": { + "type": { + "const": "PresenceType" } }, - { "$ref": "#/$defs/PresenceType_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, + "type": { "type": "string" } + } + }, + { "$ref": "#/$defs/PresenceType_props" } + ] + }, + "else": { + "const": "Not a PresenceType" + } }, "PresenceType_derived": { "anyOf": [ @@ -1504,20 +1698,30 @@ ] }, "ProfileIdentifierType": { - "allOf": [ - { - "type": "object", - "properties": { - "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, - "type": { - "oneOf": [ - { "const": "ProfileIdentifierType" } - ] - } + "if": { + "type": "object", + "properties": { + "type": { + "const": "ProfileIdentifierType" } }, - { "$ref": "#/$defs/ProfileIdentifierType_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, + "type": { "type": "string" } + } + }, + { "$ref": "#/$defs/ProfileIdentifierType_props" } + ] + }, + "else": { + "const": "Not a ProfileIdentifierType" + } }, "ProfileIdentifierType_derived": { "anyOf": [ @@ -1552,21 +1756,31 @@ ] }, "Relationship": { - "allOf": [ - { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "Relationship" } - ] - } - }, - "required": ["spdxId"] + "if": { + "type": "object", + "properties": { + "type": { + "const": "Relationship" + } }, - { "$ref": "#/$defs/Relationship_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/Relationship_props" } + ] + }, + "else": { + "const": "Not a Relationship" + } }, "Relationship_derived": { "anyOf": [ @@ -1613,7 +1827,7 @@ "$ref": "#/$defs/prop_Relationship_startTime" }, "to": { - "oneOf": [ + "anyOf": [ { "type": "array", "minItems": 1, @@ -1633,118 +1847,128 @@ ] }, "prop_Relationship_completeness": { - "enum": [ - "complete", - "incomplete", - "noAssertion" - ] + "enum": [ + "complete", + "incomplete", + "noAssertion" + ] }, "prop_Relationship_endTime": { - "type": "string", - "allOf": [ - { - "pattern": "^[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](Z|[+-][0-9]{2}:[0-9]{2})$" - }, - { - "pattern": "^\\d\\d\\d\\d-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\dZ$" - } - ] + "type": "string", + "allOf": [ + { + "pattern": "^[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](Z|[+-][0-9]{2}:[0-9]{2})$" + }, + { + "pattern": "^\\d\\d\\d\\d-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\dZ$" + } + ] }, "prop_Relationship_from_": { - "$ref": "#/$defs/Element_derived" + "$ref": "#/$defs/Element_derived" }, "prop_Relationship_relationshipType": { - "enum": [ - "affects", - "amendedBy", - "ancestorOf", - "availableFrom", - "configures", - "contains", - "coordinatedBy", - "copiedTo", - "delegatedTo", - "dependsOn", - "descendantOf", - "describes", - "doesNotAffect", - "expandsTo", - "exploitCreatedBy", - "fixedBy", - "fixedIn", - "foundBy", - "generates", - "hasAddedFile", - "hasAssessmentFor", - "hasAssociatedVulnerability", - "hasConcludedLicense", - "hasDataFile", - "hasDeclaredLicense", - "hasDeletedFile", - "hasDependencyManifest", - "hasDistributionArtifact", - "hasDocumentation", - "hasDynamicLink", - "hasEvidence", - "hasExample", - "hasHost", - "hasInput", - "hasMetadata", - "hasOptionalComponent", - "hasOptionalDependency", - "hasOutput", - "hasPrerequisite", - "hasProvidedDependency", - "hasRequirement", - "hasSpecification", - "hasStaticLink", - "hasTest", - "hasTestCase", - "hasVariant", - "invokedBy", - "modifiedBy", - "other", - "packagedBy", - "patchedBy", - "publishedBy", - "reportedBy", - "republishedBy", - "serializedInArtifact", - "testedOn", - "trainedOn", - "underInvestigationFor", - "usesTool" - ] + "enum": [ + "affects", + "amendedBy", + "ancestorOf", + "availableFrom", + "configures", + "contains", + "coordinatedBy", + "copiedTo", + "delegatedTo", + "dependsOn", + "descendantOf", + "describes", + "doesNotAffect", + "expandsTo", + "exploitCreatedBy", + "fixedBy", + "fixedIn", + "foundBy", + "generates", + "hasAddedFile", + "hasAssessmentFor", + "hasAssociatedVulnerability", + "hasConcludedLicense", + "hasDataFile", + "hasDeclaredLicense", + "hasDeletedFile", + "hasDependencyManifest", + "hasDistributionArtifact", + "hasDocumentation", + "hasDynamicLink", + "hasEvidence", + "hasExample", + "hasHost", + "hasInput", + "hasMetadata", + "hasOptionalComponent", + "hasOptionalDependency", + "hasOutput", + "hasPrerequisite", + "hasProvidedDependency", + "hasRequirement", + "hasSpecification", + "hasStaticLink", + "hasTest", + "hasTestCase", + "hasVariant", + "invokedBy", + "modifiedBy", + "other", + "packagedBy", + "patchedBy", + "publishedBy", + "reportedBy", + "republishedBy", + "serializedInArtifact", + "testedOn", + "trainedOn", + "underInvestigationFor", + "usesTool" + ] }, "prop_Relationship_startTime": { - "type": "string", - "allOf": [ - { - "pattern": "^[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](Z|[+-][0-9]{2}:[0-9]{2})$" - }, - { - "pattern": "^\\d\\d\\d\\d-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\dZ$" - } - ] + "type": "string", + "allOf": [ + { + "pattern": "^[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](Z|[+-][0-9]{2}:[0-9]{2})$" + }, + { + "pattern": "^\\d\\d\\d\\d-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\dZ$" + } + ] }, "prop_Relationship_to": { - "$ref": "#/$defs/Element_derived" + "$ref": "#/$defs/Element_derived" }, "RelationshipCompleteness": { - "allOf": [ - { - "type": "object", - "properties": { - "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, - "type": { - "oneOf": [ - { "const": "RelationshipCompleteness" } - ] - } + "if": { + "type": "object", + "properties": { + "type": { + "const": "RelationshipCompleteness" } }, - { "$ref": "#/$defs/RelationshipCompleteness_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, + "type": { "type": "string" } + } + }, + { "$ref": "#/$defs/RelationshipCompleteness_props" } + ] + }, + "else": { + "const": "Not a RelationshipCompleteness" + } }, "RelationshipCompleteness_derived": { "anyOf": [ @@ -1772,20 +1996,30 @@ ] }, "RelationshipType": { - "allOf": [ - { - "type": "object", - "properties": { - "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, - "type": { - "oneOf": [ - { "const": "RelationshipType" } - ] - } + "if": { + "type": "object", + "properties": { + "type": { + "const": "RelationshipType" } }, - { "$ref": "#/$defs/RelationshipType_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, + "type": { "type": "string" } + } + }, + { "$ref": "#/$defs/RelationshipType_props" } + ] + }, + "else": { + "const": "Not a RelationshipType" + } }, "RelationshipType_derived": { "anyOf": [ @@ -1869,21 +2103,31 @@ ] }, "SpdxDocument": { - "allOf": [ - { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "SpdxDocument" } - ] - } - }, - "required": ["spdxId"] + "if": { + "type": "object", + "properties": { + "type": { + "const": "SpdxDocument" + } }, - { "$ref": "#/$defs/SpdxDocument_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/SpdxDocument_props" } + ] + }, + "else": { + "const": "Not a SpdxDocument" + } }, "SpdxDocument_derived": { "anyOf": [ @@ -1907,7 +2151,7 @@ "$ref": "#/$defs/prop_SpdxDocument_dataLicense" }, "import": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -1917,7 +2161,7 @@ ] }, "namespaceMap": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -1931,29 +2175,39 @@ ] }, "prop_SpdxDocument_dataLicense": { - "$ref": "#/$defs/simplelicensing_AnyLicenseInfo_derived" + "$ref": "#/$defs/simplelicensing_AnyLicenseInfo_derived" }, "prop_SpdxDocument_import_": { - "$ref": "#/$defs/ExternalMap_derived" + "$ref": "#/$defs/ExternalMap_derived" }, "prop_SpdxDocument_namespaceMap": { - "$ref": "#/$defs/NamespaceMap_derived" + "$ref": "#/$defs/NamespaceMap_derived" }, "SupportType": { - "allOf": [ - { - "type": "object", - "properties": { - "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, - "type": { - "oneOf": [ - { "const": "SupportType" } - ] - } + "if": { + "type": "object", + "properties": { + "type": { + "const": "SupportType" } }, - { "$ref": "#/$defs/SupportType_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, + "type": { "type": "string" } + } + }, + { "$ref": "#/$defs/SupportType_props" } + ] + }, + "else": { + "const": "Not a SupportType" + } }, "SupportType_derived": { "anyOf": [ @@ -1985,21 +2239,31 @@ ] }, "Tool": { - "allOf": [ - { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "Tool" } - ] - } - }, - "required": ["spdxId"] + "if": { + "type": "object", + "properties": { + "type": { + "const": "Tool" + } }, - { "$ref": "#/$defs/Tool_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/Tool_props" } + ] + }, + "else": { + "const": "Not a Tool" + } }, "Tool_derived": { "anyOf": [ @@ -2024,20 +2288,30 @@ ] }, "dataset_ConfidentialityLevelType": { - "allOf": [ - { - "type": "object", - "properties": { - "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, - "type": { - "oneOf": [ - { "const": "dataset_ConfidentialityLevelType" } - ] - } + "if": { + "type": "object", + "properties": { + "type": { + "const": "dataset_ConfidentialityLevelType" } }, - { "$ref": "#/$defs/dataset_ConfidentialityLevelType_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, + "type": { "type": "string" } + } + }, + { "$ref": "#/$defs/dataset_ConfidentialityLevelType_props" } + ] + }, + "else": { + "const": "Not a dataset_ConfidentialityLevelType" + } }, "dataset_ConfidentialityLevelType_derived": { "anyOf": [ @@ -2066,20 +2340,30 @@ ] }, "dataset_DatasetAvailabilityType": { - "allOf": [ - { - "type": "object", - "properties": { - "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, - "type": { - "oneOf": [ - { "const": "dataset_DatasetAvailabilityType" } - ] - } + "if": { + "type": "object", + "properties": { + "type": { + "const": "dataset_DatasetAvailabilityType" } }, - { "$ref": "#/$defs/dataset_DatasetAvailabilityType_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, + "type": { "type": "string" } + } + }, + { "$ref": "#/$defs/dataset_DatasetAvailabilityType_props" } + ] + }, + "else": { + "const": "Not a dataset_DatasetAvailabilityType" + } }, "dataset_DatasetAvailabilityType_derived": { "anyOf": [ @@ -2109,20 +2393,30 @@ ] }, "dataset_DatasetType": { - "allOf": [ - { - "type": "object", - "properties": { - "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, - "type": { - "oneOf": [ - { "const": "dataset_DatasetType" } - ] - } + "if": { + "type": "object", + "properties": { + "type": { + "const": "dataset_DatasetType" } }, - { "$ref": "#/$defs/dataset_DatasetType_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, + "type": { "type": "string" } + } + }, + { "$ref": "#/$defs/dataset_DatasetType_props" } + ] + }, + "else": { + "const": "Not a dataset_DatasetType" + } }, "dataset_DatasetType_derived": { "anyOf": [ @@ -2192,7 +2486,7 @@ "$ref": "#/$defs/prop_expandedlicensing_LicenseAddition_expandedlicensing_obsoletedBy" }, "expandedlicensing_seeAlso": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -2212,39 +2506,49 @@ ] }, "prop_expandedlicensing_LicenseAddition_expandedlicensing_additionText": { - "type": "string" + "type": "string" }, "prop_expandedlicensing_LicenseAddition_expandedlicensing_isDeprecatedAdditionId": { - "type": "boolean" + "type": "boolean" }, "prop_expandedlicensing_LicenseAddition_expandedlicensing_licenseXml": { - "type": "string" + "type": "string" }, "prop_expandedlicensing_LicenseAddition_expandedlicensing_obsoletedBy": { - "type": "string" + "type": "string" }, "prop_expandedlicensing_LicenseAddition_expandedlicensing_seeAlso": { - "$ref": "#/$defs/anyURI" + "$ref": "#/$defs/anyURI" }, "prop_expandedlicensing_LicenseAddition_expandedlicensing_standardAdditionTemplate": { - "type": "string" + "type": "string" }, "expandedlicensing_ListedLicenseException": { - "allOf": [ - { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "expandedlicensing_ListedLicenseException" } - ] - } - }, - "required": ["spdxId"] + "if": { + "type": "object", + "properties": { + "type": { + "const": "expandedlicensing_ListedLicenseException" + } }, - { "$ref": "#/$defs/expandedlicensing_ListedLicenseException_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/expandedlicensing_ListedLicenseException_props" } + ] + }, + "else": { + "const": "Not a expandedlicensing_ListedLicenseException" + } }, "expandedlicensing_ListedLicenseException_derived": { "anyOf": [ @@ -2275,26 +2579,36 @@ ] }, "prop_expandedlicensing_ListedLicenseException_expandedlicensing_deprecatedVersion": { - "type": "string" + "type": "string" }, "prop_expandedlicensing_ListedLicenseException_expandedlicensing_listVersionAdded": { - "type": "string" + "type": "string" }, "extension_CdxPropertyEntry": { - "allOf": [ - { - "type": "object", - "properties": { - "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, - "type": { - "oneOf": [ - { "const": "extension_CdxPropertyEntry" } - ] - } + "if": { + "type": "object", + "properties": { + "type": { + "const": "extension_CdxPropertyEntry" } }, - { "$ref": "#/$defs/extension_CdxPropertyEntry_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, + "type": { "type": "string" } + } + }, + { "$ref": "#/$defs/extension_CdxPropertyEntry_props" } + ] + }, + "else": { + "const": "Not a extension_CdxPropertyEntry" + } }, "extension_CdxPropertyEntry_derived": { "anyOf": [ @@ -2328,28 +2642,40 @@ ] }, "prop_extension_CdxPropertyEntry_extension_cdxPropName": { - "type": "string" + "type": "string" }, "prop_extension_CdxPropertyEntry_extension_cdxPropValue": { - "type": "string" + "type": "string" }, "extension_Extension": { - "allOf": [ - { - "type": "object", - "unevaluatedProperties": true, - "properties": { - "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, - "type": { - "allOf": [ - { "$ref": "#/$defs/IRI" }, - { "not": { "const": "extension_Extension" } } - ] - } + "if": { + "type": "object", + "properties": { + "type": { + "allOf": [ + { "$ref": "#/$defs/IRI" }, + { "not": { "const": "extension_Extension" } } + ] } }, - { "$ref": "#/$defs/extension_Extension_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "unevaluatedProperties": true, + "properties": { + "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, + "type": { "type": "string" } + } + }, + { "$ref": "#/$defs/extension_Extension_props" } + ] + }, + "else": { + "const": "Not a extension_Extension" + } }, "extension_Extension_derived": { "anyOf": [ @@ -2374,20 +2700,30 @@ ] }, "security_CvssSeverityType": { - "allOf": [ - { - "type": "object", - "properties": { - "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, - "type": { - "oneOf": [ - { "const": "security_CvssSeverityType" } - ] - } + "if": { + "type": "object", + "properties": { + "type": { + "const": "security_CvssSeverityType" } }, - { "$ref": "#/$defs/security_CvssSeverityType_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, + "type": { "type": "string" } + } + }, + { "$ref": "#/$defs/security_CvssSeverityType_props" } + ] + }, + "else": { + "const": "Not a security_CvssSeverityType" + } }, "security_CvssSeverityType_derived": { "anyOf": [ @@ -2417,20 +2753,30 @@ ] }, "security_ExploitCatalogType": { - "allOf": [ - { - "type": "object", - "properties": { - "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, - "type": { - "oneOf": [ - { "const": "security_ExploitCatalogType" } - ] - } + "if": { + "type": "object", + "properties": { + "type": { + "const": "security_ExploitCatalogType" } }, - { "$ref": "#/$defs/security_ExploitCatalogType_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, + "type": { "type": "string" } + } + }, + { "$ref": "#/$defs/security_ExploitCatalogType_props" } + ] + }, + "else": { + "const": "Not a security_ExploitCatalogType" + } }, "security_ExploitCatalogType_derived": { "anyOf": [ @@ -2457,20 +2803,30 @@ ] }, "security_SsvcDecisionType": { - "allOf": [ - { - "type": "object", - "properties": { - "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, - "type": { - "oneOf": [ - { "const": "security_SsvcDecisionType" } - ] - } + "if": { + "type": "object", + "properties": { + "type": { + "const": "security_SsvcDecisionType" } }, - { "$ref": "#/$defs/security_SsvcDecisionType_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, + "type": { "type": "string" } + } + }, + { "$ref": "#/$defs/security_SsvcDecisionType_props" } + ] + }, + "else": { + "const": "Not a security_SsvcDecisionType" + } }, "security_SsvcDecisionType_derived": { "anyOf": [ @@ -2499,20 +2855,30 @@ ] }, "security_VexJustificationType": { - "allOf": [ - { - "type": "object", - "properties": { - "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, - "type": { - "oneOf": [ - { "const": "security_VexJustificationType" } - ] - } + "if": { + "type": "object", + "properties": { + "type": { + "const": "security_VexJustificationType" } }, - { "$ref": "#/$defs/security_VexJustificationType_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, + "type": { "type": "string" } + } + }, + { "$ref": "#/$defs/security_VexJustificationType_props" } + ] + }, + "else": { + "const": "Not a security_VexJustificationType" + } }, "security_VexJustificationType_derived": { "anyOf": [ @@ -2588,43 +2954,43 @@ ] }, "prop_security_VulnAssessmentRelationship_suppliedBy": { - "$ref": "#/$defs/Agent_derived" + "$ref": "#/$defs/Agent_derived" }, "prop_security_VulnAssessmentRelationship_security_assessedElement": { - "$ref": "#/$defs/software_SoftwareArtifact_derived" + "$ref": "#/$defs/software_SoftwareArtifact_derived" }, "prop_security_VulnAssessmentRelationship_security_modifiedTime": { - "type": "string", - "allOf": [ - { - "pattern": "^[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](Z|[+-][0-9]{2}:[0-9]{2})$" - }, - { - "pattern": "^\\d\\d\\d\\d-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\dZ$" - } - ] + "type": "string", + "allOf": [ + { + "pattern": "^[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](Z|[+-][0-9]{2}:[0-9]{2})$" + }, + { + "pattern": "^\\d\\d\\d\\d-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\dZ$" + } + ] }, "prop_security_VulnAssessmentRelationship_security_publishedTime": { - "type": "string", - "allOf": [ - { - "pattern": "^[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](Z|[+-][0-9]{2}:[0-9]{2})$" - }, - { - "pattern": "^\\d\\d\\d\\d-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\dZ$" - } - ] + "type": "string", + "allOf": [ + { + "pattern": "^[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](Z|[+-][0-9]{2}:[0-9]{2})$" + }, + { + "pattern": "^\\d\\d\\d\\d-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\dZ$" + } + ] }, "prop_security_VulnAssessmentRelationship_security_withdrawnTime": { - "type": "string", - "allOf": [ - { - "pattern": "^[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](Z|[+-][0-9]{2}:[0-9]{2})$" - }, - { - "pattern": "^\\d\\d\\d\\d-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\dZ$" - } - ] + "type": "string", + "allOf": [ + { + "pattern": "^[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](Z|[+-][0-9]{2}:[0-9]{2})$" + }, + { + "pattern": "^\\d\\d\\d\\d-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\dZ$" + } + ] }, "simplelicensing_AnyLicenseInfo_derived": { "anyOf": [ @@ -2658,21 +3024,31 @@ ] }, "simplelicensing_LicenseExpression": { - "allOf": [ - { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "simplelicensing_LicenseExpression" } - ] - } - }, - "required": ["spdxId"] + "if": { + "type": "object", + "properties": { + "type": { + "const": "simplelicensing_LicenseExpression" + } }, - { "$ref": "#/$defs/simplelicensing_LicenseExpression_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/simplelicensing_LicenseExpression_props" } + ] + }, + "else": { + "const": "Not a simplelicensing_LicenseExpression" + } }, "simplelicensing_LicenseExpression_derived": { "anyOf": [ @@ -2693,7 +3069,7 @@ "type": "object", "properties": { "simplelicensing_customIdToUri": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -2716,31 +3092,41 @@ ] }, "prop_simplelicensing_LicenseExpression_simplelicensing_customIdToUri": { - "$ref": "#/$defs/DictionaryEntry_derived" + "$ref": "#/$defs/DictionaryEntry_derived" }, "prop_simplelicensing_LicenseExpression_simplelicensing_licenseExpression": { - "type": "string" + "type": "string" }, "prop_simplelicensing_LicenseExpression_simplelicensing_licenseListVersion": { - "pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$", - "type": "string" + "pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$", + "type": "string" }, "simplelicensing_SimpleLicensingText": { - "allOf": [ - { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "simplelicensing_SimpleLicensingText" } - ] - } - }, - "required": ["spdxId"] + "if": { + "type": "object", + "properties": { + "type": { + "const": "simplelicensing_SimpleLicensingText" + } }, - { "$ref": "#/$defs/simplelicensing_SimpleLicensingText_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/simplelicensing_SimpleLicensingText_props" } + ] + }, + "else": { + "const": "Not a simplelicensing_SimpleLicensingText" + } }, "simplelicensing_SimpleLicensingText_derived": { "anyOf": [ @@ -2771,23 +3157,33 @@ ] }, "prop_simplelicensing_SimpleLicensingText_simplelicensing_licenseText": { - "type": "string" + "type": "string" }, "software_ContentIdentifier": { - "allOf": [ - { - "type": "object", - "properties": { - "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, - "type": { - "oneOf": [ - { "const": "software_ContentIdentifier" } - ] - } + "if": { + "type": "object", + "properties": { + "type": { + "const": "software_ContentIdentifier" } }, - { "$ref": "#/$defs/software_ContentIdentifier_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, + "type": { "type": "string" } + } + }, + { "$ref": "#/$defs/software_ContentIdentifier_props" } + ] + }, + "else": { + "const": "Not a software_ContentIdentifier" + } }, "software_ContentIdentifier_derived": { "anyOf": [ @@ -2822,29 +3218,39 @@ ] }, "prop_software_ContentIdentifier_software_contentIdentifierType": { - "enum": [ - "gitoid", - "swhid" - ] + "enum": [ + "gitoid", + "swhid" + ] }, "prop_software_ContentIdentifier_software_contentIdentifierValue": { - "$ref": "#/$defs/anyURI" + "$ref": "#/$defs/anyURI" }, "software_ContentIdentifierType": { - "allOf": [ - { - "type": "object", - "properties": { - "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, - "type": { - "oneOf": [ - { "const": "software_ContentIdentifierType" } - ] - } + "if": { + "type": "object", + "properties": { + "type": { + "const": "software_ContentIdentifierType" } }, - { "$ref": "#/$defs/software_ContentIdentifierType_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, + "type": { "type": "string" } + } + }, + { "$ref": "#/$defs/software_ContentIdentifierType_props" } + ] + }, + "else": { + "const": "Not a software_ContentIdentifierType" + } }, "software_ContentIdentifierType_derived": { "anyOf": [ @@ -2871,20 +3277,30 @@ ] }, "software_FileKindType": { - "allOf": [ - { - "type": "object", - "properties": { - "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, - "type": { - "oneOf": [ - { "const": "software_FileKindType" } - ] - } + "if": { + "type": "object", + "properties": { + "type": { + "const": "software_FileKindType" } }, - { "$ref": "#/$defs/software_FileKindType_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, + "type": { "type": "string" } + } + }, + { "$ref": "#/$defs/software_FileKindType_props" } + ] + }, + "else": { + "const": "Not a software_FileKindType" + } }, "software_FileKindType_derived": { "anyOf": [ @@ -2911,20 +3327,30 @@ ] }, "software_SbomType": { - "allOf": [ - { - "type": "object", - "properties": { - "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, - "type": { - "oneOf": [ - { "const": "software_SbomType" } - ] - } + "if": { + "type": "object", + "properties": { + "type": { + "const": "software_SbomType" } }, - { "$ref": "#/$defs/software_SbomType_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, + "type": { "type": "string" } + } + }, + { "$ref": "#/$defs/software_SbomType_props" } + ] + }, + "else": { + "const": "Not a software_SbomType" + } }, "software_SbomType_derived": { "anyOf": [ @@ -2955,20 +3381,30 @@ ] }, "software_SoftwarePurpose": { - "allOf": [ - { - "type": "object", - "properties": { - "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, - "type": { - "oneOf": [ - { "const": "software_SoftwarePurpose" } - ] - } + "if": { + "type": "object", + "properties": { + "type": { + "const": "software_SoftwarePurpose" } }, - { "$ref": "#/$defs/software_SoftwarePurpose_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, + "type": { "type": "string" } + } + }, + { "$ref": "#/$defs/software_SoftwarePurpose_props" } + ] + }, + "else": { + "const": "Not a software_SoftwarePurpose" + } }, "software_SoftwarePurpose_derived": { "anyOf": [ @@ -3022,21 +3458,31 @@ ] }, "build_Build": { - "allOf": [ - { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "build_Build" } - ] - } - }, - "required": ["spdxId"] + "if": { + "type": "object", + "properties": { + "type": { + "const": "build_Build" + } }, - { "$ref": "#/$defs/build_Build_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/build_Build_props" } + ] + }, + "else": { + "const": "Not a build_Build" + } }, "build_Build_derived": { "anyOf": [ @@ -3069,7 +3515,7 @@ "$ref": "#/$defs/prop_build_Build_build_buildType" }, "build_configSourceDigest": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -3079,7 +3525,7 @@ ] }, "build_configSourceEntrypoint": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -3089,7 +3535,7 @@ ] }, "build_configSourceUri": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -3099,7 +3545,7 @@ ] }, "build_environment": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -3109,7 +3555,7 @@ ] }, "build_parameter": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -3126,64 +3572,74 @@ ] }, "prop_build_Build_build_buildEndTime": { - "type": "string", - "allOf": [ - { - "pattern": "^[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](Z|[+-][0-9]{2}:[0-9]{2})$" - }, - { - "pattern": "^\\d\\d\\d\\d-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\dZ$" - } - ] + "type": "string", + "allOf": [ + { + "pattern": "^[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](Z|[+-][0-9]{2}:[0-9]{2})$" + }, + { + "pattern": "^\\d\\d\\d\\d-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\dZ$" + } + ] }, "prop_build_Build_build_buildId": { - "type": "string" + "type": "string" }, "prop_build_Build_build_buildStartTime": { - "type": "string", - "allOf": [ - { - "pattern": "^[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](Z|[+-][0-9]{2}:[0-9]{2})$" - }, - { - "pattern": "^\\d\\d\\d\\d-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\dZ$" - } - ] + "type": "string", + "allOf": [ + { + "pattern": "^[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](Z|[+-][0-9]{2}:[0-9]{2})$" + }, + { + "pattern": "^\\d\\d\\d\\d-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\dZ$" + } + ] }, "prop_build_Build_build_buildType": { - "$ref": "#/$defs/anyURI" + "$ref": "#/$defs/anyURI" }, "prop_build_Build_build_configSourceDigest": { - "$ref": "#/$defs/Hash_derived" + "$ref": "#/$defs/Hash_derived" }, "prop_build_Build_build_configSourceEntrypoint": { - "type": "string" + "type": "string" }, "prop_build_Build_build_configSourceUri": { - "$ref": "#/$defs/anyURI" + "$ref": "#/$defs/anyURI" }, "prop_build_Build_build_environment": { - "$ref": "#/$defs/DictionaryEntry_derived" + "$ref": "#/$defs/DictionaryEntry_derived" }, "prop_build_Build_build_parameter": { - "$ref": "#/$defs/DictionaryEntry_derived" + "$ref": "#/$defs/DictionaryEntry_derived" }, "Agent": { - "allOf": [ - { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "Agent" } - ] - } - }, - "required": ["spdxId"] + "if": { + "type": "object", + "properties": { + "type": { + "const": "Agent" + } }, - { "$ref": "#/$defs/Agent_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/Agent_props" } + ] + }, + "else": { + "const": "Not a Agent" + } }, "Agent_derived": { "anyOf": [ @@ -3212,21 +3668,31 @@ ] }, "Annotation": { - "allOf": [ - { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "Annotation" } - ] - } - }, - "required": ["spdxId"] + "if": { + "type": "object", + "properties": { + "type": { + "const": "Annotation" + } }, - { "$ref": "#/$defs/Annotation_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/Annotation_props" } + ] + }, + "else": { + "const": "Not a Annotation" + } }, "Annotation_derived": { "anyOf": [ @@ -3267,20 +3733,20 @@ ] }, "prop_Annotation_annotationType": { - "enum": [ - "other", - "review" - ] + "enum": [ + "other", + "review" + ] }, "prop_Annotation_contentType": { - "pattern": "^[^\\/]+\\/[^\\/]+$", - "type": "string" + "pattern": "^[^\\/]+\\/[^\\/]+$", + "type": "string" }, "prop_Annotation_statement": { - "type": "string" + "type": "string" }, "prop_Annotation_subject": { - "$ref": "#/$defs/Element_derived" + "$ref": "#/$defs/Element_derived" }, "Artifact_derived": { "anyOf": [ @@ -3309,7 +3775,7 @@ "$ref": "#/$defs/prop_Artifact_builtTime" }, "originatedBy": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -3322,7 +3788,7 @@ "$ref": "#/$defs/prop_Artifact_releaseTime" }, "standardName": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -3335,7 +3801,7 @@ "$ref": "#/$defs/prop_Artifact_suppliedBy" }, "supportLevel": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -3352,75 +3818,85 @@ ] }, "prop_Artifact_builtTime": { - "type": "string", - "allOf": [ - { - "pattern": "^[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](Z|[+-][0-9]{2}:[0-9]{2})$" - }, - { - "pattern": "^\\d\\d\\d\\d-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\dZ$" - } - ] + "type": "string", + "allOf": [ + { + "pattern": "^[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](Z|[+-][0-9]{2}:[0-9]{2})$" + }, + { + "pattern": "^\\d\\d\\d\\d-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\dZ$" + } + ] }, "prop_Artifact_originatedBy": { - "$ref": "#/$defs/Agent_derived" + "$ref": "#/$defs/Agent_derived" }, "prop_Artifact_releaseTime": { - "type": "string", - "allOf": [ - { - "pattern": "^[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](Z|[+-][0-9]{2}:[0-9]{2})$" - }, - { - "pattern": "^\\d\\d\\d\\d-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\dZ$" - } - ] + "type": "string", + "allOf": [ + { + "pattern": "^[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](Z|[+-][0-9]{2}:[0-9]{2})$" + }, + { + "pattern": "^\\d\\d\\d\\d-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\dZ$" + } + ] }, "prop_Artifact_standardName": { - "type": "string" + "type": "string" }, "prop_Artifact_suppliedBy": { - "$ref": "#/$defs/Agent_derived" + "$ref": "#/$defs/Agent_derived" }, "prop_Artifact_supportLevel": { - "enum": [ - "deployed", - "development", - "endOfSupport", - "limitedSupport", - "noAssertion", - "noSupport", - "support" - ] + "enum": [ + "deployed", + "development", + "endOfSupport", + "limitedSupport", + "noAssertion", + "noSupport", + "support" + ] }, "prop_Artifact_validUntilTime": { - "type": "string", - "allOf": [ - { - "pattern": "^[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](Z|[+-][0-9]{2}:[0-9]{2})$" - }, - { - "pattern": "^\\d\\d\\d\\d-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\dZ$" - } - ] - }, - "Bundle": { + "type": "string", "allOf": [ { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "Bundle" } - ] - } - }, - "required": ["spdxId"] + "pattern": "^[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](Z|[+-][0-9]{2}:[0-9]{2})$" }, - { "$ref": "#/$defs/Bundle_props" } + { + "pattern": "^\\d\\d\\d\\d-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\dZ$" + } ] }, + "Bundle": { + "if": { + "type": "object", + "properties": { + "type": { + "const": "Bundle" + } + }, + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/Bundle_props" } + ] + }, + "else": { + "const": "Not a Bundle" + } + }, "Bundle_derived": { "anyOf": [ { @@ -3449,23 +3925,33 @@ ] }, "prop_Bundle_context": { - "type": "string" + "type": "string" }, "Hash": { - "allOf": [ - { - "type": "object", - "properties": { - "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, - "type": { - "oneOf": [ - { "const": "Hash" } - ] - } + "if": { + "type": "object", + "properties": { + "type": { + "const": "Hash" } }, - { "$ref": "#/$defs/Hash_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, + "type": { "type": "string" } + } + }, + { "$ref": "#/$defs/Hash_props" } + ] + }, + "else": { + "const": "Not a Hash" + } }, "Hash_derived": { "anyOf": [ @@ -3500,50 +3986,60 @@ ] }, "prop_Hash_algorithm": { - "enum": [ - "adler32", - "blake2b256", - "blake2b384", - "blake2b512", - "blake3", - "crystalsDilithium", - "crystalsKyber", - "falcon", - "md2", - "md4", - "md5", - "md6", - "other", - "sha1", - "sha224", - "sha256", - "sha384", - "sha3_224", - "sha3_256", - "sha3_384", - "sha3_512", - "sha512" - ] + "enum": [ + "adler32", + "blake2b256", + "blake2b384", + "blake2b512", + "blake3", + "crystalsDilithium", + "crystalsKyber", + "falcon", + "md2", + "md4", + "md5", + "md6", + "other", + "sha1", + "sha224", + "sha256", + "sha384", + "sha3_224", + "sha3_256", + "sha3_384", + "sha3_512", + "sha512" + ] }, "prop_Hash_hashValue": { - "type": "string" + "type": "string" }, "LifecycleScopedRelationship": { - "allOf": [ - { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "LifecycleScopedRelationship" } - ] - } - }, - "required": ["spdxId"] + "if": { + "type": "object", + "properties": { + "type": { + "const": "LifecycleScopedRelationship" + } }, - { "$ref": "#/$defs/LifecycleScopedRelationship_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/LifecycleScopedRelationship_props" } + ] + }, + "else": { + "const": "Not a LifecycleScopedRelationship" + } }, "LifecycleScopedRelationship_derived": { "anyOf": [ @@ -3571,31 +4067,41 @@ ] }, "prop_LifecycleScopedRelationship_scope": { - "enum": [ - "build", - "design", - "development", - "other", - "runtime", - "test" - ] + "enum": [ + "build", + "design", + "development", + "other", + "runtime", + "test" + ] }, "Organization": { - "allOf": [ - { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "Organization" } - ] - } - }, - "required": ["spdxId"] + "if": { + "type": "object", + "properties": { + "type": { + "const": "Organization" + } }, - { "$ref": "#/$defs/Organization_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/Organization_props" } + ] + }, + "else": { + "const": "Not a Organization" + } }, "Organization_derived": { "anyOf": [ @@ -3621,21 +4127,31 @@ ] }, "Person": { - "allOf": [ - { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "Person" } - ] - } - }, - "required": ["spdxId"] + "if": { + "type": "object", + "properties": { + "type": { + "const": "Person" + } }, - { "$ref": "#/$defs/Person_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/Person_props" } + ] + }, + "else": { + "const": "Not a Person" + } }, "Person_derived": { "anyOf": [ @@ -3660,21 +4176,31 @@ ] }, "SoftwareAgent": { - "allOf": [ - { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "SoftwareAgent" } - ] - } - }, - "required": ["spdxId"] + "if": { + "type": "object", + "properties": { + "type": { + "const": "SoftwareAgent" + } }, - { "$ref": "#/$defs/SoftwareAgent_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/SoftwareAgent_props" } + ] + }, + "else": { + "const": "Not a SoftwareAgent" + } }, "SoftwareAgent_derived": { "anyOf": [ @@ -3699,21 +4225,31 @@ ] }, "expandedlicensing_ConjunctiveLicenseSet": { - "allOf": [ - { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "expandedlicensing_ConjunctiveLicenseSet" } - ] - } - }, - "required": ["spdxId"] + "if": { + "type": "object", + "properties": { + "type": { + "const": "expandedlicensing_ConjunctiveLicenseSet" + } }, - { "$ref": "#/$defs/expandedlicensing_ConjunctiveLicenseSet_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/expandedlicensing_ConjunctiveLicenseSet_props" } + ] + }, + "else": { + "const": "Not a expandedlicensing_ConjunctiveLicenseSet" + } }, "expandedlicensing_ConjunctiveLicenseSet_derived": { "anyOf": [ @@ -3734,7 +4270,7 @@ "type": "object", "properties": { "expandedlicensing_member": { - "oneOf": [ + "anyOf": [ { "type": "array", "minItems": 2, @@ -3752,24 +4288,34 @@ ] }, "prop_expandedlicensing_ConjunctiveLicenseSet_expandedlicensing_member": { - "$ref": "#/$defs/simplelicensing_AnyLicenseInfo_derived" + "$ref": "#/$defs/simplelicensing_AnyLicenseInfo_derived" }, "expandedlicensing_CustomLicenseAddition": { - "allOf": [ - { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "expandedlicensing_CustomLicenseAddition" } - ] - } - }, - "required": ["spdxId"] + "if": { + "type": "object", + "properties": { + "type": { + "const": "expandedlicensing_CustomLicenseAddition" + } }, - { "$ref": "#/$defs/expandedlicensing_CustomLicenseAddition_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/expandedlicensing_CustomLicenseAddition_props" } + ] + }, + "else": { + "const": "Not a expandedlicensing_CustomLicenseAddition" + } }, "expandedlicensing_CustomLicenseAddition_derived": { "anyOf": [ @@ -3794,21 +4340,31 @@ ] }, "expandedlicensing_DisjunctiveLicenseSet": { - "allOf": [ - { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "expandedlicensing_DisjunctiveLicenseSet" } - ] - } - }, - "required": ["spdxId"] + "if": { + "type": "object", + "properties": { + "type": { + "const": "expandedlicensing_DisjunctiveLicenseSet" + } }, - { "$ref": "#/$defs/expandedlicensing_DisjunctiveLicenseSet_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/expandedlicensing_DisjunctiveLicenseSet_props" } + ] + }, + "else": { + "const": "Not a expandedlicensing_DisjunctiveLicenseSet" + } }, "expandedlicensing_DisjunctiveLicenseSet_derived": { "anyOf": [ @@ -3829,7 +4385,7 @@ "type": "object", "properties": { "expandedlicensing_member": { - "oneOf": [ + "anyOf": [ { "type": "array", "minItems": 2, @@ -3847,7 +4403,7 @@ ] }, "prop_expandedlicensing_DisjunctiveLicenseSet_expandedlicensing_member": { - "$ref": "#/$defs/simplelicensing_AnyLicenseInfo_derived" + "$ref": "#/$defs/simplelicensing_AnyLicenseInfo_derived" }, "expandedlicensing_ExtendableLicense_derived": { "anyOf": [ @@ -3874,21 +4430,31 @@ ] }, "expandedlicensing_IndividualLicensingInfo": { - "allOf": [ - { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "expandedlicensing_IndividualLicensingInfo" } - ] - } - }, - "required": ["spdxId"] + "if": { + "type": "object", + "properties": { + "type": { + "const": "expandedlicensing_IndividualLicensingInfo" + } }, - { "$ref": "#/$defs/expandedlicensing_IndividualLicensingInfo_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/expandedlicensing_IndividualLicensingInfo_props" } + ] + }, + "else": { + "const": "Not a expandedlicensing_IndividualLicensingInfo" + } }, "expandedlicensing_IndividualLicensingInfo_derived": { "anyOf": [ @@ -3949,7 +4515,7 @@ "$ref": "#/$defs/prop_expandedlicensing_License_expandedlicensing_obsoletedBy" }, "expandedlicensing_seeAlso": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -3975,48 +4541,58 @@ ] }, "prop_expandedlicensing_License_expandedlicensing_isDeprecatedLicenseId": { - "type": "boolean" + "type": "boolean" }, "prop_expandedlicensing_License_expandedlicensing_isFsfLibre": { - "type": "boolean" + "type": "boolean" }, "prop_expandedlicensing_License_expandedlicensing_isOsiApproved": { - "type": "boolean" + "type": "boolean" }, "prop_expandedlicensing_License_expandedlicensing_licenseXml": { - "type": "string" + "type": "string" }, "prop_expandedlicensing_License_expandedlicensing_obsoletedBy": { - "type": "string" + "type": "string" }, "prop_expandedlicensing_License_expandedlicensing_seeAlso": { - "$ref": "#/$defs/anyURI" + "$ref": "#/$defs/anyURI" }, "prop_expandedlicensing_License_expandedlicensing_standardLicenseHeader": { - "type": "string" + "type": "string" }, "prop_expandedlicensing_License_expandedlicensing_standardLicenseTemplate": { - "type": "string" + "type": "string" }, "prop_expandedlicensing_License_simplelicensing_licenseText": { - "type": "string" + "type": "string" }, "expandedlicensing_ListedLicense": { - "allOf": [ - { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "expandedlicensing_ListedLicense" } - ] - } - }, - "required": ["spdxId"] + "if": { + "type": "object", + "properties": { + "type": { + "const": "expandedlicensing_ListedLicense" + } }, - { "$ref": "#/$defs/expandedlicensing_ListedLicense_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/expandedlicensing_ListedLicense_props" } + ] + }, + "else": { + "const": "Not a expandedlicensing_ListedLicense" + } }, "expandedlicensing_ListedLicense_derived": { "anyOf": [ @@ -4047,27 +4623,37 @@ ] }, "prop_expandedlicensing_ListedLicense_expandedlicensing_deprecatedVersion": { - "type": "string" + "type": "string" }, "prop_expandedlicensing_ListedLicense_expandedlicensing_listVersionAdded": { - "type": "string" + "type": "string" }, "expandedlicensing_OrLaterOperator": { - "allOf": [ - { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "expandedlicensing_OrLaterOperator" } - ] - } - }, - "required": ["spdxId"] + "if": { + "type": "object", + "properties": { + "type": { + "const": "expandedlicensing_OrLaterOperator" + } }, - { "$ref": "#/$defs/expandedlicensing_OrLaterOperator_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/expandedlicensing_OrLaterOperator_props" } + ] + }, + "else": { + "const": "Not a expandedlicensing_OrLaterOperator" + } }, "expandedlicensing_OrLaterOperator_derived": { "anyOf": [ @@ -4098,24 +4684,34 @@ ] }, "prop_expandedlicensing_OrLaterOperator_expandedlicensing_subjectLicense": { - "$ref": "#/$defs/expandedlicensing_License_derived" + "$ref": "#/$defs/expandedlicensing_License_derived" }, "expandedlicensing_WithAdditionOperator": { - "allOf": [ - { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "expandedlicensing_WithAdditionOperator" } - ] - } - }, - "required": ["spdxId"] + "if": { + "type": "object", + "properties": { + "type": { + "const": "expandedlicensing_WithAdditionOperator" + } }, - { "$ref": "#/$defs/expandedlicensing_WithAdditionOperator_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/expandedlicensing_WithAdditionOperator_props" } + ] + }, + "else": { + "const": "Not a expandedlicensing_WithAdditionOperator" + } }, "expandedlicensing_WithAdditionOperator_derived": { "anyOf": [ @@ -4150,26 +4746,36 @@ ] }, "prop_expandedlicensing_WithAdditionOperator_expandedlicensing_subjectAddition": { - "$ref": "#/$defs/expandedlicensing_LicenseAddition_derived" + "$ref": "#/$defs/expandedlicensing_LicenseAddition_derived" }, "prop_expandedlicensing_WithAdditionOperator_expandedlicensing_subjectExtendableLicense": { - "$ref": "#/$defs/expandedlicensing_ExtendableLicense_derived" + "$ref": "#/$defs/expandedlicensing_ExtendableLicense_derived" }, "extension_CdxPropertiesExtension": { - "allOf": [ - { - "type": "object", - "properties": { - "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, - "type": { - "oneOf": [ - { "const": "extension_CdxPropertiesExtension" } - ] - } + "if": { + "type": "object", + "properties": { + "type": { + "const": "extension_CdxPropertiesExtension" } }, - { "$ref": "#/$defs/extension_CdxPropertiesExtension_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "@id": { "$ref": "#/$defs/BlankNodeOrIRI" }, + "type": { "type": "string" } + } + }, + { "$ref": "#/$defs/extension_CdxPropertiesExtension_props" } + ] + }, + "else": { + "const": "Not a extension_CdxPropertiesExtension" + } }, "extension_CdxPropertiesExtension_derived": { "anyOf": [ @@ -4190,7 +4796,7 @@ "type": "object", "properties": { "extension_cdxProperty": { - "oneOf": [ + "anyOf": [ { "type": "array", "minItems": 1, @@ -4208,24 +4814,34 @@ ] }, "prop_extension_CdxPropertiesExtension_extension_cdxProperty": { - "$ref": "#/$defs/extension_CdxPropertyEntry_derived" + "$ref": "#/$defs/extension_CdxPropertyEntry_derived" }, "security_CvssV2VulnAssessmentRelationship": { - "allOf": [ - { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "security_CvssV2VulnAssessmentRelationship" } - ] - } - }, - "required": ["spdxId"] + "if": { + "type": "object", + "properties": { + "type": { + "const": "security_CvssV2VulnAssessmentRelationship" + } }, - { "$ref": "#/$defs/security_CvssV2VulnAssessmentRelationship_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/security_CvssV2VulnAssessmentRelationship_props" } + ] + }, + "else": { + "const": "Not a security_CvssV2VulnAssessmentRelationship" + } }, "security_CvssV2VulnAssessmentRelationship_derived": { "anyOf": [ @@ -4260,35 +4876,45 @@ ] }, "prop_security_CvssV2VulnAssessmentRelationship_security_score": { - "oneOf": [ - { - "type": "number" - }, - { - "type": "string", - "pattern": "^-?[0-9]+(\\.[0-9]*)?$" - } - ] + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "pattern": "^-?[0-9]+(\\.[0-9]*)?$" + } + ] }, "prop_security_CvssV2VulnAssessmentRelationship_security_vectorString": { - "type": "string" + "type": "string" }, "security_CvssV3VulnAssessmentRelationship": { - "allOf": [ - { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "security_CvssV3VulnAssessmentRelationship" } - ] - } - }, - "required": ["spdxId"] + "if": { + "type": "object", + "properties": { + "type": { + "const": "security_CvssV3VulnAssessmentRelationship" + } }, - { "$ref": "#/$defs/security_CvssV3VulnAssessmentRelationship_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/security_CvssV3VulnAssessmentRelationship_props" } + ] + }, + "else": { + "const": "Not a security_CvssV3VulnAssessmentRelationship" + } }, "security_CvssV3VulnAssessmentRelationship_derived": { "anyOf": [ @@ -4327,44 +4953,54 @@ ] }, "prop_security_CvssV3VulnAssessmentRelationship_security_score": { - "oneOf": [ - { - "type": "number" - }, - { - "type": "string", - "pattern": "^-?[0-9]+(\\.[0-9]*)?$" - } - ] + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "pattern": "^-?[0-9]+(\\.[0-9]*)?$" + } + ] }, "prop_security_CvssV3VulnAssessmentRelationship_security_severity": { - "enum": [ - "critical", - "high", - "low", - "medium", - "none" - ] + "enum": [ + "critical", + "high", + "low", + "medium", + "none" + ] }, "prop_security_CvssV3VulnAssessmentRelationship_security_vectorString": { - "type": "string" + "type": "string" }, "security_CvssV4VulnAssessmentRelationship": { - "allOf": [ - { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "security_CvssV4VulnAssessmentRelationship" } - ] - } - }, - "required": ["spdxId"] + "if": { + "type": "object", + "properties": { + "type": { + "const": "security_CvssV4VulnAssessmentRelationship" + } }, - { "$ref": "#/$defs/security_CvssV4VulnAssessmentRelationship_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/security_CvssV4VulnAssessmentRelationship_props" } + ] + }, + "else": { + "const": "Not a security_CvssV4VulnAssessmentRelationship" + } }, "security_CvssV4VulnAssessmentRelationship_derived": { "anyOf": [ @@ -4403,44 +5039,54 @@ ] }, "prop_security_CvssV4VulnAssessmentRelationship_security_score": { - "oneOf": [ - { - "type": "number" - }, - { - "type": "string", - "pattern": "^-?[0-9]+(\\.[0-9]*)?$" - } - ] + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "pattern": "^-?[0-9]+(\\.[0-9]*)?$" + } + ] }, "prop_security_CvssV4VulnAssessmentRelationship_security_severity": { - "enum": [ - "critical", - "high", - "low", - "medium", - "none" - ] + "enum": [ + "critical", + "high", + "low", + "medium", + "none" + ] }, "prop_security_CvssV4VulnAssessmentRelationship_security_vectorString": { - "type": "string" + "type": "string" }, "security_EpssVulnAssessmentRelationship": { - "allOf": [ - { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "security_EpssVulnAssessmentRelationship" } - ] - } - }, - "required": ["spdxId"] + "if": { + "type": "object", + "properties": { + "type": { + "const": "security_EpssVulnAssessmentRelationship" + } }, - { "$ref": "#/$defs/security_EpssVulnAssessmentRelationship_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/security_EpssVulnAssessmentRelationship_props" } + ] + }, + "else": { + "const": "Not a security_EpssVulnAssessmentRelationship" + } }, "security_EpssVulnAssessmentRelationship_derived": { "anyOf": [ @@ -4475,44 +5121,54 @@ ] }, "prop_security_EpssVulnAssessmentRelationship_security_percentile": { - "oneOf": [ - { - "type": "number" - }, - { - "type": "string", - "pattern": "^-?[0-9]+(\\.[0-9]*)?$" - } - ] + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "pattern": "^-?[0-9]+(\\.[0-9]*)?$" + } + ] }, "prop_security_EpssVulnAssessmentRelationship_security_probability": { - "oneOf": [ - { - "type": "number" - }, - { - "type": "string", - "pattern": "^-?[0-9]+(\\.[0-9]*)?$" - } - ] - }, - "security_ExploitCatalogVulnAssessmentRelationship": { - "allOf": [ + "anyOf": [ { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "security_ExploitCatalogVulnAssessmentRelationship" } - ] - } - }, - "required": ["spdxId"] + "type": "number" }, - { "$ref": "#/$defs/security_ExploitCatalogVulnAssessmentRelationship_props" } + { + "type": "string", + "pattern": "^-?[0-9]+(\\.[0-9]*)?$" + } ] }, + "security_ExploitCatalogVulnAssessmentRelationship": { + "if": { + "type": "object", + "properties": { + "type": { + "const": "security_ExploitCatalogVulnAssessmentRelationship" + } + }, + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/security_ExploitCatalogVulnAssessmentRelationship_props" } + ] + }, + "else": { + "const": "Not a security_ExploitCatalogVulnAssessmentRelationship" + } + }, "security_ExploitCatalogVulnAssessmentRelationship_derived": { "anyOf": [ { @@ -4550,33 +5206,43 @@ ] }, "prop_security_ExploitCatalogVulnAssessmentRelationship_security_catalogType": { - "enum": [ - "kev", - "other" - ] + "enum": [ + "kev", + "other" + ] }, "prop_security_ExploitCatalogVulnAssessmentRelationship_security_exploited": { - "type": "boolean" + "type": "boolean" }, "prop_security_ExploitCatalogVulnAssessmentRelationship_security_locator": { - "$ref": "#/$defs/anyURI" + "$ref": "#/$defs/anyURI" }, "security_SsvcVulnAssessmentRelationship": { - "allOf": [ - { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "security_SsvcVulnAssessmentRelationship" } - ] - } - }, - "required": ["spdxId"] + "if": { + "type": "object", + "properties": { + "type": { + "const": "security_SsvcVulnAssessmentRelationship" + } }, - { "$ref": "#/$defs/security_SsvcVulnAssessmentRelationship_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/security_SsvcVulnAssessmentRelationship_props" } + ] + }, + "else": { + "const": "Not a security_SsvcVulnAssessmentRelationship" + } }, "security_SsvcVulnAssessmentRelationship_derived": { "anyOf": [ @@ -4607,12 +5273,12 @@ ] }, "prop_security_SsvcVulnAssessmentRelationship_security_decisionType": { - "enum": [ - "act", - "attend", - "track", - "trackStar" - ] + "enum": [ + "act", + "attend", + "track", + "trackStar" + ] }, "security_VexVulnAssessmentRelationship_derived": { "anyOf": [ @@ -4646,27 +5312,37 @@ ] }, "prop_security_VexVulnAssessmentRelationship_security_statusNotes": { - "type": "string" + "type": "string" }, "prop_security_VexVulnAssessmentRelationship_security_vexVersion": { - "type": "string" + "type": "string" }, "security_Vulnerability": { - "allOf": [ - { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "security_Vulnerability" } - ] - } - }, - "required": ["spdxId"] + "if": { + "type": "object", + "properties": { + "type": { + "const": "security_Vulnerability" + } }, - { "$ref": "#/$defs/security_Vulnerability_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/security_Vulnerability_props" } + ] + }, + "else": { + "const": "Not a security_Vulnerability" + } }, "security_Vulnerability_derived": { "anyOf": [ @@ -4700,37 +5376,37 @@ ] }, "prop_security_Vulnerability_security_modifiedTime": { - "type": "string", - "allOf": [ - { - "pattern": "^[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](Z|[+-][0-9]{2}:[0-9]{2})$" - }, - { - "pattern": "^\\d\\d\\d\\d-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\dZ$" - } - ] + "type": "string", + "allOf": [ + { + "pattern": "^[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](Z|[+-][0-9]{2}:[0-9]{2})$" + }, + { + "pattern": "^\\d\\d\\d\\d-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\dZ$" + } + ] }, "prop_security_Vulnerability_security_publishedTime": { - "type": "string", - "allOf": [ - { - "pattern": "^[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](Z|[+-][0-9]{2}:[0-9]{2})$" - }, - { - "pattern": "^\\d\\d\\d\\d-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\dZ$" - } - ] + "type": "string", + "allOf": [ + { + "pattern": "^[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](Z|[+-][0-9]{2}:[0-9]{2})$" + }, + { + "pattern": "^\\d\\d\\d\\d-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\dZ$" + } + ] }, "prop_security_Vulnerability_security_withdrawnTime": { - "type": "string", - "allOf": [ - { - "pattern": "^[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](Z|[+-][0-9]{2}:[0-9]{2})$" - }, - { - "pattern": "^\\d\\d\\d\\d-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\dZ$" - } - ] + "type": "string", + "allOf": [ + { + "pattern": "^[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](Z|[+-][0-9]{2}:[0-9]{2})$" + }, + { + "pattern": "^\\d\\d\\d\\d-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\dZ$" + } + ] }, "software_SoftwareArtifact_derived": { "anyOf": [ @@ -4755,7 +5431,7 @@ "type": "object", "properties": { "software_additionalPurpose": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -4765,7 +5441,7 @@ ] }, "software_attributionText": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -4775,7 +5451,7 @@ ] }, "software_contentIdentifier": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -4795,96 +5471,106 @@ ] }, "prop_software_SoftwareArtifact_software_additionalPurpose": { - "enum": [ - "application", - "archive", - "bom", - "configuration", - "container", - "data", - "device", - "deviceDriver", - "diskImage", - "documentation", - "evidence", - "executable", - "file", - "filesystemImage", - "firmware", - "framework", - "install", - "library", - "manifest", - "model", - "module", - "operatingSystem", - "other", - "patch", - "platform", - "requirement", - "source", - "specification", - "test" - ] + "enum": [ + "application", + "archive", + "bom", + "configuration", + "container", + "data", + "device", + "deviceDriver", + "diskImage", + "documentation", + "evidence", + "executable", + "file", + "filesystemImage", + "firmware", + "framework", + "install", + "library", + "manifest", + "model", + "module", + "operatingSystem", + "other", + "patch", + "platform", + "requirement", + "source", + "specification", + "test" + ] }, "prop_software_SoftwareArtifact_software_attributionText": { - "type": "string" + "type": "string" }, "prop_software_SoftwareArtifact_software_contentIdentifier": { - "$ref": "#/$defs/software_ContentIdentifier_derived" + "$ref": "#/$defs/software_ContentIdentifier_derived" }, "prop_software_SoftwareArtifact_software_copyrightText": { - "type": "string" + "type": "string" }, "prop_software_SoftwareArtifact_software_primaryPurpose": { - "enum": [ - "application", - "archive", - "bom", - "configuration", - "container", - "data", - "device", - "deviceDriver", - "diskImage", - "documentation", - "evidence", - "executable", - "file", - "filesystemImage", - "firmware", - "framework", - "install", - "library", - "manifest", - "model", - "module", - "operatingSystem", - "other", - "patch", - "platform", - "requirement", - "source", - "specification", - "test" - ] + "enum": [ + "application", + "archive", + "bom", + "configuration", + "container", + "data", + "device", + "deviceDriver", + "diskImage", + "documentation", + "evidence", + "executable", + "file", + "filesystemImage", + "firmware", + "framework", + "install", + "library", + "manifest", + "model", + "module", + "operatingSystem", + "other", + "patch", + "platform", + "requirement", + "source", + "specification", + "test" + ] }, "Bom": { - "allOf": [ - { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "Bom" } - ] - } - }, - "required": ["spdxId"] + "if": { + "type": "object", + "properties": { + "type": { + "const": "Bom" + } }, - { "$ref": "#/$defs/Bom_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/Bom_props" } + ] + }, + "else": { + "const": "Not a Bom" + } }, "Bom_derived": { "anyOf": [ @@ -4910,21 +5596,31 @@ ] }, "expandedlicensing_CustomLicense": { - "allOf": [ - { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "expandedlicensing_CustomLicense" } - ] - } - }, - "required": ["spdxId"] + "if": { + "type": "object", + "properties": { + "type": { + "const": "expandedlicensing_CustomLicense" + } }, - { "$ref": "#/$defs/expandedlicensing_CustomLicense_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/expandedlicensing_CustomLicense_props" } + ] + }, + "else": { + "const": "Not a expandedlicensing_CustomLicense" + } }, "expandedlicensing_CustomLicense_derived": { "anyOf": [ @@ -4949,21 +5645,31 @@ ] }, "security_VexAffectedVulnAssessmentRelationship": { - "allOf": [ - { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "security_VexAffectedVulnAssessmentRelationship" } - ] - } - }, - "required": ["spdxId"] + "if": { + "type": "object", + "properties": { + "type": { + "const": "security_VexAffectedVulnAssessmentRelationship" + } }, - { "$ref": "#/$defs/security_VexAffectedVulnAssessmentRelationship_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/security_VexAffectedVulnAssessmentRelationship_props" } + ] + }, + "else": { + "const": "Not a security_VexAffectedVulnAssessmentRelationship" + } }, "security_VexAffectedVulnAssessmentRelationship_derived": { "anyOf": [ @@ -4997,36 +5703,46 @@ ] }, "prop_security_VexAffectedVulnAssessmentRelationship_security_actionStatement": { - "type": "string" + "type": "string" }, "prop_security_VexAffectedVulnAssessmentRelationship_security_actionStatementTime": { - "type": "string", - "allOf": [ - { - "pattern": "^[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](Z|[+-][0-9]{2}:[0-9]{2})$" - }, - { - "pattern": "^\\d\\d\\d\\d-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\dZ$" - } - ] - }, - "security_VexFixedVulnAssessmentRelationship": { + "type": "string", "allOf": [ { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "security_VexFixedVulnAssessmentRelationship" } - ] - } - }, - "required": ["spdxId"] + "pattern": "^[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](Z|[+-][0-9]{2}:[0-9]{2})$" }, - { "$ref": "#/$defs/security_VexFixedVulnAssessmentRelationship_props" } + { + "pattern": "^\\d\\d\\d\\d-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\dZ$" + } ] }, + "security_VexFixedVulnAssessmentRelationship": { + "if": { + "type": "object", + "properties": { + "type": { + "const": "security_VexFixedVulnAssessmentRelationship" + } + }, + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/security_VexFixedVulnAssessmentRelationship_props" } + ] + }, + "else": { + "const": "Not a security_VexFixedVulnAssessmentRelationship" + } + }, "security_VexFixedVulnAssessmentRelationship_derived": { "anyOf": [ { @@ -5050,21 +5766,31 @@ ] }, "security_VexNotAffectedVulnAssessmentRelationship": { - "allOf": [ - { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "security_VexNotAffectedVulnAssessmentRelationship" } - ] - } - }, - "required": ["spdxId"] + "if": { + "type": "object", + "properties": { + "type": { + "const": "security_VexNotAffectedVulnAssessmentRelationship" + } }, - { "$ref": "#/$defs/security_VexNotAffectedVulnAssessmentRelationship_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/security_VexNotAffectedVulnAssessmentRelationship_props" } + ] + }, + "else": { + "const": "Not a security_VexNotAffectedVulnAssessmentRelationship" + } }, "security_VexNotAffectedVulnAssessmentRelationship_derived": { "anyOf": [ @@ -5098,44 +5824,54 @@ ] }, "prop_security_VexNotAffectedVulnAssessmentRelationship_security_impactStatement": { - "type": "string" + "type": "string" }, "prop_security_VexNotAffectedVulnAssessmentRelationship_security_impactStatementTime": { - "type": "string", - "allOf": [ - { - "pattern": "^[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](Z|[+-][0-9]{2}:[0-9]{2})$" - }, - { - "pattern": "^\\d\\d\\d\\d-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\dZ$" - } - ] + "type": "string", + "allOf": [ + { + "pattern": "^[0-9]{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](Z|[+-][0-9]{2}:[0-9]{2})$" + }, + { + "pattern": "^\\d\\d\\d\\d-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\dZ$" + } + ] }, "prop_security_VexNotAffectedVulnAssessmentRelationship_security_justificationType": { - "enum": [ - "componentNotPresent", - "inlineMitigationsAlreadyExist", - "vulnerableCodeCannotBeControlledByAdversary", - "vulnerableCodeNotInExecutePath", - "vulnerableCodeNotPresent" - ] + "enum": [ + "componentNotPresent", + "inlineMitigationsAlreadyExist", + "vulnerableCodeCannotBeControlledByAdversary", + "vulnerableCodeNotInExecutePath", + "vulnerableCodeNotPresent" + ] }, "security_VexUnderInvestigationVulnAssessmentRelationship": { - "allOf": [ - { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "security_VexUnderInvestigationVulnAssessmentRelationship" } - ] - } - }, - "required": ["spdxId"] + "if": { + "type": "object", + "properties": { + "type": { + "const": "security_VexUnderInvestigationVulnAssessmentRelationship" + } }, - { "$ref": "#/$defs/security_VexUnderInvestigationVulnAssessmentRelationship_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/security_VexUnderInvestigationVulnAssessmentRelationship_props" } + ] + }, + "else": { + "const": "Not a security_VexUnderInvestigationVulnAssessmentRelationship" + } }, "security_VexUnderInvestigationVulnAssessmentRelationship_derived": { "anyOf": [ @@ -5160,21 +5896,31 @@ ] }, "software_File": { - "allOf": [ - { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "software_File" } - ] - } - }, - "required": ["spdxId"] + "if": { + "type": "object", + "properties": { + "type": { + "const": "software_File" + } }, - { "$ref": "#/$defs/software_File_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/software_File_props" } + ] + }, + "else": { + "const": "Not a software_File" + } }, "software_File_derived": { "anyOf": [ @@ -5205,31 +5951,41 @@ ] }, "prop_software_File_contentType": { - "pattern": "^[^\\/]+\\/[^\\/]+$", - "type": "string" + "pattern": "^[^\\/]+\\/[^\\/]+$", + "type": "string" }, "prop_software_File_software_fileKind": { - "enum": [ - "directory", - "file" - ] + "enum": [ + "directory", + "file" + ] }, "software_Package": { - "allOf": [ - { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "software_Package" } - ] - } - }, - "required": ["spdxId"] + "if": { + "type": "object", + "properties": { + "type": { + "const": "software_Package" + } }, - { "$ref": "#/$defs/software_Package_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/software_Package_props" } + ] + }, + "else": { + "const": "Not a software_Package" + } }, "software_Package_derived": { "anyOf": [ @@ -5271,36 +6027,46 @@ ] }, "prop_software_Package_software_downloadLocation": { - "$ref": "#/$defs/anyURI" + "$ref": "#/$defs/anyURI" }, "prop_software_Package_software_homePage": { - "$ref": "#/$defs/anyURI" + "$ref": "#/$defs/anyURI" }, "prop_software_Package_software_packageUrl": { - "$ref": "#/$defs/anyURI" + "$ref": "#/$defs/anyURI" }, "prop_software_Package_software_packageVersion": { - "type": "string" + "type": "string" }, "prop_software_Package_software_sourceInfo": { - "type": "string" + "type": "string" }, "software_Sbom": { - "allOf": [ - { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "software_Sbom" } - ] - } - }, - "required": ["spdxId"] + "if": { + "type": "object", + "properties": { + "type": { + "const": "software_Sbom" + } }, - { "$ref": "#/$defs/software_Sbom_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/software_Sbom_props" } + ] + }, + "else": { + "const": "Not a software_Sbom" + } }, "software_Sbom_derived": { "anyOf": [ @@ -5321,7 +6087,7 @@ "type": "object", "properties": { "software_sbomType": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -5335,31 +6101,41 @@ ] }, "prop_software_Sbom_software_sbomType": { - "enum": [ - "analyzed", - "build", - "deployed", - "design", - "runtime", - "source" - ] + "enum": [ + "analyzed", + "build", + "deployed", + "design", + "runtime", + "source" + ] }, "software_Snippet": { - "allOf": [ - { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "software_Snippet" } - ] - } - }, - "required": ["spdxId"] + "if": { + "type": "object", + "properties": { + "type": { + "const": "software_Snippet" + } }, - { "$ref": "#/$defs/software_Snippet_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/software_Snippet_props" } + ] + }, + "else": { + "const": "Not a software_Snippet" + } }, "software_Snippet_derived": { "anyOf": [ @@ -5396,30 +6172,40 @@ ] }, "prop_software_Snippet_software_byteRange": { - "$ref": "#/$defs/PositiveIntegerRange_derived" + "$ref": "#/$defs/PositiveIntegerRange_derived" }, "prop_software_Snippet_software_lineRange": { - "$ref": "#/$defs/PositiveIntegerRange_derived" + "$ref": "#/$defs/PositiveIntegerRange_derived" }, "prop_software_Snippet_software_snippetFromFile": { - "$ref": "#/$defs/software_File_derived" + "$ref": "#/$defs/software_File_derived" }, "ai_AIPackage": { - "allOf": [ - { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "ai_AIPackage" } - ] - } - }, - "required": ["spdxId"] + "if": { + "type": "object", + "properties": { + "type": { + "const": "ai_AIPackage" + } }, - { "$ref": "#/$defs/ai_AIPackage_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/ai_AIPackage_props" } + ] + }, + "else": { + "const": "Not a ai_AIPackage" + } }, "ai_AIPackage_derived": { "anyOf": [ @@ -5443,7 +6229,7 @@ "$ref": "#/$defs/prop_ai_AIPackage_ai_autonomyType" }, "ai_domain": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -5456,7 +6242,7 @@ "$ref": "#/$defs/prop_ai_AIPackage_ai_energyConsumption" }, "ai_hyperparameter": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -5475,7 +6261,7 @@ "$ref": "#/$defs/prop_ai_AIPackage_ai_limitation" }, "ai_metric": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -5485,7 +6271,7 @@ ] }, "ai_metricDecisionThreshold": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -5495,7 +6281,7 @@ ] }, "ai_modelDataPreprocessing": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -5505,7 +6291,7 @@ ] }, "ai_modelExplainability": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -5518,7 +6304,7 @@ "$ref": "#/$defs/prop_ai_AIPackage_ai_safetyRiskAssessment" }, "ai_standardCompliance": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -5528,7 +6314,7 @@ ] }, "ai_typeOfModel": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -5545,79 +6331,89 @@ ] }, "prop_ai_AIPackage_ai_autonomyType": { - "enum": [ - "no", - "noAssertion", - "yes" - ] + "enum": [ + "no", + "noAssertion", + "yes" + ] }, "prop_ai_AIPackage_ai_domain": { - "type": "string" + "type": "string" }, "prop_ai_AIPackage_ai_energyConsumption": { - "$ref": "#/$defs/ai_EnergyConsumption_derived" + "$ref": "#/$defs/ai_EnergyConsumption_derived" }, "prop_ai_AIPackage_ai_hyperparameter": { - "$ref": "#/$defs/DictionaryEntry_derived" + "$ref": "#/$defs/DictionaryEntry_derived" }, "prop_ai_AIPackage_ai_informationAboutApplication": { - "type": "string" + "type": "string" }, "prop_ai_AIPackage_ai_informationAboutTraining": { - "type": "string" + "type": "string" }, "prop_ai_AIPackage_ai_limitation": { - "type": "string" + "type": "string" }, "prop_ai_AIPackage_ai_metric": { - "$ref": "#/$defs/DictionaryEntry_derived" + "$ref": "#/$defs/DictionaryEntry_derived" }, "prop_ai_AIPackage_ai_metricDecisionThreshold": { - "$ref": "#/$defs/DictionaryEntry_derived" + "$ref": "#/$defs/DictionaryEntry_derived" }, "prop_ai_AIPackage_ai_modelDataPreprocessing": { - "type": "string" + "type": "string" }, "prop_ai_AIPackage_ai_modelExplainability": { - "type": "string" + "type": "string" }, "prop_ai_AIPackage_ai_safetyRiskAssessment": { - "enum": [ - "high", - "low", - "medium", - "serious" - ] + "enum": [ + "high", + "low", + "medium", + "serious" + ] }, "prop_ai_AIPackage_ai_standardCompliance": { - "type": "string" + "type": "string" }, "prop_ai_AIPackage_ai_typeOfModel": { - "type": "string" + "type": "string" }, "prop_ai_AIPackage_ai_useSensitivePersonalInformation": { - "enum": [ - "no", - "noAssertion", - "yes" - ] + "enum": [ + "no", + "noAssertion", + "yes" + ] }, "dataset_DatasetPackage": { - "allOf": [ - { - "type": "object", - "properties": { - "spdxId": { "$ref": "#/$defs/IRI" }, - "type": { - "oneOf": [ - { "const": "dataset_DatasetPackage" } - ] - } - }, - "required": ["spdxId"] + "if": { + "type": "object", + "properties": { + "type": { + "const": "dataset_DatasetPackage" + } }, - { "$ref": "#/$defs/dataset_DatasetPackage_props" } - ] + "required": ["type"] + }, + "then": { + "allOf": [ + { + "type": "object", + "properties": { + "spdxId": { "$ref": "#/$defs/IRI" }, + "type": { "type": "string" } + }, + "required": ["spdxId"] + }, + { "$ref": "#/$defs/dataset_DatasetPackage_props" } + ] + }, + "else": { + "const": "Not a dataset_DatasetPackage" + } }, "dataset_DatasetPackage_derived": { "anyOf": [ @@ -5638,7 +6434,7 @@ "type": "object", "properties": { "dataset_anonymizationMethodUsed": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -5654,7 +6450,7 @@ "$ref": "#/$defs/prop_dataset_DatasetPackage_dataset_dataCollectionProcess" }, "dataset_dataPreprocessing": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -5673,7 +6469,7 @@ "$ref": "#/$defs/prop_dataset_DatasetPackage_dataset_datasetSize" }, "dataset_datasetType": { - "oneOf": [ + "anyOf": [ { "type": "array", "minItems": 1, @@ -5693,7 +6489,7 @@ "$ref": "#/$defs/prop_dataset_DatasetPackage_dataset_intendedUse" }, "dataset_knownBias": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -5703,7 +6499,7 @@ ] }, "dataset_sensor": { - "oneOf": [ + "anyOf": [ { "type": "array", "items": { @@ -5720,74 +6516,74 @@ ] }, "prop_dataset_DatasetPackage_dataset_anonymizationMethodUsed": { - "type": "string" + "type": "string" }, "prop_dataset_DatasetPackage_dataset_confidentialityLevel": { - "enum": [ - "amber", - "clear", - "green", - "red" - ] + "enum": [ + "amber", + "clear", + "green", + "red" + ] }, "prop_dataset_DatasetPackage_dataset_dataCollectionProcess": { - "type": "string" + "type": "string" }, "prop_dataset_DatasetPackage_dataset_dataPreprocessing": { - "type": "string" + "type": "string" }, "prop_dataset_DatasetPackage_dataset_datasetAvailability": { - "enum": [ - "clickthrough", - "directDownload", - "query", - "registration", - "scrapingScript" - ] + "enum": [ + "clickthrough", + "directDownload", + "query", + "registration", + "scrapingScript" + ] }, "prop_dataset_DatasetPackage_dataset_datasetNoise": { - "type": "string" + "type": "string" }, "prop_dataset_DatasetPackage_dataset_datasetSize": { - "type": "integer", - "minimum": 0 + "type": "integer", + "minimum": 0 }, "prop_dataset_DatasetPackage_dataset_datasetType": { - "enum": [ - "audio", - "categorical", - "graph", - "image", - "noAssertion", - "numeric", - "other", - "sensor", - "structured", - "syntactic", - "text", - "timeseries", - "timestamp", - "video" - ] + "enum": [ + "audio", + "categorical", + "graph", + "image", + "noAssertion", + "numeric", + "other", + "sensor", + "structured", + "syntactic", + "text", + "timeseries", + "timestamp", + "video" + ] }, "prop_dataset_DatasetPackage_dataset_datasetUpdateMechanism": { - "type": "string" + "type": "string" }, "prop_dataset_DatasetPackage_dataset_hasSensitivePersonalInformation": { - "enum": [ - "no", - "noAssertion", - "yes" - ] + "enum": [ + "no", + "noAssertion", + "yes" + ] }, "prop_dataset_DatasetPackage_dataset_intendedUse": { - "type": "string" + "type": "string" }, "prop_dataset_DatasetPackage_dataset_knownBias": { - "type": "string" + "type": "string" }, "prop_dataset_DatasetPackage_dataset_sensor": { - "$ref": "#/$defs/DictionaryEntry_derived" + "$ref": "#/$defs/DictionaryEntry_derived" }, "IRI": { "type": "string", @@ -5798,7 +6594,7 @@ "pattern": "^_:.+" }, "BlankNodeOrIRI": { - "oneOf": [ + "anyOf": [ { "$ref": "#/$defs/IRI" }, { "$ref": "#/$defs/BlankNode" } ] @@ -5810,7 +6606,7 @@ "type": "object", "properties": { "type": { - "oneOf": [ + "anyOf": [ { "$ref": "#/$defs/IRI" }, { "enum": [ From 5f3620a529069d544db60cc2f4161f3969a35f55 Mon Sep 17 00:00:00 2001 From: Gary O'Neall Date: Fri, 21 Nov 2025 14:33:20 -0800 Subject: [PATCH 39/54] Update schema to match generated schema Signed-off-by: Gary O'Neall --- resources/spdx-schema-v3.0.1.json | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/resources/spdx-schema-v3.0.1.json b/resources/spdx-schema-v3.0.1.json index 13f4636..bd7a3b5 100644 --- a/resources/spdx-schema-v3.0.1.json +++ b/resources/spdx-schema-v3.0.1.json @@ -603,6 +603,16 @@ } ] }, + "extension": { + "anyOf": [ + { + "type": "array", + "items": { + "$ref": "#/$defs/prop_Element_extension" + } + } + ] + }, "externalIdentifier": { "anyOf": [ { @@ -658,6 +668,9 @@ "prop_Element_extension": { "$ref": "#/$defs/extension_Extension_derived" }, + "prop_Element_extension": { + "$ref": "#/$defs/extension_Extension_derived" + }, "prop_Element_externalIdentifier": { "$ref": "#/$defs/ExternalIdentifier_derived" }, From ec1f6634d27c8f9042e0d620277a674b141837e7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Dec 2025 18:12:47 +0000 Subject: [PATCH 40/54] Bump org.apache.maven.plugins:maven-source-plugin from 3.3.1 to 3.4.0 Bumps [org.apache.maven.plugins:maven-source-plugin](https://github.com/apache/maven-source-plugin) from 3.3.1 to 3.4.0. - [Release notes](https://github.com/apache/maven-source-plugin/releases) - [Commits](https://github.com/apache/maven-source-plugin/compare/maven-source-plugin-3.3.1...maven-source-plugin-3.4.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-source-plugin dependency-version: 3.4.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7335130..de31612 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ org.apache.maven.plugins maven-source-plugin - 3.3.1 + 3.4.0 attach-sources From 0ce3002985543d6fb02f17127a3bb1cc3d77c974 Mon Sep 17 00:00:00 2001 From: Gary O'Neall Date: Wed, 3 Dec 2025 09:00:57 -0800 Subject: [PATCH 41/54] Update SPDX library versions Signed-off-by: Gary O'Neall --- pom.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index de31612..92dec7d 100644 --- a/pom.xml +++ b/pom.xml @@ -118,17 +118,17 @@ org.spdx java-spdx-library - 2.0.1 + 2.0.2 org.spdx spdx-jackson-store - 2.0.3 + 2.0.4 org.spdx spdx-rdf-store - 2.0.1 + 2.0.2 org.spdx @@ -138,12 +138,12 @@ org.spdx spdx-tagvalue-store - 2.0.1 + 2.0.2 org.spdx spdx-v3jsonld-store - 1.0.1 + 1.0.2 com.networknt From a097f097e745fd1083d8995cb88d86dbd51ae2ff Mon Sep 17 00:00:00 2001 From: Gary O'Neall Date: Wed, 3 Dec 2025 09:28:43 -0800 Subject: [PATCH 42/54] [maven-release-plugin] prepare release v2.0.3 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 92dec7d..0d38483 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ org.spdx tools-java - 2.0.3-SNAPSHOT + 2.0.3 jar tools-java @@ -32,7 +32,7 @@ https://github.com/spdx/tools-java scm:git:git@github.com:spdx/tools-java.git scm:git:git@github.com:spdx/tools-java.git - master + v2.0.3 Github From de4734dd6d36df9002b66136117cf3859e5447c8 Mon Sep 17 00:00:00 2001 From: Gary O'Neall Date: Wed, 3 Dec 2025 09:28:58 -0800 Subject: [PATCH 43/54] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 0d38483..a1309e7 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ org.spdx tools-java - 2.0.3 + 2.0.4-SNAPSHOT jar tools-java @@ -32,7 +32,7 @@ https://github.com/spdx/tools-java scm:git:git@github.com:spdx/tools-java.git scm:git:git@github.com:spdx/tools-java.git - v2.0.3 + master Github From 77a41decbe94825424267827180ba738f8cb53cf Mon Sep 17 00:00:00 2001 From: Gary O'Neall Date: Fri, 5 Dec 2025 10:23:53 -0800 Subject: [PATCH 44/54] Revert json-schema-validator version to 1.5.9 Fixes #257 Version 2.0.0 of the json-schema-validator introduces a very significant performance degredation Signed-off-by: Gary O'Neall --- .../examples/ExpandedLicenseExampleV3.java | 22 +++++++-------- .../org/spdx/examples/FullSpdxV3Example.java | 21 +++++++-------- pom.xml | 2 +- src/main/java/org/spdx/tools/Verify.java | 27 ++++++++++--------- 4 files changed, 36 insertions(+), 36 deletions(-) diff --git a/examples/org/spdx/examples/ExpandedLicenseExampleV3.java b/examples/org/spdx/examples/ExpandedLicenseExampleV3.java index 030b1b2..5b07d11 100644 --- a/examples/org/spdx/examples/ExpandedLicenseExampleV3.java +++ b/examples/org/spdx/examples/ExpandedLicenseExampleV3.java @@ -3,7 +3,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2025 Source Auditor Inc. * SPDX-FileType: SOURCE * SPDX-License-Identifier: Apache-2.0 - * + *
* Example of serializing a single expanded license */ @@ -12,10 +12,10 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; -import com.networknt.schema.Error; -import com.networknt.schema.Schema; -import com.networknt.schema.SchemaRegistry; -import com.networknt.schema.SpecificationVersion; +import com.networknt.schema.JsonSchema; +import com.networknt.schema.JsonSchemaFactory; +import com.networknt.schema.SpecVersion.VersionFlag; +import com.networknt.schema.ValidationMessage; import org.spdx.core.DefaultModelStore; import org.spdx.core.IModelCopyManager; import org.spdx.library.LicenseInfoFactory; @@ -37,6 +37,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Set; import static org.spdx.tools.Verify.JSON_SCHEMA_RESOURCE_V3; @@ -158,18 +159,17 @@ public static void main(String[] args) throws Exception { try (OutputStream outStream = new FileOutputStream(outFile)) { modelStore.serialize(outStream, doc); } - SchemaRegistry schemaRegistry = - SchemaRegistry.withDefaultDialect(SpecificationVersion.DRAFT_2020_12); - Schema schema; + JsonSchemaFactory jsonSchemaFactory = JsonSchemaFactory.getInstance(VersionFlag.V202012); + JsonSchema schema; try (InputStream is = Verify.class.getResourceAsStream("/" + JSON_SCHEMA_RESOURCE_V3)) { - schema = schemaRegistry.getSchema(is); + schema = jsonSchemaFactory.getSchema(is); } JsonNode root; try (InputStream is = new FileInputStream(outFile)) { root = JSON_MAPPER.readTree(is); } - List messages = schema.validate(root); - for (Error msg:messages) { + Set messages = schema.validate(root); + for (ValidationMessage msg:messages) { warnings.add(msg.toString()); } if (!warnings.isEmpty()) { diff --git a/examples/org/spdx/examples/FullSpdxV3Example.java b/examples/org/spdx/examples/FullSpdxV3Example.java index fd1b269..132b3a6 100644 --- a/examples/org/spdx/examples/FullSpdxV3Example.java +++ b/examples/org/spdx/examples/FullSpdxV3Example.java @@ -3,7 +3,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2025 Source Auditor Inc. * SPDX-FileType: SOURCE * SPDX-License-Identifier: Apache-2.0 - * + *
* Full example of an SPDX document using all classes */ @@ -12,10 +12,10 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; -import com.networknt.schema.Error; -import com.networknt.schema.Schema; -import com.networknt.schema.SchemaRegistry; -import com.networknt.schema.SpecificationVersion; +import com.networknt.schema.JsonSchema; +import com.networknt.schema.JsonSchemaFactory; +import com.networknt.schema.SpecVersion.VersionFlag; +import com.networknt.schema.ValidationMessage; import org.spdx.core.DefaultModelStore; import org.spdx.core.IModelCopyManager; import org.spdx.core.InvalidSPDXAnalysisException; @@ -838,18 +838,17 @@ public static void main(String[] args) throws Exception { } // Validate using the schema - SchemaRegistry schemaRegistry = - SchemaRegistry.withDefaultDialect(SpecificationVersion.DRAFT_2020_12); - Schema schema; + JsonSchemaFactory jsonSchemaFactory = JsonSchemaFactory.getInstance(VersionFlag.V202012); + JsonSchema schema; try (InputStream is = Verify.class.getResourceAsStream("/" + JSON_SCHEMA_RESOURCE_V3)) { - schema = schemaRegistry.getSchema(is); + schema = jsonSchemaFactory.getSchema(is); } JsonNode root; try (InputStream is = new FileInputStream(outFile)) { root = JSON_MAPPER.readTree(is); } - List messages = schema.validate(root); - for (Error msg:messages) { + Set messages = schema.validate(root); + for (ValidationMessage msg:messages) { warnings.add(msg.toString()); } if (!warnings.isEmpty()) { diff --git a/pom.xml b/pom.xml index a1309e7..2034dbe 100644 --- a/pom.xml +++ b/pom.xml @@ -148,7 +148,7 @@ com.networknt json-schema-validator - 2.0.0 + 1.5.9 org.slf4j diff --git a/src/main/java/org/spdx/tools/Verify.java b/src/main/java/org/spdx/tools/Verify.java index 80b4f75..00ff30e 100644 --- a/src/main/java/org/spdx/tools/Verify.java +++ b/src/main/java/org/spdx/tools/Verify.java @@ -2,13 +2,13 @@ * SPDX-FileCopyrightText: Copyright (c) 2015 Source Auditor Inc. * SPDX-FileType: SOURCE * SPDX-License-Identifier: Apache-2.0 - * + *
* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + *
* https://www.apache.org/licenses/LICENSE-2.0 - * + *
* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -26,6 +26,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.Set; import com.fasterxml.jackson.core.JsonParseException; @@ -39,10 +40,11 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; -import com.networknt.schema.Schema; -import com.networknt.schema.SchemaRegistry; -import com.networknt.schema.SpecificationVersion; -import com.networknt.schema.Error; + +import com.networknt.schema.JsonSchema; +import com.networknt.schema.JsonSchemaFactory; +import com.networknt.schema.SpecVersion.VersionFlag; +import com.networknt.schema.ValidationMessage; /** * Verifies an SPDX document and lists any verification errors @@ -171,18 +173,17 @@ public static List verify(String filePath, SerFileType fileType) throws } else { jsonSchemaResource = JSON_SCHEMA_RESOURCE_V3; } - SchemaRegistry schemaRegistry = - SchemaRegistry.withDefaultDialect(SpecificationVersion.DRAFT_2020_12); - Schema schema; + JsonSchemaFactory jsonSchemaFactory = JsonSchemaFactory.getInstance(VersionFlag.V202012); + JsonSchema schema; try (InputStream is = Verify.class.getResourceAsStream("/" + jsonSchemaResource)) { - schema = schemaRegistry.getSchema(is); + schema = jsonSchemaFactory.getSchema(is); } JsonNode root; try (InputStream is = new FileInputStream(file)) { root = JSON_MAPPER.readTree(is); } - List messages = schema.validate(root); - for (Error msg:messages) { + Set messages = schema.validate(root); + for (ValidationMessage msg:messages) { retval.add(msg.toString()); } } catch (IOException e) { From 93c22b84e78c74d436f88ff95c7aaa0f2bfe5eb7 Mon Sep 17 00:00:00 2001 From: Gary O'Neall Date: Fri, 5 Dec 2025 11:11:30 -0800 Subject: [PATCH 45/54] [maven-release-plugin] prepare release v2.0.4 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 2034dbe..d0d5684 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ org.spdx tools-java - 2.0.4-SNAPSHOT + 2.0.4 jar tools-java @@ -32,7 +32,7 @@ https://github.com/spdx/tools-java scm:git:git@github.com:spdx/tools-java.git scm:git:git@github.com:spdx/tools-java.git - master + v2.0.4 Github From 085d5b4c55cb4a9304ec24407734275a1d07b67f Mon Sep 17 00:00:00 2001 From: Gary O'Neall Date: Fri, 5 Dec 2025 11:11:37 -0800 Subject: [PATCH 46/54] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index d0d5684..2458f23 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ org.spdx tools-java - 2.0.4 + 2.0.5-SNAPSHOT jar tools-java @@ -32,7 +32,7 @@ https://github.com/spdx/tools-java scm:git:git@github.com:spdx/tools-java.git scm:git:git@github.com:spdx/tools-java.git - v2.0.4 + master Github From 9bba4eb85557f3c2689da5f14d5e19a027586a8b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Dec 2025 16:01:09 +0000 Subject: [PATCH 47/54] Bump org.spdx:spdx-spreadsheet-store from 2.0.1 to 2.0.2 Bumps [org.spdx:spdx-spreadsheet-store](https://github.com/spdx/spdx-spreadsheet-store) from 2.0.1 to 2.0.2. - [Commits](https://github.com/spdx/spdx-spreadsheet-store/commits) --- updated-dependencies: - dependency-name: org.spdx:spdx-spreadsheet-store dependency-version: 2.0.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2458f23..03c021d 100644 --- a/pom.xml +++ b/pom.xml @@ -133,7 +133,7 @@ org.spdx spdx-spreadsheet-store - 2.0.1 + 2.0.2 org.spdx From a0feec8295a003077f99864ea2961365b79126ed Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Jan 2026 20:16:04 +0000 Subject: [PATCH 48/54] Bump org.sonatype.central:central-publishing-maven-plugin Bumps [org.sonatype.central:central-publishing-maven-plugin](https://github.com/sonatype/central-publishing-maven-plugin) from 0.9.0 to 0.10.0. - [Commits](https://github.com/sonatype/central-publishing-maven-plugin/commits) --- updated-dependencies: - dependency-name: org.sonatype.central:central-publishing-maven-plugin dependency-version: 0.10.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 03c021d..97cbd82 100644 --- a/pom.xml +++ b/pom.xml @@ -205,7 +205,7 @@ org.sonatype.central central-publishing-maven-plugin - 0.9.0 + 0.10.0 true central From 515493fb1bc287b95cb49cd4e53983e48f99aad6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Jan 2026 20:15:55 +0000 Subject: [PATCH 49/54] Bump org.owasp:dependency-check-maven from 12.1.9 to 12.2.0 Bumps [org.owasp:dependency-check-maven](https://github.com/dependency-check/DependencyCheck) from 12.1.9 to 12.2.0. - [Release notes](https://github.com/dependency-check/DependencyCheck/releases) - [Changelog](https://github.com/dependency-check/DependencyCheck/blob/main/CHANGELOG.md) - [Commits](https://github.com/dependency-check/DependencyCheck/compare/v12.1.9...v12.2.0) --- updated-dependencies: - dependency-name: org.owasp:dependency-check-maven dependency-version: 12.2.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 97cbd82..fdf0b97 100644 --- a/pom.xml +++ b/pom.xml @@ -48,7 +48,7 @@ https://sonarcloud.io spdx tools-java - 12.1.9 + 12.2.0 11 -Xdoclint:none From 968beea74ade1ff11967b0cebb979c79c150c9a1 Mon Sep 17 00:00:00 2001 From: Gary O'Neall Date: Sat, 17 Jan 2026 19:08:53 -0800 Subject: [PATCH 50/54] Add sonar-maven-plugin version 5.5.0.6356 --- pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pom.xml b/pom.xml index fdf0b97..91625f9 100644 --- a/pom.xml +++ b/pom.xml @@ -361,6 +361,11 @@ deploy + + org.sonarsource.scanner.maven + sonar-maven-plugin + 5.5.0.6356 +
From c7e8af736bff01b8f2f09bb4e71184cca209acd3 Mon Sep 17 00:00:00 2001 From: Helio Chissini de Castro Date: Sun, 18 Jan 2026 09:59:06 +0100 Subject: [PATCH 51/54] feat(docker): Improve docker build and prevent double path in naming Signed-off-by: Helio Chissini de Castro --- .github/workflows/docker_deploy.yml | 37 +++++++++++++---------------- Dockerfile | 13 ++++------ 2 files changed, 22 insertions(+), 28 deletions(-) diff --git a/.github/workflows/docker_deploy.yml b/.github/workflows/docker_deploy.yml index 55ce713..26af21c 100644 --- a/.github/workflows/docker_deploy.yml +++ b/.github/workflows/docker_deploy.yml @@ -6,9 +6,14 @@ name: Docker Build on: + workflow_dispatch: + pull_request: + paths: + - Dockerfile + - .github/workflows/docker_deploy.yml push: paths-ignore: - - "**.md" + - '**.md' tags: - 'v*' env: @@ -24,22 +29,13 @@ jobs: steps: - name: Checkout main repository - uses: actions/checkout@v3 - - - name: Set environment variables - run: | - echo "ORG_BASE_NAME=${GITHUB_REPOSITORY}" >> $GITHUB_ENV - echo "TOOLS_JAVA_VERSION=${GITHUB_REF_NAME/v/}" >> $GITHUB_ENV - - name: Echoing current version - run: | - echo "$TOOLS_JAVA_VERSION" - echo $GITHUB_REF_NAME + uses: actions/checkout@v5 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 - name: Login to GitHub Container Registry - uses: docker/login-action@v2 + uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} @@ -47,19 +43,20 @@ jobs: - name: Extract components metadata id: meta_base - uses: docker/metadata-action@v4 + uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v51.0.0 with: - images: | - ${{ env.REGISTRY }}/${{ env.ORG_BASE_NAME }}/tools-java + tags: | + type=ref,event=tag + type=semver,pattern={{version}} + type=raw,value=main,enable=${{ github.ref == 'refs/heads/main' }} + labels: org.opencontainers.image.licenses=Apache-2.0 - name: Build Container - uses: docker/build-push-action@v3 + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 with: context: . - push: true + push: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') }} load: false - build-args: | - TOOLS_JAVA_VERSION=${{ env.TOOLS_JAVA_VERSION }} tags: | ${{ steps.meta_base.outputs.tags }} labels: ${{ steps.meta_base.outputs.labels }} diff --git a/Dockerfile b/Dockerfile index df1be6a..9b37ffb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,23 +1,21 @@ # syntax=docker/dockerfile:1.4 # Set Java versions -ARG JAVA_VERSION=17 +ARG JAVA_VERSION=21 # Use Maven eclipse Temurin based -FROM maven:3.8-eclipse-temurin-$JAVA_VERSION as build - -ARG TOOLS_JAVA_VERSION=1.1.5-SNAPSHOT +FROM maven:3.9-eclipse-temurin-$JAVA_VERSION as build WORKDIR /build # BUILD RUN --mount=type=cache,target=/root/.m2 \ --mount=type=bind,source=$PWD,target=/build,rw \ - mvn clean org.jacoco:jacoco-maven-plugin:prepare-agent install \ + export TOOLS_JAVA_VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout) \ + && mvn clean org.jacoco:jacoco-maven-plugin:prepare-agent install \ && mkdir -p /usr/lib/java/spdx \ && cp target/tools-java-$TOOLS_JAVA_VERSION-jar-with-dependencies.jar /usr/lib/java/spdx/ - # Configure the wrapper script COPY scripts/tools-java-wrapper.sh /usr/bin/tools-java @@ -25,11 +23,10 @@ COPY scripts/tools-java-wrapper.sh /usr/bin/tools-java RUN sed -i "s/@@VERSION@@/$TOOLS_JAVA_VERSION/g" /usr/bin/tools-java \ && chmod +x /usr/bin/tools-java - # Deploy image FROM eclipse-temurin:$JAVA_VERSION as run COPY --from=build /usr/lib/java/spdx /usr/lib/java/spdx COPY --from=build /usr/bin/tools-java /usr/bin/tools-java -ENTRYPOINT [ "/usr/bin/tools-java" ] \ No newline at end of file +ENTRYPOINT [ "/usr/bin/tools-java" ] From 0e188d55b7e1e03a2729f94fc81ec8e5d71a3faa Mon Sep 17 00:00:00 2001 From: Helio Chissini de Castro Date: Sun, 18 Jan 2026 11:16:14 +0100 Subject: [PATCH 52/54] feat(docker): Enable multiarch image Signed-off-by: Helio Chissini de Castro --- .github/workflows/docker_deploy.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/docker_deploy.yml b/.github/workflows/docker_deploy.yml index 26af21c..f35157a 100644 --- a/.github/workflows/docker_deploy.yml +++ b/.github/workflows/docker_deploy.yml @@ -31,6 +31,9 @@ jobs: - name: Checkout main repository uses: actions/checkout@v5 + - name: Setup QEMU + uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 + - name: Set up Docker Buildx uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 @@ -45,6 +48,8 @@ jobs: id: meta_base uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v51.0.0 with: + images: | + ${{ env.REGISTRY }}/${{ github.repository }} tags: | type=ref,event=tag type=semver,pattern={{version}} @@ -57,6 +62,7 @@ jobs: context: . push: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') }} load: false + platforms: linux/amd64,linux/arm64 tags: | ${{ steps.meta_base.outputs.tags }} labels: ${{ steps.meta_base.outputs.labels }} From e545a1b00da91a1ba7083c276c518cbe88215f6a Mon Sep 17 00:00:00 2001 From: Arthit Suriyawongkul Date: Mon, 19 Jan 2026 11:58:45 +0000 Subject: [PATCH 53/54] Add cooldown period for Maven updates in Dependabot Add 7 days cooldown period --- .github/dependabot.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 3cddd8c..ff70475 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,6 +1,8 @@ version: 2 updates: - package-ecosystem: "maven" + cooldown: + default-days: 7 directory: "/" schedule: interval: "weekly" From 1f67a1901bb345724813a2fbee05e2e38bf0d694 Mon Sep 17 00:00:00 2001 From: Marc-Etienne Vargenau Date: Wed, 18 Feb 2026 11:08:28 +0100 Subject: [PATCH 54/54] Update READEME for release 2.0.4 Signed-off-by: Marc-Etienne Vargenau --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index e1258bf..b38af53 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ If you are a developer, there are examples in the [examples folder](examples/org The command line interface of the SPDX Tools can be used like this: - java -jar tools-java-2.0.2-jar-with-dependencies.jar + java -jar tools-java-2.0.4-jar-with-dependencies.jar ## SPDX format converters @@ -54,18 +54,18 @@ The following converter tools support SPDX format: Example to convert a SPDX file from Tag to RDF format: - java -jar tools-java-2.0.2-jar-with-dependencies.jar Convert ../testResources/SPDXTagExample-v2.2.spdx TagToRDF.rdf + java -jar tools-java-2.0.4-jar-with-dependencies.jar Convert ../testResources/SPDXTagExample-v2.2.spdx TagToRDF.rdf The file formats can optionally be provided as the 3rd and 4th parameter for the input and output formats respectively. An optional 5th option `excludeLicenseDetails` will not copy the listed license properties to the output file. The following example will copy a JSON format to an RDF Turtle format without including the listed license properties: - java -jar tools-java-2.0.2-jar-with-dependencies.jar Convert ../testResources/SPDXTagExample-v2.2.spdx TagToRDF.ttl TAG RDFTTL excludeLicenseDetails + java -jar tools-java-2.0.4-jar-with-dependencies.jar Convert ../testResources/SPDXTagExample-v2.2.spdx TagToRDF.ttl TAG RDFTTL excludeLicenseDetails To convert from SPDX 2 to SPDX 3.0.1: * use the file extension `.jsonld.json` or `.jsonld`; * or add the options for the from and to file types: - java -jar tools-java-2.0.2-jar-with-dependencies.jar Convert hello.spdx hello.spdx.json TAG JSONLD + java -jar tools-java-2.0.4-jar-with-dependencies.jar Convert hello.spdx hello.spdx.json TAG JSONLD ## Compare utilities @@ -75,13 +75,13 @@ The following tools can be used to compare one or more SPDX documents: Example to compare multiple SPDX files provided in RDF format and provide a spreadsheet with the results: - java -jar tools-java-2.0.2-jar-with-dependencies.jar CompareDocs output.xlsx doc1 doc2 ... docN + java -jar tools-java-2.0.4-jar-with-dependencies.jar CompareDocs output.xlsx doc1 doc2 ... docN * CompareMultipleSpdxDocs with directory Example to compare all SPDX documents in a directory "/home/me/spdxdocs" and provide a spreadsheet with the results: - java -jar tools-java-2.0.2-jar-with-dependencies.jar CompareDocs output.xlsx /home/me/spdxdocs + java -jar tools-java-2.0.4-jar-with-dependencies.jar CompareDocs output.xlsx /home/me/spdxdocs ## SPDX Viewer @@ -91,7 +91,7 @@ The following tool can be used to "Pretty Print" an SPDX document. Sample usage: - java -jar tools-java-2.0.2-jar-with-dependencies.jar SPDXViewer ../testResources/SPDXRdfExample-v2.2.spdx.rdf + java -jar tools-java-2.0.4-jar-with-dependencies.jar SPDXViewer ../testResources/SPDXRdfExample-v2.2.spdx.rdf ## Verifier @@ -101,7 +101,7 @@ The following tool can be used to verify an SPDX document: Sample usage: - java -jar tools-java-2.0.2-jar-with-dependencies.jar Verify ../testResources/SPDXRdfExample-v2.2.spdx.rdf + java -jar tools-java-2.0.4-jar-with-dependencies.jar Verify ../testResources/SPDXRdfExample-v2.2.spdx.rdf ## Generators @@ -111,7 +111,7 @@ The following tool can be used to generate an SPDX verification code from a dire Sample usage: - java -jar tools-java-2.0.2-jar-with-dependencies.jar GenerateVerificationCode sourceDirectory [ignoredFilesRegex] + java -jar tools-java-2.0.4-jar-with-dependencies.jar GenerateVerificationCode sourceDirectory [ignoredFilesRegex] ## SPDX Validation Tool