diff --git a/pom.xml b/pom.xml index 4a2dbfe..924c6cf 100644 --- a/pom.xml +++ b/pom.xml @@ -96,17 +96,17 @@ org.spdx java-spdx-library - 1.1.6 + 1.1.8-SNAPSHOT org.spdx spdx-rdf-store - 1.1.6 + 1.1.7-SNAPSHOT org.spdx spdx-jackson-store - 1.1.6 + 1.1.7-SNAPSHOT org.apache.ws.xmlschema @@ -116,18 +116,28 @@ org.spdx spdx-spreadsheet-store - 1.1.6 + 1.1.7-SNAPSHOT org.spdx spdx-tagvalue-store - 1.1.6 + 1.1.7-SNAPSHOT com.github.java-json-tools json-schema-validator 2.2.14 + + org.apache.jena + jena-shacl + 4.8.0 + + + com.github.spullara.mustache.java + compiler + 0.7.9 + diff --git a/resources/javaTemplates/EnumTemplate.txt b/resources/javaTemplates/EnumTemplate.txt new file mode 100644 index 0000000..3987d3c --- /dev/null +++ b/resources/javaTemplates/EnumTemplate.txt @@ -0,0 +1,45 @@ +/** + * Copyright (c) {{{year}}} Source Auditor Inc. + * + * 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 + * + * http://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. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package {{{pkgName}}}; + +{{{classComment}}} +public enum {{{name}}} implements IndividualUriValue { + + {{#enumValues}} + {{{.}}} + {{/enumValues}} + + private String longName; + + private {{{name}}}(String longName) { + this.longName = longName; + } + + @Override + public String getIndividualURI() { + return getNameSpace() + "/" + getLongName(); + } + + public String getLongName() { + return longName; + } + + public String getNameSpace() { + return "{{{classUri}}}"; + } diff --git a/resources/javaTemplates/ModelObjectTemplate.txt b/resources/javaTemplates/ModelObjectTemplate.txt new file mode 100644 index 0000000..c80da7b --- /dev/null +++ b/resources/javaTemplates/ModelObjectTemplate.txt @@ -0,0 +1,280 @@ +/** + * Copyright (c) {{{year}}} Source Auditor Inc. + * + * 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 + * + * http://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. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package {{{pkgName}}}; + +{{#imports}} +{{.}} +{{/imports}} + +{{{classComments}}} +public class {{{name}}} extends {{{superClass}}} {{#compareUsingProperties}}implements Comparable<{{{name}}}>{{/compareUsingProperties}} { + + {{#objectPropertyValueCollection}} + TO BE IMPLEMENTED + {{/objectPropertyValueCollection}} + {{#stringCollection}} + TO BE IMPLEMENTED + {{/stringCollection}} + {{#objectPropertyValueSet}} + TO BE IMPLEMENTED + {{/objectPropertyValueSet}} + + /** + * Create the {{{name}}} with default model store and generated anonymous ID + * @throws InvalidSPDXAnalysisException when unable to create the {{{name}}} + */ + public {{{name}}}() throws InvalidSPDXAnalysisException { + super(); + } + + /** + * @param objectUri URI or anonymous ID for the {{{name}}} + * @throws InvalidSPDXAnalysisException when unable to create the {{{name}}} + */ + public {{{name}}}(String objectUri) throws InvalidSPDXAnalysisException { + super(objectUri); + } + + /** + * @param modelStore Model store where the {{{name}}} is to be stored + * @param objectUri URI or anonymous ID for the {{{name}}} + * @param copyManager Copy manager for the {{{name}}} - can be null if copying is not required + * @param create true if {{{name}}} is to be created + * @throws InvalidSPDXAnalysisException when unable to create the {{{name}}} + */ + public {{{name}}}(IModelStore modelStore, String objectUri, ModelCopyManager copyManager, + boolean create) throws InvalidSPDXAnalysisException { + super(modelStore, objectUri, copyManager, create); + } + + /* (non-Javadoc) + * @see org.spdx.library.model.ModelObject#getType() + */ + @Override + public String getType() { + return {{{name}}}; + } + + /* (non-Javadoc) + * @see org.spdx.library.model.ModelObject#_verify(java.util.List) + */ + @Override + protected List _verify(Set verifiedIds, String specVersion) { + List retval = new ArrayList<>(); + {{#verifySuperclass}} + retval.addAll(super._verify(verifiedIds, specVersion); + {{/verifySuperclass}} + {{#elementProperties}} + Optional<{{{elementProperties.type}}}> {{{elementProperties.name}}}; + try { + {{{elementProperties.name}}} = {{{elementProperties.getter}}}; + if ({{{elementProperties.name}}}.isPresent()) { + retval.addAll({{{elementProperties.name}}}.get().verify(verifiedIds, specVersion)); + {{#elementProperties.required}} + else { + if (getProfile() in {{{elementProperties.requiredProfiles}}}) { + retval.add("Missing {{{elementProperties.name}}} in {{{name}}}"); + } + {{/elementProperties.required}} + } + } catch (InvalidSPDXAnalysisException e) { + retval.add("Error getting {{{elementProperties.name}}} for {{{name}}}: "+e.getMessage()); + } + {{/elementProperties}} + {{#objectProperties}} + Optional<{{{objectProperties.type}}}> {{{objectProperties.name}}}; + try { + {{{objectProperties.name}}} = {{{objectProperties.getter}}}; + if ({{{objectProperties.name}}}.isPresent()) { + retval.addAll({{{objectProperties.name}}}.get().verify(verifiedIds, specVersion)); + {{#objectProperties.required}} + else { + if (getProfile() in {{{objectProperties.requiredProfiles}}}) { + retval.add("Missing {{{objectProperties.name}}} in {{{name}}}"); + } + {{/objectProperties.required}} + } + } catch (InvalidSPDXAnalysisException e) { + retval.add("Error getting {{{objectProperties.name}}} for {{{name}}}: "+e.getMessage()); + } + {{/objectProperties}} + {{#anyLicenseInfoProperties}} + Optional<{{{anyLicenseInfoProperties.type}}}> {{{anyLicenseInfoProperties.name}}}; + try { + {{{anyLicenseInfoProperties.name}}} = {{{anyLicenseInfoProperties.getter}}}; + if ({{{anyLicenseInfoProperties.name}}}.isPresent()) { + retval.addAll({{{anyLicenseInfoProperties.name}}}.get().verify(verifiedIds, specVersion)); + {{#anyLicenseInfoProperties.required}} + else { + if (getProfile() in {{{anyLicenseInfoProperties.requiredProfiles}}}) { + retval.add("Missing {{{anyLicenseInfoProperties.name}}} in {{{name}}}"); + } + {{/anyLicenseInfoProperties.required}} + } + } catch (InvalidSPDXAnalysisException e) { + retval.add("Error getting {{{anyLicenseInfoProperties.name}}} for {{{name}}}: "+e.getMessage()); + } + {{/anyLicenseInfoProperties}} + {{#enumerationProperties}} + try { + Optional<{{{enumerationProperties.type}}}> {{{enumerationProperties.name}}} = {{{enumerationProperties.getter}}}; + {{#enumerationProperties.required}} + if (!{{{enumerationProperties.name}}}.isPresent()) { + retval.add("Missing {{{enumerationProperties.name}}} in {{{name}}}"); + } + {{/enumerationProperties.required}} + } catch (InvalidSPDXAnalysisException e) { + retval.add("Error getting {{{enumerationProperties.name}}} for {{{name}}}: "+e.getMessage()); + } + {{/enumerationProperties}} + {{#booleanProperties}} + try { + Optional<{{{booleanProperties.type}}}> {{{booleanProperties.name}}} = {{{booleanProperties.getter}}}; + {{#booleanProperties.required}} + if (!{{{booleanProperties.name}}}.isPresent()) { + retval.add("Missing {{{booleanProperties.name}}} in {{{name}}}"); + } + {{/booleanProperties.required}} + } catch (InvalidSPDXAnalysisException e) { + retval.add("Error getting {{{booleanProperties.name}}} for {{{name}}}: "+e.getMessage()); + } + {{/booleanProperties}} + {{#integerProperties}} + try { + Optional<{{{integerProperties.type}}}> {{{integerProperties.name}}} = {{{integerProperties.getter}}}; + {{#integerProperties.required}} + if (!{{{integerProperties.name}}}.isPresent()) { + retval.add("Missing {{{integerProperties.name}}} in {{{name}}}"); + } + {{/integerProperties.required}} + {{#integerProperties.min}} + TODO Implement + {{/integerProperties.min}} + {{#integerProperties.max}} + TODO Implement + {{/integerProperties.max}} + } catch (InvalidSPDXAnalysisException e) { + retval.add("Error getting {{{integerProperties.name}}} for {{{name}}}: "+e.getMessage()); + } + {{/integerProperties}} + {{#stringProperties}} + try { + Optional<{{{stringProperties.type}}}> {{{stringProperties.name}}} = {{{stringProperties.getter}}}; + {{#stringProperties.required}} + if (!{{{stringProperties.name}}}.isPresent()) { + retval.add("Missing {{{stringProperties.name}}} in {{{name}}}"); + } + {{/stringProperties.required}} + {{#stringProperties.pattern}} + TODO: Implement Pattern.compile etc + {{/stringProperties.pattern}} + } catch (InvalidSPDXAnalysisException e) { + retval.add("Error getting {{{stringProperties.name}}} for {{{name}}}: "+e.getMessage()); + } + {{/stringProperties}} + + + {{#objectPropertyValueCollection}} + TO BE IMPLEMENTED + {{/objectPropertyValueCollection}} + {{#stringCollection}} + TO BE IMPLEMENTED + {{/stringCollection}} + {{#objectPropertyValueSet}} + TO BE IMPLEMENTED + {{/objectPropertyValueSet}} + return retval; + } + + // Getters and Setters + {{#objectPropertyValueCollection}} + TO BE IMPLEMENTED + {{/objectPropertyValueCollection}} + {{#stringCollection}} + TO BE IMPLEMENTED + {{/stringCollection}} + {{#objectPropertyValueSet}} + TO BE IMPLEMENTED + {{/objectPropertyValueSet}} + + + {{#elementProperties}} + /** + * @return the {{{elementProperties.name}}} + */ + public Optional<{{{elementProperties.type}}}> {{{elementProperties.getter}}} throws InvalidSPDXAnalysisException { + return getElementPropertyValue({{{elementProperties.propertyConstant}}}); + } + + /** + * @param {{{elementProperties.name}}} the {{{elementProperties.name}}} to set + * @return this to chain setters + * @throws InvalidSPDXAnalysisException + */ + public {{{name}}} {{{elementProperties.setter}}}({{{elementProperties.type}}} {{{elementProperties.name}}}) throws InvalidSPDXAnalysisException { + setPropertyValue({{{elementProperties.uri}}}, {{{elementProperties.propertyConstant}}}); + return this; + } + {{/elementProperties}} + + {{#compareUsingProperties}} + /* (non-Javadoc) + * @see java.lang.Comparable#compareTo(java.lang.Object) + */ + @Override + public int compareTo({{{name}}} o) { + int retval = 0; + {{#compareProperties}} + Optional<{{{compareWithProperties.type}}}> my{{{compareWithProperties.name}}} = {{{compareWithProperties.getter}}}; + Optional<{{{compareWithProperties.type}}}> compare{{{compareWithProperties.name}}} = o.{{{compareWithProperties.getter}}}; + retval = compareOptional(my{{{compareWithProperties.name}}}, compare{{{compareWithProperties.name}}}); + if (retval != 0) { + return retval; + } + {{/compareProperties}} + return retval; + } + {{/compareUsingProperties}} + + @Override + public String toString() { + {{^usePropertiesForToString}} + return "{{{name}}}: "+getObjectUri(); + {{/usePropertiesForToString}} + {{#usePropertiesForToString}} + try { + StringBuilder sb = new StringBuilder(); + {{#toStringProperties}} + Optional<{{{toStringProperties.type}}}> {{{toStringProperties.name}}} = {{{toStringProperties.getter}}}; + if ({{{toStringProperties.name}}}.isPresent()) { + sb.append({{{toStringProperties.name}}}.get().toString()); + } else { + sb.append("{{{toStringProperties.type}}}-Missing"); + } + sb.append(" "); + {{/toStringProperties}} + sb.setLenght(sb.length() == 0 ? 0 : sb.length()-1); + return sb.toString(); + } catch (InvalidSPDXAnalysisException e) { + logger.error("Error in toString: ",e); + return "Error: "+e.getMessage(); + } + {{/usePropertiesForToString}} + } +} diff --git a/resources/javaTemplates/SpdxConstants.txt b/resources/javaTemplates/SpdxConstants.txt new file mode 100644 index 0000000..a95bca7 --- /dev/null +++ b/resources/javaTemplates/SpdxConstants.txt @@ -0,0 +1,460 @@ +/** + * Copyright (c) 2023 Source Auditor Inc. + * + * 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 + * + * http://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. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.spdx.library; + +import org.spdx.storage.PropertyDescriptor; + +/** + * Constants which map to the SPDX specifications + * @author Gary O'Neall + * + */ +public class SpdxConstants { + + public enum SpdxMajorVersion { + VERSION_1, + VERSION_2, + VERSION_3; + + public static SpdxMajorVersion latestVersion() { + return VERSION_3; + } + } + + /** + * Core namespace + */ + public static final String CORE_NAMESPACE = "https://rdf.spdx.org/v3/Core"; + public static final PropertyDescriptor CORE_PROP_RELATED_SPDX_ELEMENT = new PropertyDescriptor("to", CORE_NAMESPACE); + +} + + +/** + * Copyright (c) 2011 Source Auditor Inc. + * + * 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 + * + * http://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. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.spdx.library; + +import java.util.regex.Pattern; + +import org.spdx.storage.PropertyDescriptor; + + +/** + * Constants which map to the SPDX specifications for versions prior to SPDX Spec version 3.0 + * @author Gary O'Neall + * + */ +public class SpdxConstantsCompatV2 { + + public static final String SPDX_VERSION_2 = "2"; + + // Namespaces + public static final String RDF_NAMESPACE = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"; + public static final String RDFS_NAMESPACE = "http://www.w3.org/2000/01/rdf-schema#"; + public static final String SPDX_NAMESPACE = "http://spdx.org/rdf/terms#"; + public static final String DOAP_NAMESPACE = "http://usefulinc.com/ns/doap#"; + public static final String OWL_NAMESPACE = "http://www.w3.org/2002/07/owl#"; + public static final String RDF_POINTER_NAMESPACE = "http://www.w3.org/2009/pointers#"; + public static final String XML_SCHEMA_NAMESPACE = "http://www.w3.org/2001/XMLSchema#"; + + // RDF Properties - within the RDF_NAMESPACE + public static final PropertyDescriptor RDF_PROP_TYPE = new PropertyDescriptor("type", RDF_NAMESPACE); + public static final PropertyDescriptor RDF_PROP_RESOURCE = new PropertyDescriptor("resource", RDF_NAMESPACE); + public static final String[] RDF_PROPERTIES = new String[] {RDF_PROP_TYPE.getName(), RDF_PROP_RESOURCE.getName()}; + + + // OWL Properties - within the OWL_NAMESPACE + public static final PropertyDescriptor PROP_OWL_SAME_AS = new PropertyDescriptor("sameAs", OWL_NAMESPACE); + public static final String[] OWL_PROPERTIES = new String[] {PROP_OWL_SAME_AS.getName()}; + + // RDFS Properties - within the RDFS_NAMESPACE + public static final PropertyDescriptor RDFS_PROP_COMMENT = new PropertyDescriptor("comment", RDFS_NAMESPACE); + public static final PropertyDescriptor RDFS_PROP_LABEL = new PropertyDescriptor("label", RDFS_NAMESPACE); + public static final PropertyDescriptor RDFS_PROP_SEE_ALSO = new PropertyDescriptor("seeAlso", RDFS_NAMESPACE); + public static final String[] RDFS_PROPERTIES = new String[] {RDFS_PROP_COMMENT.getName(), + RDFS_PROP_LABEL.getName(), RDFS_PROP_SEE_ALSO.getName()}; + + // DOAP Class Names - within the DOAP_NAMESPACE + public static final String CLASS_DOAP_PROJECT = "Project"; + public static final String[] DOAP_CLASSES = {CLASS_DOAP_PROJECT}; + + // DOAP Project Property Names - within the DOAP_NAMESPACE + public static final PropertyDescriptor PROP_PROJECT_HOMEPAGE = new PropertyDescriptor("homepage", DOAP_NAMESPACE); + public static final String[] DOAP_PROPERTIES = new String[] {PROP_PROJECT_HOMEPAGE.getName()}; + + // Pointer Class Names - with in the RDF_POINTER_NAMESPACE + public static final String CLASS_POINTER_START_END_POINTER = "StartEndPointer"; + public static final String CLASS_POINTER_BYTE_OFFSET_POINTER = "ByteOffsetPointer"; + public static final String CLASS_POINTER_LINE_CHAR_POINTER = "LineCharPointer"; + public static final String CLASS_POINTER_COMPOUNT_POINTER = "CompoundPointer"; + public static final String CLASS_SINGLE_POINTER = "SinglePointer"; + public static final String[] POINTER_CLASSES = new String[] { + CLASS_POINTER_START_END_POINTER, CLASS_POINTER_BYTE_OFFSET_POINTER, + CLASS_POINTER_LINE_CHAR_POINTER, CLASS_POINTER_COMPOUNT_POINTER, CLASS_SINGLE_POINTER + }; + + // Pointer Properties - with in the RDF_POINTER_NAMESPACE + public static final PropertyDescriptor PROP_POINTER_START_POINTER = new PropertyDescriptor("startPointer", RDF_POINTER_NAMESPACE); + public static final PropertyDescriptor PROP_POINTER_END_POINTER = new PropertyDescriptor("endPointer", RDF_POINTER_NAMESPACE); + public static final PropertyDescriptor PROP_POINTER_REFERENCE = new PropertyDescriptor("reference", RDF_POINTER_NAMESPACE); + public static final PropertyDescriptor PROP_POINTER_OFFSET = new PropertyDescriptor("offset", RDF_POINTER_NAMESPACE); + public static final PropertyDescriptor PROP_POINTER_LINE_NUMBER = new PropertyDescriptor("lineNumber", RDF_POINTER_NAMESPACE); + public static final String[] POINTER_PROPERTIES = new String[] { + PROP_POINTER_START_POINTER.getName(), PROP_POINTER_END_POINTER.getName(), + PROP_POINTER_REFERENCE.getName(), PROP_POINTER_OFFSET.getName(), + PROP_POINTER_LINE_NUMBER.getName() + }; + + // SPDX Class Names + public static final String CLASS_SPDX_DOCUMENT = "SpdxDocument"; + public static final String CLASS_SPDX_PACKAGE = "Package"; + public static final String CLASS_SPDX_CREATION_INFO = "CreationInfo"; + public static final String CLASS_SPDX_CHECKSUM = "Checksum"; + public static final String CLASS_SPDX_ANY_LICENSE_INFO = "AnyLicenseInfo"; + public static final String CLASS_SPDX_SIMPLE_LICENSE_INFO = "SimpleLicensingInfo"; + public static final String CLASS_SPDX_CONJUNCTIVE_LICENSE_SET = "ConjunctiveLicenseSet"; + public static final String CLASS_SPDX_DISJUNCTIVE_LICENSE_SET = "DisjunctiveLicenseSet"; + public static final String CLASS_SPDX_EXTRACTED_LICENSING_INFO = "ExtractedLicensingInfo"; + public static final String CLASS_SPDX_LICENSE = "License"; + public static final String CLASS_SPDX_LISTED_LICENSE = "ListedLicense"; + public static final String CLASS_SPDX_LICENSE_EXCEPTION = "LicenseException"; + public static final String CLASS_SPDX_LISTED_LICENSE_EXCEPTION = "ListedLicenseException"; + public static final String CLASS_OR_LATER_OPERATOR = "OrLaterOperator"; + public static final String CLASS_WITH_EXCEPTION_OPERATOR = "WithExceptionOperator"; + public static final String CLASS_SPDX_FILE = "File"; + public static final String CLASS_SPDX_REVIEW = "Review"; + public static final String CLASS_SPDX_VERIFICATIONCODE = "PackageVerificationCode"; + public static final String CLASS_ANNOTATION = "Annotation"; + public static final String CLASS_RELATIONSHIP = "Relationship"; + public static final String CLASS_SPDX_ITEM = "SpdxItem"; + public static final String CLASS_SPDX_ELEMENT = "SpdxElement"; + public static final String CLASS_SPDX_NONE_ELEMENT = "SpdxNoneElement"; + public static final String CLASS_SPDX_NOASSERTION_ELEMENT = "SpdxNoAssertionElement"; + public static final String CLASS_EXTERNAL_DOC_REF = "ExternalDocumentRef"; + public static final String CLASS_SPDX_EXTERNAL_REFERENCE = "ExternalRef"; + public static final String CLASS_SPDX_REFERENCE_TYPE = "ReferenceType"; + public static final String CLASS_SPDX_SNIPPET = "Snippet"; + public static final String CLASS_NONE_LICENSE = "SpdxNoneLicense"; + public static final String CLASS_NOASSERTION_LICENSE = "SpdxNoAssertionLicense"; + public static final String CLASS_EXTERNAL_SPDX_ELEMENT = "ExternalSpdxElement"; + public static final String CLASS_EXTERNAL_EXTRACTED_LICENSE = "ExternalExtractedLicenseInfo"; + public static final String CLASS_CROSS_REF = "CrossRef"; + + // all classes used including classes in non-SPDX namespaces + public static final String[] ALL_SPDX_CLASSES = {CLASS_SPDX_DOCUMENT, CLASS_SPDX_PACKAGE, + CLASS_SPDX_CREATION_INFO, CLASS_SPDX_CHECKSUM, CLASS_SPDX_ANY_LICENSE_INFO, + CLASS_SPDX_SIMPLE_LICENSE_INFO, CLASS_SPDX_CONJUNCTIVE_LICENSE_SET, CLASS_SPDX_DISJUNCTIVE_LICENSE_SET, + CLASS_SPDX_EXTRACTED_LICENSING_INFO, CLASS_SPDX_LICENSE, CLASS_SPDX_LISTED_LICENSE, + CLASS_SPDX_LICENSE_EXCEPTION, CLASS_SPDX_LISTED_LICENSE_EXCEPTION, CLASS_OR_LATER_OPERATOR, CLASS_WITH_EXCEPTION_OPERATOR, + CLASS_SPDX_FILE, CLASS_SPDX_REVIEW, CLASS_SPDX_VERIFICATIONCODE, CLASS_ANNOTATION, + CLASS_RELATIONSHIP, CLASS_SPDX_ITEM, CLASS_SPDX_ELEMENT, + CLASS_SPDX_NONE_ELEMENT, CLASS_SPDX_NOASSERTION_ELEMENT, CLASS_EXTERNAL_DOC_REF, + CLASS_SPDX_EXTERNAL_REFERENCE, CLASS_SPDX_REFERENCE_TYPE, CLASS_SPDX_SNIPPET, + CLASS_NONE_LICENSE, CLASS_NOASSERTION_LICENSE, CLASS_EXTERNAL_SPDX_ELEMENT, + CLASS_EXTERNAL_EXTRACTED_LICENSE, CLASS_CROSS_REF, + // DOAP Namespace + CLASS_DOAP_PROJECT, + // RDF Pointer Namespace + CLASS_POINTER_START_END_POINTER, CLASS_POINTER_BYTE_OFFSET_POINTER, + CLASS_POINTER_COMPOUNT_POINTER, CLASS_POINTER_LINE_CHAR_POINTER, CLASS_SINGLE_POINTER}; + + // classes that use the listed license URI for their namespace + public static final String[] LISTED_LICENSE_URI_CLASSES = {CLASS_SPDX_LISTED_LICENSE, CLASS_SPDX_LISTED_LICENSE_EXCEPTION}; + + // Enumeration class names + public static final String ENUM_FILE_TYPE = "FileType"; + public static final String ENUM_ANNOTATION_TYPE = "AnnotationType"; + public static final String ENUM_CHECKSUM_ALGORITHM_TYPE = "ChecksumAlgorithm"; + public static final String ENUM_REFERENCE_CATEGORY_TYPE = "ReferenceCategory"; + public static final String ENUM_REFERENCE_RELATIONSHIP_TYPE = "RelationshipType"; + public static final String ENUM_PURPOSE = "Purpose"; + // General SPDX Properties + public static final PropertyDescriptor PROP_VALUE_NONE = new PropertyDescriptor("none", SPDX_NAMESPACE); + public static final String URI_VALUE_NONE = PROP_VALUE_NONE.toString(); + public static final PropertyDescriptor PROP_VALUE_NOASSERTION = new PropertyDescriptor("noassertion", SPDX_NAMESPACE); + public static final String URI_VALUE_NOASSERTION = PROP_VALUE_NOASSERTION.toString(); + public static final String SPDX_IDENTIFIER = "SPDXID"; + public static final String EXTERNAL_DOCUMENT_REF_IDENTIFIER = "externalDocumentId"; + + // SPDX Document Properties + // The comment property is the RDFS_PROP_COMMENT property in the rdfs namespace + public static final PropertyDescriptor PROP_SPDX_REVIEWED_BY = new PropertyDescriptor("reviewed", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_SPDX_EXTRACTED_LICENSES = new PropertyDescriptor("hasExtractedLicensingInfo", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_SPDX_VERSION = new PropertyDescriptor("specVersion", SPDX_NAMESPACE); // TODO: Migrate this to PROP_SPDX_SPEC_VERSION in 3.0. See issue + public static final PropertyDescriptor PROP_SPDX_SPEC_VERSION = new PropertyDescriptor("spdxVersion", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_SPDX_CREATION_INFO = new PropertyDescriptor("creationInfo", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_SPDX_PACKAGE = new PropertyDescriptor("describesPackage", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_SPDX_DATA_LICENSE = new PropertyDescriptor("dataLicense", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_SPDX_EXTERNAL_DOC_REF = new PropertyDescriptor("externalDocumentRef", SPDX_NAMESPACE); + public static final String SPDX_DOCUMENT_ID = "SPDXRef-DOCUMENT"; + public static final PropertyDescriptor PROP_DOCUMENT_NAMESPACE = new PropertyDescriptor("documentNamespace", SPDX_NAMESPACE); + + // SPDX Document properties for JSON and YAML files + public static final PropertyDescriptor PROP_DOCUMENT_DESCRIBES = new PropertyDescriptor("documentDescribes", SPDX_NAMESPACE); //TODO: This is not yet approved in the spec - see issue # + public static final PropertyDescriptor PROP_DOCUMENT_FILES = new PropertyDescriptor("files", SPDX_NAMESPACE); //TODO: This is not yet approved in the spec - see issue # + public static final PropertyDescriptor PROP_DOCUMENT_PACKAGES = new PropertyDescriptor("packages", SPDX_NAMESPACE); //TODO: This is not yet approved in the spec - see issue # + public static final PropertyDescriptor PROP_DOCUMENT_SNIPPETS = new PropertyDescriptor("snippets", SPDX_NAMESPACE); //TODO: This is not yet approved in the spec - see issue # + public static final PropertyDescriptor PROP_DOCUMENT_RELATIONSHIPS = new PropertyDescriptor("relationships", SPDX_NAMESPACE); //TODO: This is not yet approved in the spec - see issue # + + // SPDX CreationInfo Properties + // The comment property is the RDFS_PROP_COMMENT property in the rdfs namespace + public static final PropertyDescriptor PROP_CREATION_CREATOR = new PropertyDescriptor("creator", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_CREATION_CREATED = new PropertyDescriptor("created", SPDX_NAMESPACE); // creation timestamp + public static final PropertyDescriptor PROP_LICENSE_LIST_VERSION = new PropertyDescriptor("licenseListVersion", SPDX_NAMESPACE); + public static final String CREATOR_PREFIX_PERSON = "Person:"; + public static final String CREATOR_PREFIX_ORGANIZATION = "Organization:"; + public static final String CREATOR_PREFIX_TOOL = "Tool:"; + + // SPDX Checksum Properties + public static final PropertyDescriptor PROP_CHECKSUM_ALGORITHM = new PropertyDescriptor("algorithm", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_CHECKSUM_VALUE = new PropertyDescriptor("checksumValue", SPDX_NAMESPACE); + public static final String ALGORITHM_SHA1 = "SHA1"; + public static final String PROP_CHECKSUM_ALGORITHM_SHA1 = "checksumAlgorithm_sha1"; + + // SPDX PackageVerificationCode Properties + public static final PropertyDescriptor PROP_VERIFICATIONCODE_IGNORED_FILES = new PropertyDescriptor("packageVerificationCodeExcludedFile", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_VERIFICATIONCODE_VALUE = new PropertyDescriptor("packageVerificationCodeValue", SPDX_NAMESPACE); + + // SPDX Element Properties + public static final PropertyDescriptor PROP_ANNOTATION = new PropertyDescriptor("annotation", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_RELATIONSHIP = new PropertyDescriptor("relationship", SPDX_NAMESPACE); + + // SPDX Item Properties + public static final PropertyDescriptor PROP_LICENSE_CONCLUDED = new PropertyDescriptor("licenseConcluded", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_COPYRIGHT_TEXT = new PropertyDescriptor("copyrightText", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_LIC_COMMENTS = new PropertyDescriptor("licenseComments", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_LICENSE_DECLARED = new PropertyDescriptor("licenseDeclared", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_ATTRIBUTION_TEXT = new PropertyDescriptor("attributionText", SPDX_NAMESPACE); + + // SPDX Package Properties + public static final PropertyDescriptor PROP_PACKAGE_DECLARED_NAME = new PropertyDescriptor("name", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_PACKAGE_FILE_NAME = new PropertyDescriptor("packageFileName", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_PACKAGE_CHECKSUM = new PropertyDescriptor("checksum", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_PACKAGE_DOWNLOAD_URL = new PropertyDescriptor("downloadLocation", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_PACKAGE_SOURCE_INFO = new PropertyDescriptor("sourceInfo", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_PACKAGE_DECLARED_LICENSE = new PropertyDescriptor("licenseDeclared", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_PACKAGE_CONCLUDED_LICENSE = PROP_LICENSE_CONCLUDED; + public static final PropertyDescriptor PROP_PACKAGE_DECLARED_COPYRIGHT = PROP_COPYRIGHT_TEXT; + public static final PropertyDescriptor PROP_PACKAGE_SHORT_DESC = new PropertyDescriptor("summary", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_PACKAGE_DESCRIPTION = new PropertyDescriptor("description", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_PACKAGE_FILE = new PropertyDescriptor("hasFile", SPDX_NAMESPACE);; + public static final PropertyDescriptor PROP_PACKAGE_VERIFICATION_CODE = new PropertyDescriptor("packageVerificationCode", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_PACKAGE_LICENSE_INFO_FROM_FILES = new PropertyDescriptor("licenseInfoFromFiles", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_PACKAGE_LICENSE_COMMENT = new PropertyDescriptor("licenseComments", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_PACKAGE_VERSION_INFO = new PropertyDescriptor("versionInfo", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_PACKAGE_ORIGINATOR = new PropertyDescriptor("originator", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_PACKAGE_SUPPLIER = new PropertyDescriptor("supplier", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_PACKAGE_FILES_ANALYZED = new PropertyDescriptor("filesAnalyzed", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_EXTERNAL_REF = new PropertyDescriptor("externalRef", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_PRIMARY_PACKAGE_PURPOSE = new PropertyDescriptor("primaryPackagePurpose", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_BUILT_DATE = new PropertyDescriptor("builtDate", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_RELEASE_DATE = new PropertyDescriptor("releaseDate", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_VALID_UNTIL_DATE = new PropertyDescriptor("validUntilDate", SPDX_NAMESPACE); + public static final Pattern REFERENCE_TYPE_URI_PATTERN = Pattern.compile("https?://spdx.org/rdf/references/.+"); + + // SPDX License Properties + // The comment property is the RDFS_PROP_COMMENT property in the rdfs namespace + // the seeAlso property is in the RDFS_PROP_SEE_ALSO property in the rdfs namespace + public static final PropertyDescriptor PROP_LICENSE_ID = new PropertyDescriptor("licenseId", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_LICENSE_TEXT = new PropertyDescriptor("licenseText", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_LICENSE_TEXT_HTML = new PropertyDescriptor("licenseTextHtml", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_EXTRACTED_TEXT = new PropertyDescriptor("extractedText", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_LICENSE_NAME = new PropertyDescriptor("licenseName", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_STD_LICENSE_NAME_VERSION_1 = new PropertyDescriptor("licenseName", SPDX_NAMESPACE); // old property name (pre 1.1 spec) + public static final PropertyDescriptor PROP_STD_LICENSE_NAME = new PropertyDescriptor("name", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_STD_LICENSE_URL_VERSION_1 = new PropertyDescriptor("licenseSourceUrl", SPDX_NAMESPACE); // This has been replaced with the rdfs:seeAlso property + public static final PropertyDescriptor PROP_STD_LICENSE_NOTES_VERSION_1 = new PropertyDescriptor("licenseNotes", SPDX_NAMESPACE); // old property name (pre 1.1 spec) + public static final PropertyDescriptor PROP_STD_LICENSE_HEADER_VERSION_1 = new PropertyDescriptor("licenseHeader", SPDX_NAMESPACE); // old property name (pre 1.1 spec) + public static final PropertyDescriptor PROP_STD_LICENSE_NOTICE = new PropertyDescriptor("standardLicenseHeader", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_STD_LICENSE_HEADER_TEMPLATE = new PropertyDescriptor("standardLicenseHeaderTemplate", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_LICENSE_HEADER_HTML = new PropertyDescriptor("standardLicenseHeaderHtml", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_STD_LICENSE_TEMPLATE_VERSION_1 = new PropertyDescriptor("licenseTemplate", SPDX_NAMESPACE); // old property name (pre 1.2 spec) + public static final PropertyDescriptor PROP_STD_LICENSE_TEMPLATE = new PropertyDescriptor("standardLicenseTemplate", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_STD_LICENSE_OSI_APPROVED = new PropertyDescriptor("isOsiApproved", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_STD_LICENSE_FSF_LIBRE = new PropertyDescriptor("isFsfLibre", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_STD_LICENSE_OSI_APPROVED_VERSION_1 = new PropertyDescriptor("licenseOsiApproved", SPDX_NAMESPACE); // old property name (pre 1.1 spec) + public static final PropertyDescriptor PROP_LICENSE_SET_MEMEBER = new PropertyDescriptor("member", SPDX_NAMESPACE); + public static final String TERM_LICENSE_NOASSERTION = PROP_VALUE_NOASSERTION.getName(); + public static final String TERM_LICENSE_NONE = PROP_VALUE_NONE.getName(); + public static final PropertyDescriptor PROP_LICENSE_EXCEPTION_ID = new PropertyDescriptor("licenseExceptionId", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_EXAMPLE = new PropertyDescriptor("example", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_EXCEPTION_TEXT = new PropertyDescriptor("licenseExceptionText", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_EXCEPTION_TEXT_HTML = new PropertyDescriptor("exceptionTextHtml", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_EXCEPTION_TEMPLATE = new PropertyDescriptor("licenseExceptionTemplate", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_LICENSE_EXCEPTION = new PropertyDescriptor("licenseException", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_LIC_ID_DEPRECATED = new PropertyDescriptor("isDeprecatedLicenseId", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_LIC_DEPRECATED_VERSION = new PropertyDescriptor("deprecatedVersion", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_CROSS_REF = new PropertyDescriptor("crossRef", SPDX_NAMESPACE); + + // SPDX Listed License constants + public static final String LISTED_LICENSE_URL = "https://spdx.org/licenses/"; + // http rather than https since RDF depends on the exact string, + // we were not able to update the namespace variable to match the URL's. + public static final String LISTED_LICENSE_NAMESPACE_PREFIX = "http://spdx.org/licenses/"; + + // crossrefs details (crossRef) properties + public static final PropertyDescriptor PROP_CROSS_REF_IS_VALID = new PropertyDescriptor("isValid", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_CROSS_REF_WAYBACK_LINK = new PropertyDescriptor("isWayBackLink", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_CROSS_REF_MATCH = new PropertyDescriptor("match", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_CROSS_REF_URL = new PropertyDescriptor("url", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_CROSS_REF_IS_LIVE = new PropertyDescriptor("isLive", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_CROSS_REF_TIMESTAMP = new PropertyDescriptor("timestamp", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_CROSS_REF_ORDER = new PropertyDescriptor("order", SPDX_NAMESPACE); + + // SpdxElement Properties + public static final PropertyDescriptor PROP_NAME = new PropertyDescriptor("name", SPDX_NAMESPACE); + + // SPDX File Properties + // The comment property is the RDFS_PROP_COMMENT property in the rdfs namespace + public static final PropertyDescriptor PROP_FILE_NAME = new PropertyDescriptor("fileName", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_FILE_TYPE = new PropertyDescriptor("fileType", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_FILE_LICENSE = PROP_LICENSE_CONCLUDED; + public static final PropertyDescriptor PROP_FILE_COPYRIGHT = PROP_COPYRIGHT_TEXT; + public static final PropertyDescriptor PROP_FILE_CHECKSUM = new PropertyDescriptor("checksum", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_FILE_SEEN_LICENSE = new PropertyDescriptor("licenseInfoInFile", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_FILE_LIC_COMMENTS = PROP_LIC_COMMENTS; + public static final PropertyDescriptor PROP_FILE_ARTIFACTOF = new PropertyDescriptor("artifactOf", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_FILE_FILE_DEPENDENCY = new PropertyDescriptor("fileDependency", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_FILE_CONTRIBUTOR = new PropertyDescriptor("fileContributor", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_FILE_NOTICE = new PropertyDescriptor("noticeText", SPDX_NAMESPACE); + + // SPDX Snippet Properties + public static final PropertyDescriptor PROP_SNIPPET_FROM_FILE = new PropertyDescriptor("snippetFromFile", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_SNIPPET_RANGE = new PropertyDescriptor("range", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_LICENSE_INFO_FROM_SNIPPETS = new PropertyDescriptor("licenseInfoInSnippet", SPDX_NAMESPACE); + + // SPDX File Type Properties + public static final String PROP_FILE_TYPE_SOURCE = "fileType_source"; + public static final String PROP_FILE_TYPE_ARCHIVE = "fileType_archive"; + public static final String PROP_FILE_TYPE_BINARY = "fileType_binary"; + public static final String PROP_FILE_TYPE_OTHER = "fileType_other"; + + public static final String FILE_TYPE_SOURCE = "SOURCE"; + public static final String FILE_TYPE_ARCHIVE = "ARCHIVE"; + public static final String FILE_TYPE_BINARY = "BINARY"; + public static final String FILE_TYPE_OTHER = "OTHER"; + + // SPDX Annotation Properties + public static final PropertyDescriptor PROP_ANNOTATOR = new PropertyDescriptor("annotator", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_ANNOTATION_DATE = new PropertyDescriptor("annotationDate", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_ANNOTATION_TYPE = new PropertyDescriptor("annotationType", SPDX_NAMESPACE); + + // SPDX Relationship Properties + public static final PropertyDescriptor PROP_RELATED_SPDX_ELEMENT = new PropertyDescriptor("relatedSpdxElement", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_RELATIONSHIP_TYPE = new PropertyDescriptor("relationshipType", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_SPDX_ELEMENTID = new PropertyDescriptor("spdxElementId", SPDX_NAMESPACE); + + // ExternalDocumentRef properties + public static final PropertyDescriptor PROP_EXTERNAL_DOC_CHECKSUM = new PropertyDescriptor("checksum", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_EXTERNAL_SPDX_DOCUMENT = new PropertyDescriptor("spdxDocument", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_EXTERNAL_DOCUMENT_ID = new PropertyDescriptor("externalDocumentId", SPDX_NAMESPACE); + + // External Reference properties + public static final PropertyDescriptor PROP_REFERENCE_CATEGORY = new PropertyDescriptor("referenceCategory", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_REFERENCE_TYPE = new PropertyDescriptor("referenceType", SPDX_NAMESPACE); + public static final PropertyDescriptor PROP_REFERENCE_LOCATOR = new PropertyDescriptor("referenceLocator", SPDX_NAMESPACE); + + // Date format - NOTE: This format does not handle milliseconds. Use Instant.parse for full ISO 8601 parsing + public static final String SPDX_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'"; + + // license ID format + public static String NON_STD_LICENSE_ID_PRENUM = "LicenseRef-"; + public static Pattern LICENSE_ID_PATTERN_NUMERIC = + Pattern.compile(NON_STD_LICENSE_ID_PRENUM+"(\\d+)$"); // Pattern for numeric only license IDs + public static Pattern LICENSE_ID_PATTERN = Pattern.compile(NON_STD_LICENSE_ID_PRENUM+"([0-9a-zA-Z\\.\\-\\_]+)\\+?$"); + + // SPDX Element Reference format + public static String SPDX_ELEMENT_REF_PRENUM = "SPDXRef-"; + public static Pattern SPDX_ELEMENT_REF_PATTERN = Pattern.compile(SPDX_ELEMENT_REF_PRENUM+"([0-9a-zA-Z\\.\\-\\+]+)$"); + + // External Document ID format + public static String EXTERNAL_DOC_REF_PRENUM = "DocumentRef-"; + public static Pattern EXTERNAL_DOC_REF_PATTERN = Pattern.compile(EXTERNAL_DOC_REF_PRENUM+"([0-9a-zA-Z\\.\\-\\+]+)$"); + public static Pattern EXTERNAL_ELEMENT_REF_PATTERN = Pattern.compile("(.+[0-9a-zA-Z\\.\\-\\+]+):("+SPDX_ELEMENT_REF_PRENUM+"[0-9a-zA-Z\\.\\-\\+]+)$"); + public static Pattern EXTERNAL_SPDX_ELEMENT_URI_PATTERN = Pattern.compile("(.+)#("+SPDX_ELEMENT_REF_PRENUM+"[0-9a-zA-Z\\.\\-\\+]+)$"); + public static Pattern EXTERNAL_EXTRACTED_LICENSE_URI_PATTERN = Pattern.compile("(.+)#("+NON_STD_LICENSE_ID_PRENUM+"[0-9a-zA-Z\\.\\-\\+]+)$"); + public static Pattern EXTERNAL_EXTRACTED_LICENSE_PATTERN = Pattern.compile("(.+[0-9a-zA-Z\\.\\-\\+]+):("+NON_STD_LICENSE_ID_PRENUM+"[0-9a-zA-Z\\.\\-\\+]+)$"); + + // SPDX version format + public static Pattern SPDX_VERSION_PATTERN = Pattern.compile("^SPDX-(\\d+)\\.(\\d+)$"); + + // Download Location Format + private static final String SUPPORTED_DOWNLOAD_REPOS = "(git|hg|svn|bzr)"; + private static final String URL_PATTERN = "(http:\\/\\/www\\.|https:\\/\\/www\\.|http:\\/\\/|https:\\/\\/|ssh:\\/\\/|git:\\/\\/|svn:\\/\\/|sftp:\\/\\/|ftp:\\/\\/)?[a-z0-9]+([\\-\\.]{1}[a-z0-9]+){0,100}\\.[a-z]{2,5}(:[0-9]{1,5})?(\\/.*)?"; + private static final String GIT_PATTERN = "(git\\+git@[a-zA-Z0-9\\.\\-]+:[a-zA-Z0-9/\\\\.@\\-]+)"; + private static final String BAZAAR_PATTERN = "(bzr\\+lp:[a-zA-Z0-9\\.\\-]+)"; + public static final Pattern DOWNLOAD_LOCATION_PATTERN = Pattern.compile("^(NONE|NOASSERTION|(("+SUPPORTED_DOWNLOAD_REPOS+"\\+)?"+URL_PATTERN+")|"+GIT_PATTERN+"|"+BAZAAR_PATTERN+")$", Pattern.CASE_INSENSITIVE); + + // License list version Format + + public static final Pattern LICENSE_LIST_VERSION_PATTERN = Pattern.compile("^[a-zA-Z0-9]+\\.[a-zA-Z0-9]+"); + // Standard value strings + public static String NONE_VALUE = "NONE"; + public static String NOASSERTION_VALUE = "NOASSERTION"; + public static final String[] LITERAL_VALUES = new String[]{NONE_VALUE, NOASSERTION_VALUE}; + + // data license ID + public static final String SPDX_DATA_LICENSE_ID_VERSION_1_0 = "PDDL-1.0"; + public static final String SPDX_DATA_LICENSE_ID = "CC0-1.0"; + + public static final String SPDX_LISTED_REFERENCE_TYPES_PREFIX = "http://spdx.org/rdf/references/"; + + // License XML constants + public static final String LICENSEXML_URI = "http://www.spdx.org/license"; + public static final String LICENSEXML_ELEMENT_LICENSE_COLLECTION = "SPDXLicenseCollection"; + public static final String LICENSEXML_ELEMENT_LICENSE = "license"; + public static final String LICENSEXML_ELEMENT_EXCEPTION = "exception"; + public static final String LICENSEXML_ATTRIBUTE_ID = "licenseId"; + public static final String LICENSEXML_ATTRIBUTE_DEPRECATED = "isDeprecated"; + public static final String LICENSEXML_ATTRIBUTE_DEPRECATED_VERSION = "deprecatedVersion"; + public static final String LICENSEXML_ATTRIBUTE_OSI_APPROVED = "isOsiApproved"; + public static final String LICENSEXML_ATTRIBUTE_FSF_LIBRE = "isFsfLibre"; + public static final String LICENSEXML_ATTRIBUTE_NAME = "name"; + public static final String LICENSEXML_ATTRIBUTE_LIST_VERSION_ADDED = "listVersionAdded"; + public static final String LICENSEXML_ELEMENT_CROSS_REFS = "crossRefs"; + public static final String LICENSEXML_ELEMENT_CROSS_REF = "crossRef"; + public static final String LICENSEXML_ELEMENT_NOTES = "notes"; + public static final String LICENSEXML_ELEMENT_STANDARD_LICENSE_HEADER = "standardLicenseHeader"; + public static final String LICENSEXML_ELEMENT_TITLE_TEXT = "titleText"; + public static final String LICENSEXML_ELEMENT_COPYRIGHT_TEXT = "copyrightText"; + public static final String LICENSEXML_ELEMENT_BULLET = "bullet"; + public static final String LICENSEXML_ELEMENT_LIST = "list"; + public static final String LICENSEXML_ELEMENT_ITEM = "item"; + public static final String LICENSEXML_ELEMENT_PARAGRAPH = "p"; + public static final String LICENSEXML_ELEMENT_OPTIONAL = "optional"; + public static final String LICENSEXML_ELEMENT_ALT = "alt"; + public static final String LICENSEXML_ATTRIBUTE_ALT_NAME = "name"; + public static final String LICENSEXML_ATTRIBUTE_ALT_MATCH = "match"; + public static final String LICENSEXML_ELEMENT_BREAK = "br"; + public static final String LICENSEXML_ELEMENT_TEXT = "text"; + +} \ No newline at end of file diff --git a/src/main/java/org/spdx/tools/SpdxViewer.java b/src/main/java/org/spdx/tools/SpdxViewer.java index 85995ad..8451532 100644 --- a/src/main/java/org/spdx/tools/SpdxViewer.java +++ b/src/main/java/org/spdx/tools/SpdxViewer.java @@ -25,7 +25,6 @@ import org.spdx.library.InvalidSPDXAnalysisException; import org.spdx.library.model.SpdxDocument; -import org.spdx.spdxRdfStore.RdfStore; import org.spdx.storage.ISerializableModelStore; import org.spdx.tag.CommonCode; import org.spdx.tools.SpdxToolsHelper.SerFileType; diff --git a/src/main/java/org/spdx/tools/schema/OwlToJava.java b/src/main/java/org/spdx/tools/schema/OwlToJava.java new file mode 100644 index 0000000..a898032 --- /dev/null +++ b/src/main/java/org/spdx/tools/schema/OwlToJava.java @@ -0,0 +1,599 @@ +/** + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) 2023 Source Auditor Inc. + */ +package org.spdx.tools.schema; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Map.Entry; +import java.util.Set; + +import org.apache.jena.ontology.OntModel; +import org.apache.jena.ontology.DatatypeProperty; +import org.apache.jena.ontology.Individual; +import org.apache.jena.ontology.ObjectProperty; +import org.apache.jena.ontology.OntClass; +import org.apache.jena.ontology.OntProperty; +import org.apache.jena.ontology.OntResource; +import org.apache.jena.rdf.model.Resource; +import org.apache.jena.rdf.model.Statement; +import org.apache.jena.ext.com.google.common.base.Optional; +import org.apache.jena.graph.Node; +import org.apache.jena.shacl.Shapes; +import org.apache.jena.shacl.parser.Shape; +import org.spdx.library.InvalidSPDXAnalysisException; +import org.spdx.library.model.IndividualUriValue; +import org.spdx.library.model.ModelObject; +import org.spdx.library.model.Relationship; + +import com.github.mustachejava.DefaultMustacheFactory; +import com.github.mustachejava.Mustache; + +/** + * Generates Java source class files for the SPDX Java Library from the RDF Owl Document generated from the spec model + * + * @author Gary O'Neall + * + */ +public class OwlToJava { + + static final String SPDX_URI_PREFIX = "https://spdx.org/rdf/"; + static final String INDENT = "\t"; + private static final int COMMENT_LINE_LEN = 72; + private static final String BOOLEAN_TYPE = "http://www.w3.org/2001/XMLSchema#boolean"; + private static final String STRING_TYPE = "http://www.w3.org/2001/XMLSchema#string"; + private static final String ELEMENT_TYPE_URI = "https://spdx.org/rdf/Core/Element"; + private static final String ELEMENT_TYPE_ANY_LICENSE_INFO = "https://spdx.org/rdf/Licensing/AnyLicenseInfo"; + static final String TEMPLATE_CLASS_PATH = "resources" + "/" + "javaTemplates"; + static final String TEMPLATE_ROOT_PATH = "resources" + File.separator + "javaTemplates"; + private static final String JAVA_CLASS_TEMPLATE = "ModelObjectTemplate.txt"; + private static final String ENUM_CLASS_TEMPLATE = "EnumTemplate.txt"; + private static final String DATE_TIME_TYPE = "https://spdx.org/rdf/Core/DateTime"; + private static final String ANY_URI_TYPE = "http://www.w3.org/2001/XMLSchema#anyURI"; + + private static Set INTEGER_TYPES = new HashSet<>(); + static { + INTEGER_TYPES.add("http://www.w3.org/2001/XMLSchema#positiveInteger"); + INTEGER_TYPES.add("http://www.w3.org/2001/XMLSchema#decimal"); + INTEGER_TYPES.add("http://www.w3.org/2001/XMLSchema#nonNegativeInteger"); + //TODO: Add other types - needs research + } + + OntModel model = null; + Shapes shapes = null; + Map shapeMap = null; + + Set enumClassUris = new HashSet<>(); // Set of enum URI's + + /** + * Property maps mapping a property URI to a map of metadata about the property suitable for passing into Mustache templates + */ + Map> elementProperties = new HashMap<>(); + Map> anyLicenseInfoProperties = new HashMap<>(); + Map> objectProperties = new HashMap<>(); + Map> enumerationProperties = new HashMap<>(); + Map> booleanProperties = new HashMap<>(); + Map> integerProperties = new HashMap<>(); + Map> stringProperties = new HashMap<>(); + Map> objectPropertyValueCollection = new HashMap<>(); + Map> stringCollection = new HashMap<>(); + Map> objectPropertyValueSet = new HashMap<>(); + + /** + * @param model model to use to generate the java files + */ + public OwlToJava(OntModel model) { + this.model = model; + shapes = Shapes.parse(model); + shapeMap = shapes.getShapeMap(); + } + + public void generateJavaSource(File dir) throws IOException { + List allObjectProperties = model.listObjectProperties().toList(); + List allDataProperties = model.listDatatypeProperties().toList(); + List allIndividuals = model.listIndividuals().toList(); + List allClasses = model.listClasses().toList(); + collectPropertyInformation(allObjectProperties, allDataProperties, allClasses, allIndividuals); + allClasses.forEach(ontClass -> { + String comment = ontClass.getComment(null); + String classUri = ontClass.getURI(); + String name = ontClass.getLocalName(); + Shape classShape = shapeMap.get(ontClass.asNode()); + List props = new ArrayList<>(); + boolean enumeration = ontClass.isEnumeratedClass(); + ontClass.listProperties().forEach(stmt -> { + props.add(stmt); + }); + List subClasses = new ArrayList<>(); + ontClass.listSubClasses().forEach(oc -> { + subClasses.add(oc); + }); + List superClasses = new ArrayList<>(); + addAllSuperClasses(ontClass, superClasses); + List properties = ontClass.listDeclaredProperties(true).toList(); + + try { + //TODO: Handle individual classes + if (isEnumClass(ontClass)) { + generateJavaEnum(dir, classUri, name, allIndividuals, comment); + } else { + generateJavaClass(dir, classUri, name, properties, comment); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + }); + } + + /** + * Collect property information into the field maps for properties and initialize the enum classes field + * @param allObjectProperties object properties in the schema + * @param allDataProperties data properties in the schema + * @param allClasses classes in the schema + * @param allIndividuals Individuals to determine enum class types + */ + private void collectPropertyInformation( + List allObjectProperties, + List allDataProperties, List allClasses, List allIndividuals) { + + Set enumerationTypes = new HashSet<>(); + Set anyLicenseInfoTypes = new HashSet<>(); + Set elementTypes = new HashSet<>(); + + for (Individual individual:allIndividuals) { + this.enumClassUris.add(individual.getOntClass(true).getURI()); + } + allClasses.forEach(ontClass -> { + List superClasses = new ArrayList<>(); + addAllSuperClasses(ontClass, superClasses); + if (isEnumClass(ontClass)) { + enumerationTypes.add(ontClass.getURI()); + } else if (isAnyLicenseInfoClass(ontClass, superClasses)) { + anyLicenseInfoTypes.add(ontClass.getURI()); + } else if (isElementClass(ontClass, superClasses)) { + elementTypes.add(ontClass.getURI()); + } + }); + + for (ObjectProperty prop:allObjectProperties) { + OntResource rangeResource = prop.getRange(); + String rangeUri = rangeResource == null ? "" : rangeResource.getURI() == null ? "" : rangeResource.getURI(); + if (enumerationTypes.contains(rangeUri)) { + enumerationProperties.put(prop.getURI(), propertyToMustachMap(prop)); + } else if (isSet(prop)) { + objectPropertyValueSet.put(prop.getURI(), propertyToMustachMap(prop)); + } else if (isCollection(prop)) { + objectPropertyValueCollection.put(prop.getURI(), propertyToMustachMap(prop)); + } else if (anyLicenseInfoTypes.contains(rangeUri)) { + anyLicenseInfoProperties.put(prop.getURI(), propertyToMustachMap(prop)); + } else if (elementTypes.contains(rangeUri)) { + elementProperties.put(prop.getURI(), propertyToMustachMap(prop)); + } else { + objectProperties.put(prop.getURI(), propertyToMustachMap(prop)); + } + } + + for (DatatypeProperty prop:allDataProperties) { + OntResource rangeResource = prop.getRange(); + String rangeUri = rangeResource == null ? "" : rangeResource.getURI() == null ? "" : rangeResource.getURI(); + if (enumerationTypes.contains(rangeUri)) { + enumerationProperties.put(prop.getURI(), propertyToMustachMap(prop)); + } else if (BOOLEAN_TYPE.equals(rangeUri)) { + booleanProperties.put(prop.getURI(), propertyToMustachMap(prop)); + } else if (INTEGER_TYPES.contains(rangeUri)) { + integerProperties.put(prop.getURI(), propertyToMustachMap(prop)); + //TODO: Add in specific types and type checking for DATE_TIME_TYPE and ANY_URI_TYPE + } else if (STRING_TYPE.equals(rangeUri) || DATE_TIME_TYPE.equals(rangeUri) || ANY_URI_TYPE.equals(rangeUri)) { + if (isCollection(prop)) { + stringCollection.put(prop.getURI(), propertyToMustachMap(prop)); + } else { + stringProperties.put(prop.getURI(), propertyToMustachMap(prop)); + } + } else { +// throw new OwlToJavaException("Unknown data type URI "+rangeUri+" for property URI "+prop.getURI()); + int i = 0; + i++; + } + } + } + + /** + * Add super classes including transitive superclasses to the superClasses list + * @param ontClass class to add superClasses for + * @param superClasses + */ + private void addAllSuperClasses(OntClass ontClass, + List superClasses) { + ontClass.listSuperClasses().forEach(superClass -> { + superClasses.add(superClass); + addAllSuperClasses(superClass, superClasses); + }); + } + + /** + * @param prop prop to test + * @return true if the property is a collection + */ + private boolean isCollection(OntProperty prop) { + // TODO Auto-generated method stub + return false; + } + + /** + * @param prop prop to test + * @return true if the property is a set + */ + private boolean isSet(OntProperty prop) { + // TODO Auto-generated method stub + return false; + } + + /** + * @param ontClass class + * @param superClasses list of all superclasses for the class + * @return true if the class is an Element or a subclass of Element + */ + private boolean isElementClass(OntClass ontClass, + List superClasses) { + if (ELEMENT_TYPE_URI.equals(ontClass.getURI())) { + return true; + } + for (OntClass superClass:superClasses) { + if (ELEMENT_TYPE_URI.equals(superClass.getURI())) { + return true; + } + } + return false; + } + + /** + * @param ontClass class + * @param superClasses list of all superclasses for the class + * @return true if the class is an AnyLicenseInfo or a subclass of AnyLicenseInfo + */ + private boolean isAnyLicenseInfoClass(OntClass ontClass, + List superClasses) { + if (ELEMENT_TYPE_ANY_LICENSE_INFO.equals(ontClass.getURI())) { + return true; + } + for (OntClass superClass:superClasses) { + if (ELEMENT_TYPE_ANY_LICENSE_INFO.equals(superClass.getURI())) { + return true; + } + } + return false; + } + + /** + * @param ontClass class + * @return true if the class is an enumeration + */ + private boolean isEnumClass(OntClass ontClass) { + if (ontClass.isEnumeratedClass()) { + return true; + } + //TODO: Switch to enums to remove this hack + List properties = ontClass.listDeclaredProperties().toList(); + for (OntProperty prop:properties) { + OntResource res = prop.getRange(); + String uri = res.getURI(); + } + return this.enumClassUris.contains(ontClass.getURI()); + } + + /** + * @param dir Directory to store the source files in + * @param classUri URI for the class + * @param name local name for the class + * @param properties properties for the class + * @param comment Description of the class + * @throws IOException + */ + private void generateJavaClass(File dir, String classUri, String name, + List properties, String comment) throws IOException { + String pkgName = uriToPkg(classUri); + File sourceFile = createJavaSourceFile(classUri, dir); + Map mustacheMap = new HashMap<>(); + mustacheMap.put("name", name); + mustacheMap.put("elementProperties", findProperties(properties, elementProperties)); + mustacheMap.put("objectProperties", findProperties(properties, objectProperties)); + mustacheMap.put("anyLicenseInfoProperties", findProperties(properties, anyLicenseInfoProperties)); + mustacheMap.put("enumerationProperties", findProperties(properties, enumerationProperties)); + mustacheMap.put("booleanProperties", findProperties(properties, booleanProperties)); + mustacheMap.put("integerProperties", findProperties(properties, integerProperties)); + mustacheMap.put("stringProperties", findProperties(properties, stringProperties)); + mustacheMap.put("objectPropertyValueCollection", findProperties(properties, objectPropertyValueCollection)); + mustacheMap.put("stringCollection", findProperties(properties, stringCollection)); + mustacheMap.put("objectPropertyValueSet", findProperties(properties, objectPropertyValueSet)); + mustacheMap.put("year", "2023"); // TODO - use actual year + mustacheMap.put("pkgName", pkgName); + List imports = buildImports(); + mustacheMap.put("imports", imports.toArray(new String[imports.size()])); + mustacheMap.put("classComments", toClassComment(comment)); + String superClass = getSuperClass(); + mustacheMap.put("superClass", superClass); + mustacheMap.put("verifySuperclass", superClass != "ModelObject"); + //TODO: Implement + mustacheMap.put("compareUsingProperties", false); // use properties to implement compareTo + mustacheMap.put("compareProperties", new ArrayList>()); // List of property mustache maps to use in compare + //TODO: Implement + mustacheMap.put("usePropertiesForToString", false); // use properties to implement toString + mustacheMap.put("toStringProperties", new ArrayList>()); // List of property mustache maps to use in compare + //TODO: Figure out how to handle version specific verify + + String templateDirName = TEMPLATE_ROOT_PATH; + File templateDirectoryRoot = new File(templateDirName); + if (!(templateDirectoryRoot.exists() && templateDirectoryRoot.isDirectory())) { + templateDirName = TEMPLATE_CLASS_PATH; + } + DefaultMustacheFactory builder = new DefaultMustacheFactory(templateDirName); + Mustache mustache = builder.compile(JAVA_CLASS_TEMPLATE); + FileOutputStream stream = null; + OutputStreamWriter writer = null; + try { + stream = new FileOutputStream(sourceFile); + writer = new OutputStreamWriter(stream, "UTF-8"); + mustache.execute(writer, mustacheMap); + } finally { + if (writer != null) { + writer.close(); + } + if (stream != null) { + stream.close(); + } + } + } + + + /** + * @param properties direct ontology properties + * @param propertyMap map of property URI's to map of mustache strings to properties for any properties returning a type of Element + * @return map of mustache strings to properties for any properties returning a type of Element + */ + private List> findProperties( + List properties, + Map> propertyMap) { + List> retval = new ArrayList<>(); + for (OntProperty property:properties) { + if (propertyMap.containsKey(property.getURI())) { + retval.add(propertyMap.get(property.getURI())); + } + } + return retval; + } + + /** + * @param property + * @return map of Mustache strings to values for a give ontology property + */ + private Map propertyToMustachMap(OntProperty property) { + //TODO: Implement + Map retval = new HashMap<>(); + retval.put("type", "NOT IMPLEMENTED"); + retval.put("name", "NOT IMPLEMENTED"); + retval.put("getter", "NOT IMPLEMENTED"); + retval.put("setter", "NOT IMPLEMENTED"); + retval.put("required", true); + retval.put("requiredProfiles", "NOT IMPLEMENTED"); + retval.put("pattern", "NOT IMPLEMENTED"); + retval.put("min", "NOT IMPLEMENTED"); + retval.put("max", "NOT IMPLEMENTED"); + retval.put("uri", property.getURI()); + retval.put("propertyConstant", "NOT IMPLEMENTED"); + return retval; + } + + /** + * @param property + * @return + */ + private boolean isElementProperty(OntProperty property) { + // TODO Implement + return true; + } + + /** + * @return superClass for the class + */ + private String getSuperClass() { + // TODO Implement + return "SUPERCLASS NOT IMPLEMENTED"; + } + + /** + * @return a list of import statements appropriate for the class + */ + private List buildImports() { + List retval = new ArrayList<>(); + retval.add("import java.util.ArrayList;"); + retval.add("import java.util.List;"); + retval.add("import java.util.Set;"); + retval.add(""); + retval.add("import org.spdx.library.InvalidSPDXAnalysisException;"); + retval.add("import org.spdx.library.ModelCopyManager;"); + retval.add("import org.spdx.storage.IModelStore;"); + retval.add("IMPORTS NOT COMPLETELY IMPLEMENTED"); + //TODO: Implement + + + return retval; + } + + /** + * @param dir Directory to store the source files in + * @param classUri URI for the class + * @param name local name for the class + * @param properties properties for the class + * @param comment Description of the class + * @throws IOException + */ + private void generateUnitTest(File dir, String classUri, String name, + List properties, String comment) throws IOException { + //TODO: Implement + } + + + /** + * @param dir Directory to store the source files in + * @param classUri URI for the enum + * @param name local name for the enum + * @param allIndividuals individual values from the model + * @param comment Description of the enum + * @throws IOException + */ + private void generateJavaEnum(File dir, String classUri, String name, + List allIndividuals, String comment) throws IOException { + Map mustacheMap = new HashMap<>(); + mustacheMap.put("year", "2023"); // TODO: Implement the actual year + mustacheMap.put("pkgName", uriToPkg(classUri)); + mustacheMap.put("classComment", toClassComment(comment)); + mustacheMap.put("name", name); + mustacheMap.put("classUri", classUri); + List enumValues = new ArrayList<>(); + String lastEnumValue = null; + for (Individual individual:allIndividuals) { + if (individual.hasRDFType(classUri)) { + StringBuilder enumName = new StringBuilder(); + String localName = individual.getLocalName(); + for (int i = 0; i < localName.length(); i++) { + char ch = localName.charAt(i); + if (!Character.isLowerCase(ch)) { + enumName.append('_'); + } + if (ch == '-') { + enumName.append('_'); + } else { + enumName.append(Character.toUpperCase(ch)); + } + } + if (Objects.nonNull(lastEnumValue)) { + enumValues.add(lastEnumValue + ","); + } + lastEnumValue = enumName.toString() + "(\"" + individual.getLocalName() + "\")"; + } + } + if (Objects.nonNull(lastEnumValue)) { + enumValues.add(lastEnumValue + ";"); + } + mustacheMap.put("enumValues", enumValues); + File sourceFile = createJavaSourceFile(classUri, dir); + + String templateDirName = TEMPLATE_ROOT_PATH; + File templateDirectoryRoot = new File(templateDirName); + if (!(templateDirectoryRoot.exists() && templateDirectoryRoot.isDirectory())) { + templateDirName = TEMPLATE_CLASS_PATH; + } + DefaultMustacheFactory builder = new DefaultMustacheFactory(templateDirName); + Mustache mustache = builder.compile(ENUM_CLASS_TEMPLATE); + FileOutputStream stream = null; + OutputStreamWriter writer = null; + try { + stream = new FileOutputStream(sourceFile); + writer = new OutputStreamWriter(stream, "UTF-8"); + mustache.execute(writer, mustacheMap); + } finally { + if (writer != null) { + writer.close(); + } + if (stream != null) { + stream.close(); + } + } + } + + /** + * @param comment from model documentation + * @return text formatted for a class comment + */ + private String toClassComment(String comment) { + StringBuilder sb = new StringBuilder("/**\n"); + sb.append(" * DO NOT EDIT - this file is generated by the Owl to Java Utility \n"); + sb.append(" * See: https://github.com/spdx/tools-java \n"); + sb.append(" * \n"); + String[] tokens = comment.split("\\s+"); + int i = 0; + while (i < tokens.length) { + int len = 4; + sb.append(" * "); + while (len < COMMENT_LINE_LEN && i < tokens.length) { + len += tokens[i].length(); + sb.append(tokens[i++].trim()); + sb.append(' '); + } + sb.append("\n"); + } + sb.append(" */"); + return sb.toString(); + } + + /** + * @param enumToModelName entry mapping an enum value to the model name + * @param writer + */ + private void writeEnumEntry(Entry enumToModelName, PrintWriter writer) { + writer.write(enumToModelName.getKey()); + writer.write("(\""); + writer.write(enumToModelName.getValue()); + writer.write("\")"); + } + + /** + * @param writer + */ + private void writeFileHeader(PrintWriter writer) { + writer.println("/**"); + writer.println(" * Copyright (c) 2019 Source Auditor Inc."); + writer.println(""); + writer.println(" * SPDX-License-Identifier: Apache-2.0"); + writer.println(""); + writer.println(" */"); + } + + /** + * @param classUri URI for the class + * @param dir directory to hold the file + * @return the created file + * @throws IOException + */ + private File createJavaSourceFile(String classUri, File dir) throws IOException { + Path path = dir.toPath().resolve("src").resolve("main").resolve("java").resolve("org") + .resolve("spdx").resolve("library").resolve("model"); + String[] parts = classUri.substring(SPDX_URI_PREFIX.length()).split("/"); + for (int i = 0; i < parts.length-1; i++) { + path = path.resolve(parts[i]); + } + Files.createDirectories(path); + File retval = path.resolve(parts[parts.length-1] + ".java").toFile(); + retval.createNewFile(); + return retval; + } + + /** + * @param classUri + * @return + */ + private String uriToPkg(String classUri) { + String[] parts = classUri.substring(SPDX_URI_PREFIX.length()).split("/"); + StringBuilder sb = new StringBuilder("org.spdx.library"); + for (String part:parts) { + sb.append("."); + sb.append(part.toLowerCase()); + } + return sb.toString(); + } + +} diff --git a/src/test/java/org/spdx/tools/schema/OwlToJavaTest.java b/src/test/java/org/spdx/tools/schema/OwlToJavaTest.java new file mode 100644 index 0000000..7dcae4b --- /dev/null +++ b/src/test/java/org/spdx/tools/schema/OwlToJavaTest.java @@ -0,0 +1,80 @@ +/** + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) 2023 Source Auditor Inc. + */ +package org.spdx.tools.schema; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Objects; + +import org.apache.jena.ontology.OntModel; +import org.apache.jena.ontology.OntModelSpec; +import org.apache.jena.rdf.model.ModelFactory; +import org.apache.ws.commons.schema.XmlSchemaSerializer.XmlSchemaSerializerException; + +import junit.framework.TestCase; + +/** + * @author gary + * + */ +public class OwlToJavaTest extends TestCase { + + static final String MODEL_FILE_PATH = "testResources" + File.separator + "model.ttl"; + + protected void setUp() throws Exception { + super.setUp(); + } + + protected void tearDown() throws Exception { + super.tearDown(); + } + + public void testConvertToJava() throws IOException, XmlSchemaSerializerException, SchemaException { + OwlToJava otj = null; + File tempDir = Files.createTempDirectory("spdx_test").toFile(); + try { + try (InputStream is = new FileInputStream(new File(MODEL_FILE_PATH))) { + OntModel model = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM); + model.read(is, "", "Turtle"); + otj = new OwlToJava(model); + otj.generateJavaSource(tempDir); + Path aIPath = tempDir.toPath().resolve("src") + .resolve("main") + .resolve("java") + .resolve("org") + .resolve("spdx") + .resolve("library") + .resolve("model") + .resolve("AI"); + File classFile = aIPath.resolve("AIPackage.java").toFile(); + File enumFile = aIPath.resolve("PresenceType.java").toFile(); + assertTrue(classFile.exists()); + assertTrue(classFile.isFile()); + assertTrue(enumFile.exists()); + assertTrue(enumFile.isFile()); + } + } finally { + assertTrue(deleteDirectory(tempDir)); + } + } + + /** + * @param tempDir + */ + private boolean deleteDirectory(File tempDir) { + File[] files = tempDir.listFiles(); + if (Objects.nonNull(files)) { + for (File file:files) { + deleteDirectory(file); + } + } + return tempDir.delete(); + } + +} diff --git a/testResources/model.ttl b/testResources/model.ttl new file mode 100644 index 0000000..6d4ec0b --- /dev/null +++ b/testResources/model.ttl @@ -0,0 +1,3701 @@ +@prefix ai: . +@prefix build: . +@prefix core: . +@prefix dataset: . +@prefix expandedlicense: . +@prefix licensing: . +@prefix ns0: . +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix security: . +@prefix sh: . +@prefix software: . +@prefix xsd: . + + a owl:NamedIndividual, + ai:PresenceType . + + a owl:NamedIndividual, + ai:PresenceType . + + a owl:NamedIndividual, + ai:PresenceType . + + a owl:NamedIndividual, + ai:SafetyRiskAssessmentType . + + a owl:NamedIndividual, + ai:SafetyRiskAssessmentType . + + a owl:NamedIndividual, + ai:SafetyRiskAssessmentType . + + a owl:NamedIndividual, + ai:SafetyRiskAssessmentType . + + a owl:NamedIndividual, + core:AnnotationType . + + a owl:NamedIndividual, + core:AnnotationType . + + a owl:NamedIndividual, + core:ExternalIdentifierType . + + a owl:NamedIndividual, + core:ExternalIdentifierType . + + a owl:NamedIndividual, + core:ExternalIdentifierType . + + a owl:NamedIndividual, + core:ExternalIdentifierType . + + a owl:NamedIndividual, + core:ExternalIdentifierType . + + a owl:NamedIndividual, + core:ExternalIdentifierType . + + a owl:NamedIndividual, + core:ExternalIdentifierType . + + a owl:NamedIndividual, + core:ExternalIdentifierType . + + a owl:NamedIndividual, + core:ExternalIdentifierType . + + a owl:NamedIndividual, + core:ExternalIdentifierType . + + a owl:NamedIndividual, + core:ExternalIdentifierType . + + a owl:NamedIndividual, + core:ExternalReferenceType . + + a owl:NamedIndividual, + core:ExternalReferenceType . + + a owl:NamedIndividual, + core:ExternalReferenceType . + + a owl:NamedIndividual, + core:ExternalReferenceType . + + a owl:NamedIndividual, + core:ExternalReferenceType . + + a owl:NamedIndividual, + core:ExternalReferenceType . + + a owl:NamedIndividual, + core:ExternalReferenceType . + + a owl:NamedIndividual, + core:ExternalReferenceType . + + a owl:NamedIndividual, + core:ExternalReferenceType . + + a owl:NamedIndividual, + core:ExternalReferenceType . + + a owl:NamedIndividual, + core:ExternalReferenceType . + + a owl:NamedIndividual, + core:ExternalReferenceType . + + a owl:NamedIndividual, + core:ExternalReferenceType . + + a owl:NamedIndividual, + core:ExternalReferenceType . + + a owl:NamedIndividual, + core:ExternalReferenceType . + + a owl:NamedIndividual, + core:ExternalReferenceType . + + a owl:NamedIndividual, + core:ExternalReferenceType . + + a owl:NamedIndividual, + core:ExternalReferenceType . + + a owl:NamedIndividual, + core:ExternalReferenceType . + + a owl:NamedIndividual, + core:ExternalReferenceType . + + a owl:NamedIndividual, + core:ExternalReferenceType . + + a owl:NamedIndividual, + core:ExternalReferenceType . + + a owl:NamedIndividual, + core:ExternalReferenceType . + + a owl:NamedIndividual, + core:ExternalReferenceType . + + a owl:NamedIndividual, + core:ExternalReferenceType . + + a owl:NamedIndividual, + core:ExternalReferenceType . + + a owl:NamedIndividual, + core:ExternalReferenceType . + + a owl:NamedIndividual, + core:ExternalReferenceType . + + a owl:NamedIndividual, + core:ExternalReferenceType . + + a owl:NamedIndividual, + core:ExternalReferenceType . + + a owl:NamedIndividual, + core:ExternalReferenceType . + + a owl:NamedIndividual, + core:ExternalReferenceType . + + a owl:NamedIndividual, + core:ExternalReferenceType . + + a owl:NamedIndividual, + core:ExternalReferenceType . + + a owl:NamedIndividual, + core:ExternalReferenceType . + + a owl:NamedIndividual, + core:ExternalReferenceType . + + a owl:NamedIndividual, + core:ExternalReferenceType . + + a owl:NamedIndividual, + core:ExternalReferenceType . + + a owl:NamedIndividual, + core:HashAlgorithm . + + a owl:NamedIndividual, + core:HashAlgorithm . + + a owl:NamedIndividual, + core:HashAlgorithm . + + a owl:NamedIndividual, + core:HashAlgorithm . + + a owl:NamedIndividual, + core:HashAlgorithm . + + a owl:NamedIndividual, + core:HashAlgorithm . + + a owl:NamedIndividual, + core:HashAlgorithm . + + a owl:NamedIndividual, + core:HashAlgorithm . + + a owl:NamedIndividual, + core:HashAlgorithm . + + a owl:NamedIndividual, + core:HashAlgorithm . + + a owl:NamedIndividual, + core:HashAlgorithm . + + a owl:NamedIndividual, + core:HashAlgorithm . + + a owl:NamedIndividual, + core:HashAlgorithm . + + a owl:NamedIndividual, + core:HashAlgorithm . + + a owl:NamedIndividual, + core:HashAlgorithm . + + a owl:NamedIndividual, + core:HashAlgorithm . + + a owl:NamedIndividual, + core:HashAlgorithm . + + a owl:NamedIndividual, + core:HashAlgorithm . + + a owl:NamedIndividual, + core:HashAlgorithm . + + a owl:NamedIndividual, + core:HashAlgorithm . + + a owl:NamedIndividual, + core:HashAlgorithm . + + a owl:NamedIndividual, + core:HashAlgorithm . + + a owl:NamedIndividual, + core:HashAlgorithm . + + a owl:NamedIndividual, + core:HashAlgorithm . + + a owl:NamedIndividual, + core:LifecycleScopeType . + + a owl:NamedIndividual, + core:LifecycleScopeType . + + a owl:NamedIndividual, + core:LifecycleScopeType . + + a owl:NamedIndividual, + core:LifecycleScopeType . + + a owl:NamedIndividual, + core:LifecycleScopeType . + + a owl:NamedIndividual, + core:LifecycleScopeType . + +core:Organization a owl:Class, + sh:NodeShape ; + rdfs:comment "An Organization is a group of people who work together in an organized way for a shared purpose." ; + rdfs:subClassOf core:Agent ; + ns0:term_status "Stable" . + +core:Person a owl:Class, + sh:NodeShape ; + rdfs:comment "A Person is an individual human being." ; + rdfs:subClassOf core:Agent ; + ns0:term_status "Stable" . + + a owl:NamedIndividual, + core:ProfileIdentifierType . + + a owl:NamedIndividual, + core:ProfileIdentifierType . + + a owl:NamedIndividual, + core:ProfileIdentifierType . + + a owl:NamedIndividual, + core:ProfileIdentifierType . + + a owl:NamedIndividual, + core:ProfileIdentifierType . + + a owl:NamedIndividual, + core:ProfileIdentifierType . + + a owl:NamedIndividual, + core:ProfileIdentifierType . + + a owl:NamedIndividual, + core:ProfileIdentifierType . + + a owl:NamedIndividual, + core:ProfileIdentifierType . + + a owl:NamedIndividual, + core:RelationshipCompleteness . + + a owl:NamedIndividual, + core:RelationshipCompleteness . + + a owl:NamedIndividual, + core:RelationshipCompleteness . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + + a owl:NamedIndividual, + core:RelationshipType . + +core:SoftwareAgent a owl:Class, + sh:NodeShape ; + rdfs:comment "A SoftwareAgent is a software program that is given the authority (similar to a user's authority) to act on a system." ; + rdfs:subClassOf core:Agent ; + ns0:term_status "Stable" . + + a owl:NamedIndividual, + dataset:ConfidentialityLevelType . + + a owl:NamedIndividual, + dataset:ConfidentialityLevelType . + + a owl:NamedIndividual, + dataset:ConfidentialityLevelType . + + a owl:NamedIndividual, + dataset:ConfidentialityLevelType . + + a owl:NamedIndividual, + dataset:DatasetAvailabilityType . + + a owl:NamedIndividual, + dataset:DatasetAvailabilityType . + + a owl:NamedIndividual, + dataset:DatasetAvailabilityType . + + a owl:NamedIndividual, + dataset:DatasetAvailabilityType . + + a owl:NamedIndividual, + dataset:DatasetAvailabilityType . + + a owl:NamedIndividual, + dataset:DatasetType . + + a owl:NamedIndividual, + dataset:DatasetType . + + a owl:NamedIndividual, + dataset:DatasetType . + + a owl:NamedIndividual, + dataset:DatasetType . + + a owl:NamedIndividual, + dataset:DatasetType . + + a owl:NamedIndividual, + dataset:DatasetType . + + a owl:NamedIndividual, + dataset:DatasetType . + + a owl:NamedIndividual, + dataset:DatasetType . + + a owl:NamedIndividual, + dataset:DatasetType . + + a owl:NamedIndividual, + dataset:DatasetType . + + a owl:NamedIndividual, + dataset:DatasetType . + + a owl:NamedIndividual, + dataset:DatasetType . + + a owl:NamedIndividual, + dataset:DatasetType . + + a owl:NamedIndividual, + dataset:DatasetType . + +expandedlicense:ExtendableLicense a owl:Class, + sh:NodeShape ; + rdfs:comment "The WithAdditionOperator can have a License or an OrLaterOperator as the license property value. This class is used for the value." ; + rdfs:subClassOf licensing:AnyLicenseInfo ; + ns0:term_status "Stable" . + +expandedlicense:subjectAddition a owl:ObjectProperty ; + rdfs:comment """A subjectAddition is a LicenseAddition which is subject to a 'with additional +text' effect (WithAdditionOperator).""" ; + rdfs:range expandedlicense:LicenseAddition ; + ns0:term_status "Stable" . + +expandedlicense:subjectLicense a owl:ObjectProperty ; + rdfs:comment """A subjectLicense is a License which is subject to either an 'or later' effect +(OrLaterOperator) or a 'with additional text' effect (WithAdditionOperator).""" ; + rdfs:range licensing:License ; + ns0:term_status "Stable" . + +licensing:CustomLicense a owl:Class, + sh:NodeShape ; + rdfs:comment """A CustomLicense represents a License that is not listed on the SPDX License +List at https://spdx.org/licenses, and is therefore defined by an SPDX data +creator.""" ; + rdfs:subClassOf licensing:License ; + ns0:term_status "Stable" . + +licensing:CustomLicenseAddition a owl:Class, + sh:NodeShape ; + rdfs:comment """A CustomLicenseAddition represents an addition to a License that is not listed +on the SPDX Exceptions List at https://spdx.org/licenses/exceptions-index.html, +and is therefore defined by an SPDX data creator. + +It is intended to represent additional language which is meant to be added to +a License, but which is not itself a standalone License.""" ; + rdfs:subClassOf licensing:LicenseAddition ; + ns0:term_status "Stable" . + +licensing:OrLaterOperator a owl:Class, + sh:NodeShape ; + rdfs:comment """An OrLaterOperator indicates that this portion of the AnyLicenseInfo +represents either (1) the specified version of the corresponding License, or +(2) any later version of that License. It is represented in the SPDX License +Expression Syntax by the `+` operator. + +It is context-dependent, and unspecified by SPDX, as to what constitutes a +"later version" of any particular License. Some Licenses may not be versioned, +or may not have clearly-defined ordering for versions. The consumer of SPDX +data will need to determine for themselves what meaning to attribute to a +"later version" operator for a particular License.""" ; + rdfs:subClassOf expandedlicense:ExtendableLicense ; + ns0:term_status "Stable" ; + sh:property [ sh:class licensing:License ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:name "subjectLicense" ; + sh:path licensing:subjectLicense ] . + +licensing:WithAdditionOperator a owl:Class, + sh:NodeShape ; + rdfs:comment """A WithAdditionOperator indicates that the designated License is subject to the +designated LicenseAddition, which might be a license exception on the SPDX +Exceptions List (ListedLicenseException) or may be other additional text +(CustomLicenseAddition). It is represented in the SPDX License Expression +Syntax by the `WITH` operator.""" ; + rdfs:subClassOf licensing:AnyLicenseInfo ; + ns0:term_status "Stable" ; + sh:property [ sh:class licensing:LicenseAddition ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:name "subjectAddition" ; + sh:path licensing:subjectAddition ], + [ sh:datatype expandedlicense:ExtendableLicense ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:name "subjectLicense" ; + sh:path licensing:subjectLicense ] . + +licensing:additionComment a owl:DatatypeProperty ; + rdfs:comment """An additionComment for a LicenseAddition describes general factual information +about the LicenseAddition. It should not contain information (or links to +information) that includes any kind of interpretation about the meaning or +effect of the License, even if written by the license addition's author. + +Examples of information for an additionComment may include the following: + +* If the LicenseAddition's identifier is deprecated, it may briefly explain the + reason for deprecation. +* It may include the date of release, if identified, for LicenseAdditions with + multiple versions. +* It may include links to other official language translations for the + LicenseAddition. +* It may include a reference to the License(s) with which this LicenseAddition + is typically used.""" ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +licensing:additionId a owl:DatatypeProperty ; + rdfs:comment """An additionId contains a human-readable, short-form identifier for a +LicenseAddition. It may only include letters, numbers, period (".") and +hyphen ("-") characters. + +For a ListedLicenseException, the licenseId will be as specified on the +[SPDX Exceptions List](https://spdx.org/licenses/exceptions-index.html) for the +particular exception. + +For a CustomLicenseAddition, the short-form identifier must begin with the +prefix `AdditionRef-` and must be unique within the applicable SPDX namespace. +The short-form identifier may be preceded by an SPDX namespace or a +fully-qualified URI prefix.""" ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +licensing:additionName a owl:DatatypeProperty ; + rdfs:comment """An additionName contains the full name of a LicenseAddition, preferably using +the title found in the applicable license addition text or file, or as +otherwise specified by the LicenseAddition's author or steward. + +When no such title is specified, using a name from another well-known source or list +of licenses additions (such as OSI or Fedora) is suggested. + +If no official or common name is known, any name may be used to aid in +distinguishing the LicenseAddition from other LicenseAdditions.""" ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +licensing:licenseComment a owl:DatatypeProperty ; + rdfs:comment """A licenseComment describes general factual information about the License. It +should not contain information (or links to information) that includes any kind +of interpretation about the meaning or effect of the License, even if written +by the license's author. + +Examples of information for a licenseComment may include the following: + +* If the License's identifier is deprecated, it may briefly explain the reason + for deprecation. +* It may include the date of release, if identified, for Licenses with multiple + versions. +* It may include links to other official language translations for the License. +* For LicenseAdditions, it may include a reference to the License(s) with + which this additional text is typically used.""" ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +licensing:licenseId a owl:DatatypeProperty ; + rdfs:comment """A licenseId contains a human-readable, short-form license identifier for a +License. It may only include letters, numbers, period (".") and hyphen ("-") +characters. + +For a ListedLicense, the licenseId will be as specified on the +[SPDX License List](https://spdx.org/licenses) for the particular license. + +For a CustomLicense, the short-form license identifer must begin with the +prefix `LicenseRef-` and must be unique within the applicable SPDX namespace. +The short-form license ID may be preceded by an SPDX namespace or a +fully-qualified URI prefix.""" ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +licensing:licenseName a owl:DatatypeProperty ; + rdfs:comment """A licenseName contains the full name of a License, preferably using the title found +in the applicable license text or file, or as otherwise specified by the +License's author or steward. + +When no such title is specified, using a name from another well-known source or list +of licenses (such as OSI or Fedora) is suggested. + +If no official or common name is known, any name may be used to aid in +distinguishing the License from other Licenses.""" ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +licensing:seeAlso a owl:DatatypeProperty ; + rdfs:comment """A seeAlso defines a cross-reference with a URL where the License or +LicenseAddition can be found in use by one or a few projects. + +If applicable, it should include a URL where the license text is posted by +the license steward, particularly if the license steward has made available a +"canonical" primary URL for the license text. + +If the license is OSI approved, a seeAlso should be included with the URL for +the license's listing on the OSI website. + +The seeAlso URL may refer to a previously-available URL for the License or +LicenseAddition which is no longer active. + +Where applicable, the seeAlso URL should include the license text in its +native language. seeAlso URLs to English or other translations may be included +where multiple, equivalent official translations exist.""" ; + rdfs:range xsd:anyURI ; + ns0:term_status "Stable" . + + a owl:NamedIndividual, + security:ExploitCatalogType . + + a owl:NamedIndividual, + security:ExploitCatalogType . + + a owl:NamedIndividual, + security:SsvcDecisionType . + + a owl:NamedIndividual, + security:SsvcDecisionType . + + a owl:NamedIndividual, + security:SsvcDecisionType . + + a owl:NamedIndividual, + security:SsvcDecisionType . + +security:VexFixedVulnAssessmentRelationship a owl:Class, + sh:NodeShape ; + rdfs:comment """VexFixedVulnAssessmentRelationship links a vulnerability to a number of elements +representing VEX products where a vulnerability has been fixed and are no longer +affected. It represents the VEX fixed status. + +**Constraints** + +When linking elements using a VexFixedVulnAssessmentRelationship, the following +requirements must be observed: + +- Elements linked with a VulnVexFixedAssessmentRelationship are constrained to +using the fixedIn relationship type. +- The from: end of the relationship must ve a /Security/Vulnerability classed +element. + +**Syntax** + +```json +{ + "@type": "VexFixedVulnAssessmentRelationship", + "@id": "urn:spdx.dev:vex-fixed-in-1", + "relationshipType": "fixedIn", + "from": "urn:spdx.dev:vuln-cve-2020-28498", + "to": ["urn:product-acme-application-1.3"], + "assessedElement": "urn:npm-elliptic-6.5.4", + "suppliedBy": ["urn:spdx.dev:agent-jane-doe"], + "publishedTime": "2021-03-09T11:04:53Z" +} +```""" ; + rdfs:subClassOf security:VexVulnAssessmentRelationship ; + ns0:term_status "Stable" . + + a owl:NamedIndividual, + security:VexJustificationType . + + a owl:NamedIndividual, + security:VexJustificationType . + + a owl:NamedIndividual, + security:VexJustificationType . + + a owl:NamedIndividual, + security:VexJustificationType . + + a owl:NamedIndividual, + security:VexJustificationType . + +security:VexUnderInvestigationVulnAssessmentRelationship a owl:Class, + sh:NodeShape ; + rdfs:comment """VexUnderInvestigationVulnAssessmentRelationship links a vulnerability to a +number of products stating the vulnerability's impact on them is being +investigated. It represents the VEX under_investigation status. + +**Constraints** + +When linking elements using a VexUnderInvestigationVulnAssessmentRelationship +the following requirements must be observed: + +- Elements linked with a VexUnderInvestigationVulnAssessmentRelationship are +constrained to using the underInvestigationFor relationship type. +- The from: end of the relationship must ve a /Security/Vulnerability classed +element. + +**Syntax** + +```json +{ + "@type": "VexUnderInvestigationVulnAssessmentRelationship", + "@id": "urn:spdx.dev:vex-underInvestigation-1", + "relationshipType": "underInvestigationFor", + "from": "urn:spdx.dev:vuln-cve-2020-28498", + "to": ["urn:product-acme-application-1.3"], + "assessedElement": "urn:npm-elliptic-6.5.2", + "suppliedBy": ["urn:spdx.dev:agent-jane-doe"], + "publishedTime": "2021-03-09T11:04:53Z" +} +```""" ; + rdfs:subClassOf security:VexVulnAssessmentRelationship ; + ns0:term_status "Stable" . + + a owl:NamedIndividual, + software:DependencyConditionalityType . + + a owl:NamedIndividual, + software:DependencyConditionalityType . + + a owl:NamedIndividual, + software:DependencyConditionalityType . + + a owl:NamedIndividual, + software:DependencyConditionalityType . + + a owl:NamedIndividual, + software:DependencyConditionalityType . + + a owl:NamedIndividual, + software:SBOMType . + + a owl:NamedIndividual, + software:SBOMType . + + a owl:NamedIndividual, + software:SBOMType . + + a owl:NamedIndividual, + software:SBOMType . + + a owl:NamedIndividual, + software:SBOMType . + + a owl:NamedIndividual, + software:SBOMType . + + a owl:NamedIndividual, + software:SoftwareDependencyLinkType . + + a owl:NamedIndividual, + software:SoftwareDependencyLinkType . + + a owl:NamedIndividual, + software:SoftwareDependencyLinkType . + + a owl:NamedIndividual, + software:SoftwareDependencyLinkType . + + a owl:NamedIndividual, + software:SoftwarePurpose . + + a owl:NamedIndividual, + software:SoftwarePurpose . + + a owl:NamedIndividual, + software:SoftwarePurpose . + + a owl:NamedIndividual, + software:SoftwarePurpose . + + a owl:NamedIndividual, + software:SoftwarePurpose . + + a owl:NamedIndividual, + software:SoftwarePurpose . + + a owl:NamedIndividual, + software:SoftwarePurpose . + + a owl:NamedIndividual, + software:SoftwarePurpose . + + a owl:NamedIndividual, + software:SoftwarePurpose . + + a owl:NamedIndividual, + software:SoftwarePurpose . + + a owl:NamedIndividual, + software:SoftwarePurpose . + + a owl:NamedIndividual, + software:SoftwarePurpose . + + a owl:NamedIndividual, + software:SoftwarePurpose . + + a owl:NamedIndividual, + software:SoftwarePurpose . + + a owl:NamedIndividual, + software:SoftwarePurpose . + + a owl:NamedIndividual, + software:SoftwarePurpose . + + a owl:NamedIndividual, + software:SoftwarePurpose . + + a owl:NamedIndividual, + software:SoftwarePurpose . + + a owl:NamedIndividual, + software:SoftwarePurpose . + + a owl:NamedIndividual, + software:SoftwarePurpose . + + a owl:NamedIndividual, + software:SoftwarePurpose . + + a owl:NamedIndividual, + software:SoftwarePurpose . + + a owl:NamedIndividual, + software:SoftwarePurpose . + + a owl:NamedIndividual, + software:SoftwarePurpose . + + a owl:NamedIndividual, + software:SoftwarePurpose . + +ai:autonomyType a owl:DatatypeProperty ; + rdfs:comment """AutonomyType indicates if a human is involved in any of the decisions of the AI software +or if that software is fully automatic.""" ; + rdfs:domain ai:AIPackage ; + rdfs:range ai:PresenceType ; + ns0:term_status "Stable" . + +ai:domain a owl:DatatypeProperty ; + rdfs:comment """Domain describes the domain in which the AI model contained in the AI software +can be expected to operate successfully. Examples include computer vision, natural language etc.""" ; + rdfs:domain ai:AIPackage ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +ai:energyConsumption a owl:DatatypeProperty ; + rdfs:comment """EnergyConsumption captures the amount of energy needed to train and operate the AI model. +This value is also known as training energy consumption or inference energy consumption.""" ; + rdfs:domain ai:AIPackage ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +ai:hyperparameter a owl:DatatypeProperty ; + rdfs:comment """This field records a hyperparameter value. +Hyperparameters are parameters of the machine learning model that are used to control the learning process, +for example the optimization and learning rate used during the training of the model.""" ; + rdfs:domain ai:AIPackage ; + rdfs:range core:DictionaryEntry ; + ns0:term_status "Stable" . + +ai:informationAboutApplication a owl:DatatypeProperty ; + rdfs:comment """InformationAboutApplication describes any relevant information in free form text about +how the AI model is used inside the software, as well as any relevant pre-processing steps, third party APIs etc.""" ; + rdfs:domain ai:AIPackage ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +ai:informationAboutTraining a owl:DatatypeProperty ; + rdfs:comment """InformationAboutTraining describes the specific steps involved in the training of the AI model. +For example, it can be specified whether supervised fine-tuning +or active learning is used as part of training the model.""" ; + rdfs:domain ai:AIPackage ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +ai:limitation a owl:DatatypeProperty ; + rdfs:comment """Limitation captures a limitation of the AI Package (or of the AI models present in the AI package), +expressed as free form text. Note that this is not guaranteed to be exhaustive. +For instance, a limitation might be that the AI package cannot be used on datasets from a certain demography.""" ; + rdfs:domain ai:AIPackage ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +ai:metric a owl:DatatypeProperty ; + rdfs:comment """Metric records the measurement with which the AI model was evaluated. +This makes statements about the prediction quality including uncertainty, +accuracy, characteristics of the tested population, quality, fairness, explainability, robustness etc.""" ; + rdfs:domain ai:AIPackage ; + rdfs:range core:DictionaryEntry ; + ns0:term_status "Stable" . + +ai:metricDecisionThreshold a owl:DatatypeProperty ; + rdfs:comment """Each metric might be computed based on a decision threshold. +For instance, precision or recall is typically computed by checking +if the probability of the outcome is larger than 0.5. +Each decision threshold should match with a metric field defined in the AI Package.""" ; + rdfs:domain ai:AIPackage ; + rdfs:range core:DictionaryEntry ; + ns0:term_status "Stable" . + +ai:modelDataPreprocessing a owl:DatatypeProperty ; + rdfs:comment """ModelDataPreprocessing is a free form text that describes the preprocessing steps +applied to the training data before training of the model(s) contained in the AI software.""" ; + rdfs:domain ai:AIPackage ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +ai:modelExplainability a owl:DatatypeProperty ; + rdfs:comment """ModelExplainability is a free form text that lists the different explainability mechanisms +(such as SHAP, or other model specific explainability mechanisms) that can be used to explain the model.""" ; + rdfs:domain ai:AIPackage ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +ai:safetyRiskAssessment a owl:DatatypeProperty ; + rdfs:comment """SafetyRiskAssessment categorizes the safety risk impact of the AI software +in accordance with Article 20 of [EC Regulation No 765/2008](https://ec.europa.eu/docsroom/documents/17107/attachments/1/translations/en/renditions/pdf).""" ; + rdfs:domain ai:AIPackage ; + rdfs:range ai:SafetyRiskAssessmentType ; + ns0:term_status "Stable" . + +ai:sensitivePersonalInformation a owl:DatatypeProperty ; + rdfs:comment """SensitivePersonalInformation notes if sensitive personal information +is used in the training or inference of the AI models. +This might include biometric data, addresses or other data that can be used to infer a person's identity.""" ; + rdfs:domain ai:AIPackage ; + rdfs:range ai:PresenceType ; + ns0:term_status "Stable" . + +ai:standardCompliance a owl:DatatypeProperty ; + rdfs:comment """StandardCompliance captures a standard that the AI software complies with. +This includes both published and unpublished standards, for example ISO, IEEE, ETSI etc. +The standard could (but not necessarily have to) be used to satisfy a legal or regulatory requirement.""" ; + rdfs:domain ai:AIPackage ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +ai:typeOfModel a owl:DatatypeProperty ; + rdfs:comment """TypeOfModel records the type of the AI model(s) used in the software. +For instance, if it is a supervised model, unsupervised model, reinforcement learning model or a combination of those.""" ; + rdfs:domain ai:AIPackage ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +build:buildEndTime a owl:DatatypeProperty ; + rdfs:comment "buildEndTime describes the time at which a build stops or finishes. This value is typically recorded by the builder." ; + rdfs:domain build:Build ; + rdfs:range core:DateTime ; + ns0:term_status "Stable" . + +build:buildId a owl:DatatypeProperty ; + rdfs:comment "A buildId is a locally unique identifier to identify a unique instance of a build. This identifier differs based on build toolchain, platform, or naming convention used by an organization or standard." ; + rdfs:domain build:Build ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +build:buildStartTime a owl:DatatypeProperty ; + rdfs:comment "buildStartTime is the time at which a build is triggered. The builder typically records this value." ; + rdfs:domain build:Build ; + rdfs:range core:DateTime ; + ns0:term_status "Stable" . + +build:buildType a owl:DatatypeProperty ; + rdfs:comment "A buildType is a URI expressing the toolchain, platform, or infrastructure that the build was invoked on. For example, if the build was invoked on GitHub's CI platform using github actions, the buildType can be expressed as `https://github.com/actions`. In contrast, if the build was invoked on a local machine, the buildType can be expressed as `file://username@host/path/to/build`." ; + rdfs:domain build:Build ; + rdfs:range xsd:anyURI ; + ns0:term_status "Stable" . + +build:configSourceDigest a owl:DatatypeProperty ; + rdfs:comment "configSourceDigest is the checksum of the build configuration file used by a builder to execute a build. This Property uses the Core model's [Hash](../../Core/Classes/Hash.md) class." ; + rdfs:domain build:Build ; + rdfs:range core:Hash ; + ns0:term_status "Stable" . + +build:configSourceEntrypoint a owl:DatatypeProperty ; + rdfs:comment """A build entrypoint is the invoked executable of a build which always runs when the build is triggered. For example, when a build is triggered by running a shell script, the entrypoint is `script.sh`. In terms of a declared build, the entrypoint is the position in a configuration file or a build declaration which is always run when the build is triggered. For example, in the following configuration file, the entrypoint of the build is `publish`. + +``` +name: Publish packages to PyPI + +on: +create: +tags: "*" + +jobs: +publish: +runs-on: ubuntu-latest +if: startsWith(github.ref, 'refs/tags/') +steps: + +... +```""" ; + rdfs:domain build:Build ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +build:configSourceUri a owl:DatatypeProperty ; + rdfs:comment """If a build configuration exists for the toolchain or platform performing the build, the configSourceUri of a build is the URI of that build configuration. For example, a build triggered by a GitHub action is defined by a build configuration YAML file. In this case, the configSourceUri is the URL of that YAML file. +m""" ; + rdfs:domain build:Build ; + rdfs:range xsd:anyURI ; + ns0:term_status "Stable" . + +build:environment a owl:DatatypeProperty ; + rdfs:comment "environment is a map of environment variables and values that are set during a build session. This is different from the [parameters](parameters.md) property in that it describes the environment variables set before a build is invoked rather than the variables provided to the builder." ; + rdfs:domain build:Build ; + rdfs:range core:DictionaryEntry ; + ns0:term_status "Stable" . + +build:parameters a owl:DatatypeProperty ; + rdfs:comment "parameters is a key-value map of all build parameters and their values that were provided to the builder for a build instance. This is different from the [environment](environment.md) property in that the keys and values are provided as command line arguments or a configuration file to the builder." ; + rdfs:domain build:Build ; + rdfs:range core:DictionaryEntry ; + ns0:term_status "Stable" . + +core:Bom a owl:Class, + sh:NodeShape ; + rdfs:comment """A Bill Of Materials (BOM) is a container for a grouping of SPDX-3.0 content +characterizing details about a product. +This could include details of the content and composition of the product, +provenence details of the product and/or +its composition, licensing information, known quality or security issues, etc.""" ; + rdfs:subClassOf core:Bundle ; + ns0:term_status "Stable" . + +core:SpdxDocument a owl:Class, + sh:NodeShape ; + rdfs:comment """An SpdxDocument assembles a collection of Elements under a common string, the name of the document. +Commonly used when representing a unit of transfer of SPDX Elements. +External property restriction on /Core/Element/name: minCount: 1""" ; + rdfs:subClassOf core:Bundle ; + ns0:term_status "Stable" ; + sh:property [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:name "name" ; + sh:path core:name ] . + +core:algorithm a owl:DatatypeProperty ; + rdfs:comment "An algorithm specifies the algorithm that was used for calculating the hash value." ; + rdfs:domain core:Hash ; + rdfs:range core:HashAlgorithm ; + ns0:term_status "Stable" . + +core:annotationType a owl:DatatypeProperty ; + rdfs:comment "An annotationType describes the type of an annotation." ; + rdfs:domain core:Annotation ; + rdfs:range core:AnnotationType ; + ns0:term_status "Stable" . + +core:begin a owl:DatatypeProperty ; + rdfs:comment "begin is a positive integer that defines the beginning of a range." ; + rdfs:domain core:PositiveIntegerRange ; + rdfs:range xsd:positiveInteger ; + ns0:term_status "Stable" . + +core:builtTime a owl:DatatypeProperty ; + rdfs:comment "A builtTime specifies the time an artifact was built." ; + rdfs:domain core:Artifact ; + rdfs:range core:DateTime ; + ns0:term_status "Stable" . + +core:completeness a owl:DatatypeProperty ; + rdfs:comment """Completeness gives information about whether the provided relationships are +complete, known to be incomplete or if no assertion is made either way.""" ; + rdfs:domain core:Relationship ; + rdfs:range core:RelationshipCompleteness ; + ns0:term_status "Stable" . + +core:context a owl:DatatypeProperty ; + rdfs:comment """A context gives information about the circumstances or unifying properties +that Elements of the bundle have been assembled under.""" ; + rdfs:domain core:Bundle ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +core:created a owl:DatatypeProperty ; + rdfs:comment """Created is a date that identifies when the Element was originally created. +The time stamp can serve as an indication as to whether the analysis needs to be updated. This is often the date of last change (e.g., a git commit date), not the date when the SPDX data was created, as doing so supports reproducible builds.""" ; + rdfs:domain core:CreationInfo ; + rdfs:range core:DateTime ; + ns0:term_status "Stable" . + +core:createdBy a owl:ObjectProperty ; + rdfs:comment """CreatedBy identifies who or what created the Element. +The generation method will assist the recipient of the Element in assessing +the general reliability/accuracy of the analysis information.""" ; + rdfs:domain core:CreationInfo ; + rdfs:range core:Agent ; + ns0:term_status "Stable" . + +core:createdUsing a owl:ObjectProperty ; + rdfs:comment """CreatedUsing identifies the tooling that was used during the creation of the Element. +The generation method will assist the recipient of the Element in assessing +the general reliability/accuracy of the analysis information.""" ; + rdfs:domain core:CreationInfo ; + rdfs:range core:Tool ; + ns0:term_status "Stable" . + +core:dataLicense a owl:DatatypeProperty ; + rdfs:comment """The data license provides the license under which the SPDX documentation of the Element can be used. +This is to alleviate any concern that content (the data or database) in an SPDX file +is subject to any form of intellectual property right that could restrict the re-use +of the information or the creation of another SPDX file for the same project(s). +This approach avoids intellectual property and related restrictions over the SPDX file, +however individuals can still contract with each other to restrict release +of specific collections of SPDX files (which map to software bill of materials) +and the identification of the supplier of SPDX files. +Compliance with this document includes populating the SPDX fields therein +with data related to such fields ("SPDX-Metadata"). +This document contains numerous fields where an SPDX file creator may provide +relevant explanatory text in SPDX-Metadata. Without opining on the lawfulness +of "database rights" (in jurisdictions where applicable), +such explanatory text is copyrightable subject matter in most Berne Convention countries. +By using the SPDX specification, or any portion hereof, +you hereby agree that any copyright rights (as determined by your jurisdiction) +in any SPDX-Metadata, including without limitation explanatory text, +shall be subject to the terms of the Creative Commons CC0 1.0 Universal license. +For SPDX-Metadata not containing any copyright rights, +you hereby agree and acknowledge that the SPDX-Metadata is provided to you “as-is” +and without any representations or warranties of any kind concerning the SPDX-Metadata, +express, implied, statutory or otherwise, including without limitation warranties +of title, merchantability, fitness for a particular purpose, non-infringement, +or the absence of latent or other defects, accuracy, or the presence or absence of errors, +whether or not discoverable, all to the greatest extent permissible under applicable law.""" ; + rdfs:domain core:CreationInfo ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +core:definingDocument a owl:DatatypeProperty ; + rdfs:comment "A definingDocument property is used to link an Element identifier to an SpdxDocument which contains the definition for the Element." ; + rdfs:domain core:ExternalMap ; + rdfs:range xsd:anyURI ; + ns0:term_status "Stable" . + +core:description a owl:DatatypeProperty ; + rdfs:comment """This field is a detailed description of the Element. It may also be extracted from the Element itself. +The intent is to provide recipients of the SPDX file with a detailed technical explanation +of the functionality, anticipated use, and anticipated implementation of the Element. +This field may also include a description of improvements over prior versions of the Element.""" ; + rdfs:domain core:Element ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +core:element a owl:ObjectProperty ; + rdfs:comment "This field refers to one or more Elements that are part of an ElementCollection." ; + rdfs:domain core:ElementCollection ; + rdfs:range core:Element ; + ns0:term_status "Stable" . + +core:end a owl:DatatypeProperty ; + rdfs:comment "end is a positive integer that defines the end of a range." ; + rdfs:domain core:PositiveIntegerRange ; + rdfs:range xsd:positiveInteger ; + ns0:term_status "Stable" . + +core:endTime a owl:DatatypeProperty ; + rdfs:comment "A endTime specifies the time from which element is no applicable / valid." ; + rdfs:domain core:Relationship ; + rdfs:range core:DateTime ; + ns0:term_status "Stable" . + +core:extension rdfs:comment "TODO" ; + rdfs:domain core:Element ; + ns0:term_status "Stable" . + +core:externalId a owl:DatatypeProperty ; + rdfs:comment "ExternalId identifies an external Element used within a Document but defined external to that Document." ; + rdfs:domain core:ExternalMap ; + rdfs:range xsd:anyURI ; + ns0:term_status "Stable" . + +core:externalIdentifier a owl:ObjectProperty ; + rdfs:comment """ExternalIdentifier points to a resource outside the scope of SPDX-3.0 content +that uniquely identifies an Element.""" ; + rdfs:domain core:Element ; + rdfs:range core:ExternalIdentifier ; + ns0:term_status "Stable" . + +core:externalIdentifierType a owl:DatatypeProperty ; + rdfs:comment "An externalIdentifierType specifies the type of the external identifier." ; + rdfs:domain core:ExternalIdentifier ; + rdfs:range core:ExternalIdentifierType ; + ns0:term_status "Stable" . + +core:externalReference a owl:ObjectProperty ; + rdfs:comment """This field points to a resource outside the scope of the SPDX-3.0 content +that provides additional characteristics of an Element.""" ; + rdfs:domain core:Element ; + rdfs:range core:ExternalReference ; + ns0:term_status "Stable" . + +core:externalReferenceType a owl:DatatypeProperty ; + rdfs:comment "An externalReferenceType specifies the type of the external reference." ; + rdfs:domain core:ExternalReference ; + rdfs:range core:ExternalReferenceType ; + ns0:term_status "Stable" . + +core:from a owl:ObjectProperty ; + rdfs:comment "This field references the Element on the left-hand side of a relationship." ; + rdfs:domain core:Relationship ; + rdfs:range core:Element ; + ns0:term_status "Stable" . + +core:hashValue a owl:DatatypeProperty ; + rdfs:comment "HashValue is the result of applying a hash algorithm to an Element." ; + rdfs:domain core:Hash ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +core:identifier a owl:DatatypeProperty ; + rdfs:comment "An identifier uniquely identifies an external element." ; + rdfs:domain core:ExternalIdentifier ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +core:identifierLocator a owl:DatatypeProperty ; + rdfs:comment "A identifierLocator is TODO" ; + rdfs:domain core:ExternalIdentifier ; + rdfs:range xsd:anyURI ; + ns0:term_status "Stable" . + +core:issuingAuthority a owl:DatatypeProperty ; + rdfs:comment "A issuingAuthority is TODO" ; + rdfs:domain core:ExternalIdentifier ; + rdfs:range xsd:anyURI ; + ns0:term_status "Stable" . + +core:key a owl:DatatypeProperty ; + rdfs:comment """A key used in generic a key-value pair. +A key-value pair can be used to implement a dictionary which associates a key with a value.""" ; + rdfs:domain core:DictionaryEntry ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +core:locationHint a owl:DatatypeProperty ; + rdfs:comment "A locationHint provides an indication of where to retrieve an external Element." ; + rdfs:domain core:ExternalMap ; + rdfs:range xsd:anyURI ; + ns0:term_status "Stable" . + +core:locator a owl:DatatypeProperty ; + rdfs:comment "A locator provides the location of an external reference." ; + rdfs:domain core:ExternalReference ; + rdfs:range xsd:anyURI ; + ns0:term_status "Stable" . + +core:namespace a owl:DatatypeProperty ; + rdfs:comment "A namespace provides an unambiguous mechanism for other documents to reference Elements within this document." ; + rdfs:domain core:NamespaceMap ; + rdfs:range xsd:anyURI ; + ns0:term_status "Stable" . + +core:originatedBy a owl:ObjectProperty ; + rdfs:comment "OriginatedBy identifies from where or whom the Element originally came." ; + rdfs:domain core:Artifact ; + rdfs:range core:Agent ; + ns0:term_status "Stable" . + +core:prefix a owl:DatatypeProperty ; + rdfs:comment "A prefix is a substitute for a URI." ; + rdfs:domain core:NamespaceMap ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +core:profile a owl:DatatypeProperty ; + rdfs:comment "This field provides information about which profiles the Element belongs to." ; + rdfs:domain core:CreationInfo ; + rdfs:range core:ProfileIdentifierType ; + ns0:term_status "Stable" . + +core:relationshipType a owl:DatatypeProperty ; + rdfs:comment """This field provides information about the relationship between two Elements. +For example, you can represent a relationship between two different Files, +between a Package and a File, between two Packages, or between one SPDXDocument and another SPDXDocument.""" ; + rdfs:domain core:Relationship ; + rdfs:range core:RelationshipType ; + ns0:term_status "Stable" . + +core:releaseTime a owl:DatatypeProperty ; + rdfs:comment "A releaseTime specifies the time an artifact was released." ; + rdfs:domain core:Artifact ; + rdfs:range core:DateTime ; + ns0:term_status "Stable" . + +core:rootElement a owl:ObjectProperty ; + rdfs:comment "A rootElement of a collection is the top level Element from which all other Elements are reached via relationships." ; + rdfs:domain core:ElementCollection ; + rdfs:range core:Element ; + ns0:term_status "Stable" . + +core:scope a owl:DatatypeProperty ; + rdfs:comment "A scope is TODO" ; + rdfs:domain core:LifecycleScopedRelationship ; + rdfs:range core:LifecycleScopeType ; + ns0:term_status "Stable" . + +core:specVersion a owl:DatatypeProperty ; + rdfs:comment """The specVersion provides a reference number that can be used to understand how to parse and interpret an Element. +It will enable both future changes to the specification and to support backward compatibility. +The major version number shall be incremented when incompatible changes between versions are made +(one or more sections are created, modified or deleted). +The minor version number shall be incremented when backwards compatible changes are made. + +Here, parties exchanging information in accordance with the SPDX specification need to provide +100% transparency as to which SPDX specification version such information is conforming to.""" ; + rdfs:domain core:CreationInfo ; + rdfs:range core:SemVer ; + ns0:term_status "Stable" . + +core:standard a owl:DatatypeProperty ; + rdfs:comment "Various standards may be relevant to useful to capture for specific artifacts." ; + rdfs:domain core:Artifact ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +core:startTime a owl:DatatypeProperty ; + rdfs:comment "A startTime specifies the time from which element is applicable / valid." ; + rdfs:domain core:Relationship ; + rdfs:range core:DateTime ; + ns0:term_status "Stable" . + +core:statement a owl:DatatypeProperty ; + rdfs:comment "A statement is a commentary on an assertion that an annotator has made." ; + rdfs:domain core:Annotation ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +core:subject a owl:ObjectProperty ; + rdfs:comment "A subject is an Element an annotator has made an assertion about." ; + rdfs:domain core:Annotation ; + rdfs:range core:Element ; + ns0:term_status "Stable" . + +core:summary a owl:DatatypeProperty ; + rdfs:comment """A summary is a short description of an Element. Here, the intent is to allow the Element creator to +provide concise information about the function or use of the Element.""" ; + rdfs:domain core:Element ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +core:suppliedBy a owl:ObjectProperty ; + rdfs:comment """Identify the actual distribution source for the Artifact being referenced. +This might or might not be different from the originating distribution source for the artifact.""" ; + rdfs:domain core:Artifact ; + rdfs:range core:Agent ; + ns0:term_status "Stable" . + +core:to a owl:ObjectProperty ; + rdfs:comment "This field references an Element on the right-hand side of a relationship." ; + rdfs:domain core:Relationship ; + rdfs:range core:Element ; + ns0:term_status "Stable" . + +core:validUntilTime a owl:DatatypeProperty ; + rdfs:comment "A validUntilTime specifies until when the artifact can be used before its usage needs to be reassessed." ; + rdfs:domain core:Artifact ; + rdfs:range core:DateTime ; + ns0:term_status "Stable" . + +core:value a owl:DatatypeProperty ; + rdfs:comment """A value used in a generic key-value pair. +A key-value pair can be used to implement a dictionary which associates a key with a value.""" ; + rdfs:domain core:DictionaryEntry ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +dataset:anonymizationMethodUsed a owl:DatatypeProperty ; + rdfs:comment "AnonymizationMethodUsed describes the methods used to anonymize the dataset (of fields in the dataset)." ; + rdfs:domain dataset:Dataset ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +dataset:confidentialityLevel a owl:DatatypeProperty ; + rdfs:comment "ConfidentialityLevel describes the levels of confidentiality of the data points contained in the dataset." ; + rdfs:domain dataset:Dataset ; + rdfs:range dataset:ConfidentialityLevelType ; + ns0:term_status "Stable" . + +dataset:dataCollectionProcess a owl:DatatypeProperty ; + rdfs:comment """DataCollectionProcess describes how a dataset was collected. +Examples include the sources from which a dataset was scrapped or +the interview protocol that was used for data collection.""" ; + rdfs:domain dataset:Dataset ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +dataset:dataPreprocessing a owl:DatatypeProperty ; + rdfs:comment """DataPreprocessing describes the various preprocessing steps +that were applied to the raw data to create the dataset.""" ; + rdfs:domain dataset:Dataset ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +dataset:datasetAvailability a owl:DatatypeProperty ; + rdfs:comment "Some datasets are publicly available and can be downloaded directly. Others are only accessible behind a clickthrough, or after filling a registration form. This field will describe the dataset availability from that perspective." ; + rdfs:domain dataset:Dataset ; + rdfs:range dataset:DatasetAvailabilityType ; + ns0:term_status "Stable" . + +dataset:datasetNoise a owl:DatatypeProperty ; + rdfs:comment """DatasetNoise describes what kinds of noises a dataset might encompass. +The field uses free form text to specify the fields or the samples that might be noisy. +Alternatively, it can also be used to describe various noises that could impact the whole dataset.""" ; + rdfs:domain dataset:Dataset ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +dataset:datasetSize a owl:DatatypeProperty ; + rdfs:comment """DatasetSize Captures how large a dataset is. +The size is to be measured in bytes.""" ; + rdfs:domain dataset:Dataset ; + rdfs:range xsd:nonNegativeInteger ; + ns0:term_status "Stable" . + +dataset:datasetType a owl:DatatypeProperty ; + rdfs:comment "Type describes the datatype contained in the dataset. For example a dataset can be an image dataset for computer vision applications, a text dataset such as the contents of a book or Wikipedia article, or sometimes a multimodal dataset that contains multiple types of data." ; + rdfs:domain dataset:Dataset ; + rdfs:range dataset:DatasetType ; + ns0:term_status "Stable" . + +dataset:datasetUpdateMechanism a owl:DatatypeProperty ; + rdfs:comment "DatasetUpdateMechanism describes a mechanism to update the dataset." ; + rdfs:domain dataset:Dataset ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +dataset:intendedUse a owl:DatatypeProperty ; + rdfs:comment """IntendedUse describes what the given dataset should be used for. +Some datasets are collected to be used only for particular purposes. +For example, medical data collected from a specific demography might only be applicable +for training machine learning models to make predictions for that demography. +In such a case, the intendedUse field would capture this information. +Similarly, if a dataset is collected for building a facial recognition model, +the intendedUse field would specify that.""" ; + rdfs:domain dataset:Dataset ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +dataset:knownBias a owl:DatatypeProperty ; + rdfs:comment "KnownBias is a free form text field that describes the different biases that the dataset encompasses." ; + rdfs:domain dataset:Dataset ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +dataset:sensitivePersonalInformation a owl:DatatypeProperty ; + rdfs:comment """SensitivePersonalInformation indicates the presence of sensitive personal data +or information that allows drawing conclusions about a person's identity.""" ; + rdfs:domain dataset:Dataset ; + rdfs:range dataset:PresenceType ; + ns0:term_status "Stable" . + +dataset:sensor a owl:DatatypeProperty ; + rdfs:comment """Sensor describes a sensor that was used for collecting the data +and its calibration value as a key-value pair.""" ; + rdfs:domain dataset:Dataset ; + rdfs:range core:DictionaryEntry ; + ns0:term_status "Stable" . + +expandedlicense:ConjunctiveLicenseSet a owl:Class, + sh:NodeShape ; + rdfs:comment """A ConjunctiveLicenseSet indicates that _each_ of its subsidiary +AnyLicenseInfos apply. In other words, a ConjunctiveLicenseSet of two or +more licenses represents a licensing situation where _all_ of the specified +licenses are to be complied with. It is represented in the SPDX License +Expression Syntax by the `AND` operator. + +It is syntactically correct to specify a ConjunctiveLicenseSet where the +subsidiary AnyLicenseInfos may be "incompatible" according to a particular +interpretation of the corresponding Licenses. The SPDX License Expression +Syntax does not take into account interpretation of license texts, which is +left to the consumer of SPDX data to determine for themselves.""" ; + rdfs:subClassOf licensing:AnyLicenseInfo ; + ns0:term_status "Stable" ; + sh:property [ sh:class licensing:AnyLicenseInfo ; + sh:minCount 2 ; + sh:name "member" ; + sh:path expandedlicense:member ] . + +expandedlicense:DisjunctiveLicenseSet a owl:Class, + sh:NodeShape ; + rdfs:comment """A DisjunctiveLicenseSet indicates that _only one_ of its subsidiary +AnyLicenseInfos is required to apply. In other words, a +DisjunctiveLicenseSet of two or more licenses represents a licensing +situation where _only one_ of the specified licenses are to be complied with. +A consumer of SPDX data would typically understand this to permit the recipient +of the licensed content to choose which of the corresponding license they +would prefer to use. It is represented in the SPDX License Expression Syntax +by the `OR` operator.""" ; + rdfs:subClassOf licensing:AnyLicenseInfo ; + ns0:term_status "Stable" ; + sh:property [ sh:class licensing:AnyLicenseInfo ; + sh:minCount 2 ; + sh:name "member" ; + sh:path expandedlicense:member ] . + +licensing:LicenseExpression a owl:Class, + sh:NodeShape ; + rdfs:comment """Often a single license can be used to represent the licensing terms of a source code or binary file, but there are situations where a single license identifier is not sufficient. A common example is when software is offered under a choice of one or more licenses (e.g., GPL-2.0-only OR BSD-3-Clause). Another example is when a set of licenses is needed to represent a binary program constructed by compiling and linking two (or more) different source files each governed by different licenses (e.g., LGPL-2.1-only AND BSD-3-Clause). + +SPDX License Expressions provide a way for one to construct expressions that more accurately represent the licensing terms typically found in open source software source code. A license expression could be a single license identifier found on the SPDX License List; a user defined license reference denoted by the LicenseRef-idString; a license identifier combined with an SPDX exception; or some combination of license identifiers, license references and exceptions constructed using a small set of defined operators (e.g., AND, OR, WITH and +). We provide the definition of what constitutes a valid an SPDX License Expression in this section.""" ; + rdfs:subClassOf licensing:AnyLicenseInfo ; + ns0:term_status "Stable" ; + sh:property [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:name "licenseExpression" ; + sh:path licensing:licenseExpression ] . + +licensing:additionText a owl:DatatypeProperty ; + rdfs:comment """An additionText contains the plain text of the LicenseAddition, without +templating or other similar markup. + +Users of the additionText for a License can apply the SPDX Matching Guidelines +when comparing it to another text for matching purposes.""" ; + rdfs:domain licensing:LicenseAddition ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +licensing:isDeprecatedAdditionId a owl:DatatypeProperty ; + rdfs:comment """The isDeprecatedAdditionId property specifies whether an identifier for a +LicenseAddition has been marked as deprecated. If the property is not defined, +then it is presumed to be false (i.e., not deprecated). + +If the LicenseAddition is included on the SPDX Exceptions List, then +the `deprecatedVersion` property indicates on which version release of the +Exceptions List it was first marked as deprecated. + +"Deprecated" in this context refers to deprecating the use of the +_identifier_, not the underlying license addition. In other words, even if a +LicenseAddition's author or steward has stated that a particular +LicenseAddition generally should not be used, that would _not_ mean that the +LicenseAddition's identifier is "deprecated." Rather, a LicenseAddition +operator is typically marked as "deprecated" when it is determined that use of +another identifier is preferable.""" ; + rdfs:domain licensing:LicenseAddition ; + rdfs:range xsd:boolean ; + ns0:term_status "Stable" . + +licensing:isDeprecatedLicenseId a owl:DatatypeProperty ; + rdfs:comment """The isDeprecatedLicenseId property specifies whether an identifier for a +License or LicenseAddition has been marked as deprecated. If the property +is not defined, then it is presumed to be false (i.e., not deprecated). + +If the License or LicenseAddition is included on the SPDX License List, then +the `deprecatedVersion` property indicates on which version release of the +License List it was first marked as deprecated. + +"Deprecated" in this context refers to deprecating the use of the +_identifier_, not the underlying license. In other words, even if a License's +author or steward has stated that a particular License generally should not be +used, that would _not_ mean that the License's identifier is "deprecated." +Rather, a License or LicenseAddition operator is typically marked as +"deprecated" when it is determined that use of another identifier is +preferable.""" ; + rdfs:domain licensing:License ; + rdfs:range xsd:boolean ; + ns0:term_status "Stable" . + +licensing:isFsfLibre a owl:DatatypeProperty ; + rdfs:comment """isFsfLibre specifies whether the [Free Software Foundation FSF](https://fsf.org) +has listed this License as "free" in their commentary on licenses, located at +the time of this writing at https://www.gnu.org/licenses/license-list.en.html. + +A value of "true" indicates that the FSF has listed this License as _free_. + +A value of "false" indicates that the FSF has listed this License as _not free_. + +If the isFsfLibre field is not specified, the SPDX data creator makes no +assertions about whether the License is listed in the FSF's commentary.""" ; + rdfs:domain licensing:License ; + rdfs:range xsd:boolean ; + ns0:term_status "Stable" . + +licensing:isOsiApproved a owl:DatatypeProperty ; + rdfs:comment """isOsiApproved specifies whether the [Open Source Initiative (OSI)](https://opensource.org) +has listed this License as "approved" in their list of OSI Approved Licenses, +located at the time of this writing at https://opensource.org/licenses/. + +A value of "true" indicates that the OSI has listed this License as approved. + +A value of "false" indicates that the OSI has not listed this License as +approved. + +If the isOsiApproved field is not specified, the SPDX data creator makes no +assertions about whether the License is approved by the OSI.""" ; + rdfs:domain licensing:License ; + rdfs:range xsd:boolean ; + ns0:term_status "Stable" . + +licensing:licenseExpression a owl:DatatypeProperty ; + rdfs:comment """Often a single license can be used to represent the licensing terms of a source code or binary file, but there are situations where a single license identifier is not sufficient. A common example is when software is offered under a choice of one or more licenses (e.g., GPL-2.0-only OR BSD-3-Clause). Another example is when a set of licenses is needed to represent a binary program constructed by compiling and linking two (or more) different source files each governed by different licenses (e.g., LGPL-2.1-only AND BSD-3-Clause). + +SPDX License Expressions provide a way for one to construct expressions that more accurately represent the licensing terms typically found in open source software source code. A license expression could be a single license identifier found on the SPDX License List; a user defined license reference denoted by the LicenseRef-idString; a license identifier combined with an SPDX exception; or some combination of license identifiers, license references and exceptions constructed using a small set of defined operators (e.g., AND, OR, WITH and +). We provide the definition of what constitutes a valid an SPDX License Expression in this section.""" ; + rdfs:domain licensing:LicenseExpression ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +licensing:licenseText a owl:DatatypeProperty ; + rdfs:comment """A licenseText contains the plain text of the License, without templating +or other similar markup. + +Users of the licenseText for a License can apply the SPDX Matching Guidelines +when comparing it to another text for matching purposes.""" ; + rdfs:domain licensing:License ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +licensing:standardAdditionTemplate a owl:DatatypeProperty ; + rdfs:comment """A standardAdditionTemplate contains a license addition template which describes +sections of the LicenseAddition text which can be varied. See the Legacy Text +Template format section of the SPDX specification for format information.""" ; + rdfs:domain licensing:LicenseAddition ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +licensing:standardLicenseHeader a owl:DatatypeProperty ; + rdfs:comment """A standardLicenseHeader contains the plain text of the License author's +preferred wording to be used, typically in a source code file's header +comments or similar location, to indicate that the file is subject to +the specified License.""" ; + rdfs:domain licensing:License ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +licensing:standardLicenseTemplate a owl:DatatypeProperty ; + rdfs:comment """A standardLicenseTemplate contains a license template which describes +sections of the License text which can be varied. See the Legacy Text Template +format section of the SPDX specification for format information.""" ; + rdfs:domain licensing:License ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +security:SsvcVulnAssessmentRelationship a owl:Class, + sh:NodeShape ; + rdfs:comment """An SsvcVulnAssessmentRelationship describes the decision made using the +Stakeholder-Specific Vulnerability Categorization (SSVC) decision tree as +defined on [https://www.cisa.gov/stakeholder-specific-vulnerability-categorization-ssvc](https://www.cisa.gov/stakeholder-specific-vulnerability-categorization-ssvc). +It is intended to communicate the results of using the CISA SSVC Calculator. + +**Constraints** + +- The relationship type must be set to hasAssessmentFor. + +**Syntax** + +```json +{ + "@type": "SsvcVulnAssessmentRelationship", + "@id": "urn:spdx.dev:ssvc-1", + "relationshipType": "hasAssessmentFor", + "decisionType": "act", + "from": "urn:spdx.dev:vuln-cve-2020-28498", + "to": ["urn:product-acme-application-1.3"], + "assessedElement": "urn:npm-elliptic-6.5.2", + "suppliedBy": ["urn:spdx.dev:agent-jane-doe"], + "publishedTime": "2021-03-09T11:04:53Z" +} +```""" ; + rdfs:subClassOf security:VulnAssessmentRelationship ; + ns0:term_status "Stable" ; + sh:property [ sh:class security:SsvcDecisionType ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:name "decisionType" ; + sh:path security:decisionType ] . + +security:actionStatement a owl:DatatypeProperty ; + rdfs:comment """When an element is referenced with a VexAffectedVulnAssessmentRelationship, +the relationship MUST include one actionStatement that SHOULD describe actions +to remediate or mitigate the vulnerability.""" ; + rdfs:domain security:VexAffectedVulnAssessmentRelationship ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +security:actionStatementTime a owl:DatatypeProperty ; + rdfs:comment """When a VEX statement communicates an affected status, the author MUST +include an action statement with a recommended action to help mitigate the +vulnerability's impact. The actionStatementTime property records the time +when the action statement was first communicated.""" ; + rdfs:domain security:VexAffectedVulnAssessmentRelationship ; + rdfs:range core:DateTime ; + ns0:term_status "Stable" . + +security:assessedElement a owl:ObjectProperty ; + rdfs:comment """Specifies subpackages, files or snippets referenced by a security assessment +to specify the precise location where a vulnerability was found.""" ; + rdfs:domain security:VulnAssessmentRelationship ; + rdfs:range core:Element ; + ns0:term_status "Stable" . + +security:catalogType a owl:DatatypeProperty ; + rdfs:comment "A catalogType is a mandatory value and must select one of the two entries in the `ExploitCatalogType.md` vocabulary." ; + rdfs:domain security:ExploitCatalogVulnAssessmentRelationship ; + rdfs:range security:ExploitCatalogType ; + ns0:term_status "Stable" . + +security:decisionType a owl:DatatypeProperty ; + rdfs:comment "A decisionType is a mandatory value and must select one of the four entries in the `SsvcDecisionType.md` vocabulary." ; + rdfs:domain security:SsvcVulnAssessmentRelationship ; + rdfs:range security:SsvcDecisionType ; + ns0:term_status "Stable" . + +security:exploited a owl:DatatypeProperty ; + rdfs:comment "This field is set when a CVE is listed in an exploit catalog." ; + rdfs:domain security:ExploitCatalogVulnAssessmentRelationship ; + rdfs:range xsd:boolean ; + ns0:term_status "Stable" . + +security:impactStatement a owl:DatatypeProperty ; + rdfs:comment """When a VEX product element is related with a VexNotAffectedVulnAssessmentRelationship +and a machine readable justification label is not provided, then an impactStatement +that further explains how or why the prouct(s) are not affected by the vulnerability +must be provided.""" ; + rdfs:domain security:VexNotAffectedVulnAssessmentRelationship ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +security:impactStatementTime a owl:DatatypeProperty ; + rdfs:comment "TODO" ; + rdfs:domain security:VexNotAffectedVulnAssessmentRelationship ; + rdfs:range core:DateTime ; + ns0:term_status "Stable" . + +security:justificationType a owl:DatatypeProperty ; + rdfs:comment """When stating that an element is not affected by a vulnerability, the +VexNotAffectedVulnAssessmentRelationship must include a justification from the +machine-readable labels catalog informing the reason the element is not impacted. + +impactStatement which is a string with English prose can be used instead or as +complementary to the justification label, but one of both MUST be defined.""" ; + rdfs:domain security:VexNotAffectedVulnAssessmentRelationship ; + rdfs:range security:VexJustificationType ; + ns0:term_status "Stable" . + +security:locator a owl:DatatypeProperty ; + rdfs:comment "A locator provides the location of an exploit catalog." ; + rdfs:domain security:ExploitCatalogVulnAssessmentRelationship ; + rdfs:range xsd:anyURI ; + ns0:term_status "Stable" . + +security:probability a owl:DatatypeProperty ; + rdfs:comment """The probability score between 0 and 1 (0 and 100%) estimating the likelihood +that a vulnerability will be exploited in the next 12 months.""" ; + rdfs:domain security:EpssVulnAssessmentRelationship ; + rdfs:range xsd:decimal ; + ns0:term_status "Stable" . + +security:statusNotes a owl:DatatypeProperty ; + rdfs:comment "TODO" ; + rdfs:domain security:VexVulnAssessmentRelationship ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +security:suppliedBy a owl:ObjectProperty ; + rdfs:comment "Identify the actual distribution source for the vulnerability assessment relationship being referenced." ; + rdfs:domain security:VulnAssessmentRelationship ; + rdfs:range core:Agent ; + ns0:term_status "Stable" . + +security:vexVersion a owl:DatatypeProperty ; + rdfs:comment "TODO" ; + rdfs:domain security:VexVulnAssessmentRelationship ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +software:File a owl:Class, + sh:NodeShape ; + rdfs:comment """Refers to any object that stores content on a computer. +The type of content can optionally be provided in the contentType property. +External property restriction on /Core/Element/name: minCount: 1""" ; + rdfs:subClassOf software:SoftwareArtifact ; + ns0:term_status "Stable" ; + sh:property [ sh:datatype core:MediaType ; + sh:maxCount 1 ; + sh:name "contentType" ; + sh:path software:contentType ] . + +software:Sbom a owl:Class, + sh:NodeShape ; + rdfs:comment """A Software Bill of Materials (SBOM) is a collection of SPDX Elements describing a single package. +This could include details of the content and composition of the product, +provenance details of the product and/or +its composition, licensing information, known quality or security issues, etc.""" ; + rdfs:subClassOf core:Bom ; + ns0:term_status "Stable" ; + sh:property [ sh:class software:SBOMType ; + sh:name "sbomType" ; + sh:path software:sbomType ] . + +software:additionalPurpose a owl:DatatypeProperty ; + rdfs:comment "Additional purpose provides information about the additional purposes of the software artifact in addition to the primaryPurpose." ; + rdfs:domain software:SoftwareArtifact ; + rdfs:range software:SoftwarePurpose ; + ns0:term_status "Stable" . + +software:attributionText a owl:DatatypeProperty ; + rdfs:comment """An attributionText for a software Package, File or Snippet provides a consumer +of SPDX data with acknowledgement content, to assist redistributors of the +Package, File or Snippet with reproducing those acknowledgements. + +For example, this field may include a statement that is required by a +particular license to be reproduced in end-user documentation, advertising +materials, or another form. + +This field may describe where, or in which contexts, the acknowledgements +need to be reproduced, but it is not required to do so. The SPDX data creator +may also explain elsewhere (such as in a licenseComment field) how they intend +for data in this field to be used. + +An attributionText is is not meant to include the software Package, File or +Snippet’s actual complete license text (see concludedLicense to identify the +corresponding license).""" ; + rdfs:domain software:SoftwareArtifact ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +software:byteRange a owl:DatatypeProperty ; + rdfs:comment """This field defines the byte range in the original host file that the snippet information applies to. +A range of bytes is independent of various formatting concerns, and the most accurate way +of referring to the differences. The choice was made to start the numbering of +the byte range at 1 to be consistent with the W3C pointer method vocabulary.""" ; + rdfs:domain software:Snippet ; + rdfs:range core:PositiveIntegerRange ; + ns0:term_status "Stable" . + +software:concludedLicense a owl:ObjectProperty ; + rdfs:comment """A concludedLicense is the license identified by the SPDX data creator, +based on analyzing the license information in the software Package, File +or Snippet and other information to arrive at a reasonably objective +conclusion as to what license governs it. + +If a concludedLicense has a NONE value (NoneLicense), this indicates that the +SPDX data creator has looked and did not find any license information for this +software Package, File or Snippet. + +If a concludedLicense has a NOASSERTION value (NoAssertionLicense), this +indicates that one of the following applies: +* the SPDX data creator has attempted to but cannot reach a reasonable + objective determination; +* the SPDX data creator has made no attempt to determine this field; or +* the SPDX data creator has intentionally provided no information (no + meaning should be implied by doing so). + +A written explanation of a NOASSERTION value (NoAssertionLicense) MAY be +provided in the licenseComment field. + +If the concludedLicense for a software Package, File or Snippet is not the +same as its declaredLicense, a written explanation SHOULD be provided in +the licenseComment field. + +If the declaredLicense for a software Package, File or Snippet is a choice +of more than one license (e.g. a license expression combining two licenses +through use of the `OR` operator), then the concludedLicense may either +retain the license choice or identify which license was chosen.""" ; + rdfs:domain software:SoftwareArtifact ; + rdfs:range licensing:AnyLicenseInfo ; + ns0:term_status "Stable" . + +software:conditionality a owl:DatatypeProperty ; + rdfs:comment "A conditionality is TODO" ; + rdfs:domain software:SoftwareDependencyRelationship ; + rdfs:range software:DependencyConditionalityType ; + ns0:term_status "Stable" . + +software:contentIdentifier a owl:DatatypeProperty ; + rdfs:comment """The contentIdentifier provides a canonical, unique, immutable artifact identifier for each software artifact. SPDX 3.0 describes software artifacts as Snippet, File, or Package Elements. The ContentIdentifier can be calculated for any software artifact and can be recorded for any of these SPDX 3.0 Elements using Omnibor, an attempt to standardize how software artifacts are identified independent of which programming language, version control system, build tool, package manager, or software distribution mechanism is in use. + +The contentIdentifier is defined as the [Git Object Identifier](https://git-scm.com/book/en/v2/Git-Internals-Git-Objects) (gitoid) of type `blob` of the software artifact. The use of a git-based version control system is not necessary to calculate a contentIdentifier for any software artifact. + +The gitoid is expressed in the ContentIdentifier property by using the IANA [gitoid URI scheme](https://www.iana.org/assignments/uri-schemes/prov/gitoid). + +``` +Scheme syntax: gitoid":"":"":" +``` + +The OmniBOR ID for the OmniBOR Document associated with a software artifact should not be recorded in this field. Rather, OmniBOR IDs should be recorded in the SPDX Element's ExternalIdentifier property. See [https://omnibor.io](https://omnibor.io) for more details.""" ; + rdfs:domain software:SoftwareArtifact ; + rdfs:range xsd:anyURI ; + ns0:term_status "Stable" . + +software:contentType a owl:DatatypeProperty ; + rdfs:comment """This field is a reasonable estimation of the content type of the Element, from a creator perspective. +Content type is intrinsic to the Element, independent of how the Element is being used.""" ; + rdfs:domain software:File ; + rdfs:range core:MediaType ; + ns0:term_status "Stable" . + +software:copyrightText a owl:ObjectProperty ; + rdfs:comment """A copyrightText consists of the text(s) of the copyright notice(s) found +for a software Package, File or Snippet, if any. + +If a copyrightText contains text, then it may contain any text related to +one or more copyright notices (even if not complete) for that software +Package, File or Snippet. + +If a copyrightText has a "NONE" value, this indicates that the software +Package, File or Snippet contains no copyright notice whatsoever. + +If a copyrightText has a "NOASSERTION" value, this indicates that one of the +following applies: +* the SPDX data creator has attempted to but cannot reach a reasonable + objective determination; +* the SPDX data creator has made no attempt to determine this field; or +* the SPDX data creator has intentionally provided no information (no + meaning should be implied by doing so).""" ; + rdfs:domain software:SoftwareArtifact ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +software:declaredLicense a owl:ObjectProperty ; + rdfs:comment """A declaredLicense is the license identified in text in the software package, +file or snippet as the license declared by its authors. + +This field is not intended to capture license information obtained from an +external source, such as a package's website. Such information can be +included, as needed, in a concludedLicense field. + +A declaredLicense may be expressed differently in practice for different +types of artifacts. For example: + +* for Packages: + * would include license info describing the license of the Package as a + whole, when it is found in the Package itself (e.g., LICENSE file, + README file, metadata in the repository, etc.) + * would not include any license information that is not in the Package + itself (e.g., license information from the project’s website or from a + third party repository or website) +* for Files: + * would include license info found in the File itself (e.g., license + header or notice, comments, SPDX-License-Identifier expression) + * would not include license info found in a different file (e.g., LICENSE + file in the top directory of a repository) +* for Snippets: + * would include license info found in the Snippet itself (e.g., license + notice, comments, SPDX-License-Identifier expression) + * would not include license info found elsewhere in the File or in a + different File (e.g., comment at top of File if it is not within the + Snippet, LICENSE file in the top directory of a repository) + +If a declaredLicense has a NONE value (NoneLicense), this indicates that the +corresponding Package, File or Snippet contains no license information +whatsoever. + +If a declaredLicense has a NOASSERTION value (NoAssertionLicense), this +indicates that one of the following applies: +* the SPDX data creator has attempted to but cannot reach a reasonable + objective determination; +* the SPDX data creator has made no attempt to determine this field; or +* the SPDX data creator has intentionally provided no information (no meaning + should be implied by doing so).""" ; + rdfs:domain software:SoftwareArtifact ; + rdfs:range licensing:AnyLicenseInfo ; + ns0:term_status "Stable" . + +software:downloadLocation a owl:DatatypeProperty ; + rdfs:comment """DownloadLocation identifies the download Uniform Resource Identifier +for the package at the time that the document was created. +Where and how to download the exact package being referenced +is critical for verification and tracking data.""" ; + rdfs:domain software:Package ; + rdfs:range xsd:anyURI ; + ns0:term_status "Stable" . + +software:homePage a owl:DatatypeProperty ; + rdfs:comment """HomePage is a place for the SPDX document creator to record a website that serves as the package's home page. +This saves the recipient of the SPDX document who is looking for more info from +having to search for and verify a match between the package and the associated project home page. +This link can also be used to reference further information about the package +referenced by the SPDX document creator.""" ; + rdfs:domain software:Package ; + rdfs:range xsd:anyURI ; + ns0:term_status "Stable" . + +software:lineRange a owl:DatatypeProperty ; + rdfs:comment """This field defines the line range in the original host file that the snippet information applies to. +If there is a disagreement between the byte range and line range, the byte range values will take precedence. +A range of lines is a convenient reference for those files where there is a known line delimiter. +The choice was made to start the numbering of the lines at 1 to be consistent with the W3C pointer method vocabulary.""" ; + rdfs:domain software:Snippet ; + rdfs:range core:PositiveIntegerRange ; + ns0:term_status "Stable" . + +software:packageUrl a owl:DatatypeProperty ; + rdfs:comment """A packageUrl (commonly pronounced and referred to as "purl") is an attempt to standardize package representations in order to reliably identify and locate software packages. A purl is a URL string which represents a package in a mostly universal and uniform way across programming languages, package managers, packaging conventions, tools, APIs and databases. + +the purl URL string is defined by seven components: +``` +scheme:type/namespace/name@version?qualifiers#subpath +``` + +The definition for each component can be found in the [purl specification](https://github.com/package-url/purl-spec/blob/master/PURL-SPECIFICATION.rst). Components are designed such that they form a hierarchy from the most significant on the left to the least significant components on the right. + +Parsing a purl string into its components works from left to right. Some extra type-specific normalizations are required. For more information, see [How to parse a purl string in its components](https://github.com/package-url/purl-spec/blob/master/PURL-SPECIFICATION.rst#how-to-parse-a-purl-string-in-its-components).""" ; + rdfs:domain software:Package ; + rdfs:range xsd:anyURI ; + ns0:term_status "Stable" . + +software:packageVersion a owl:DatatypeProperty ; + rdfs:comment "A packageVersion is useful for identification purposes and for indicating later changes of the package version." ; + rdfs:domain software:Package ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +software:primaryPurpose a owl:DatatypeProperty ; + rdfs:comment "primaryPurpose provides information about the primary purpose of the software artifact." ; + rdfs:domain software:SoftwareArtifact ; + rdfs:range software:SoftwarePurpose ; + ns0:term_status "Stable" . + +software:sbomType a owl:DatatypeProperty ; + rdfs:comment """This field is a reasonable estimation of the type of SBOM created from a creator perspective. +It is intended to be used to give guidance on the elements that may be contained within it. +Aligning with the guidance produced in [Types of Software Bill of Material (SBOM) Documents](https://www.cisa.gov/sites/default/files/2023-04/sbom-types-document-508c.pdf).""" ; + rdfs:domain software:Sbom ; + rdfs:range software:SBOMType ; + ns0:term_status "Stable" . + +software:softwareLinkage a owl:DatatypeProperty ; + rdfs:comment "A softwareLinkage is TODO" ; + rdfs:domain software:SoftwareDependencyRelationship ; + rdfs:range software:SoftwareDependencyLinkType ; + ns0:term_status "Stable" . + +software:sourceInfo a owl:DatatypeProperty ; + rdfs:comment """SourceInfo records any relevant background information or additional comments +about the origin of the package. For example, this field might include comments +indicating whether the package was pulled from a source code management system +or has been repackaged. The creator can provide additional information to describe +any anomalies or discoveries in the determination of the origin of the package.""" ; + rdfs:domain software:Package ; + rdfs:range xsd:string ; + ns0:term_status "Stable" . + +core:LifecycleScopedRelationship a owl:Class, + sh:NodeShape ; + rdfs:comment "TODO" ; + rdfs:subClassOf core:Relationship ; + ns0:term_status "Stable" ; + sh:property [ sh:class core:LifecycleScopeType ; + sh:maxCount 1 ; + sh:name "scope" ; + sh:path core:scope ] . + +core:SemVer a owl:Class, + sh:NodeShape ; + rdfs:comment """The semantic version is a string +that is following the specification of [Semantic Versioning 2.0.0](https://semver.org/). +Format restriction: 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-]+)*))?$""" ; + rdfs:subClassOf xsd:string ; + ns0:term_status "Stable" . + +core:Tool a owl:Class, + sh:NodeShape ; + rdfs:comment "A Tool is an element of hardware and/or software utilized to carry out a particular function." ; + rdfs:subClassOf core:Element ; + ns0:term_status "Stable" . + +core:contentType a owl:DatatypeProperty ; + rdfs:comment "ContentType specifies the media type of an Element." ; + rdfs:range core:MediaType ; + ns0:term_status "Stable" ; + sh:or ( [ rdfs:domain core:Annotation, + core:ExternalReference ] ) . + +core:name a owl:DatatypeProperty ; + rdfs:comment """This field identifies the name of an Element as designated by the creator. +The name of an Element is an important convention and easier to refer to than the URI.""" ; + rdfs:range xsd:string ; + ns0:term_status "Stable" ; + sh:or ( [ rdfs:domain core:Element, + core:SpdxDocument ] ) . + +core:verifiedUsing a owl:ObjectProperty ; + rdfs:comment "VerifiedUsing provides an IntegrityMethod with which the integrity of an Element can be asserted." ; + rdfs:range core:IntegrityMethod ; + ns0:term_status "Stable" ; + sh:or ( [ rdfs:domain core:Element, + core:ExternalMap ] ) . + +expandedlicense:member a owl:ObjectProperty ; + rdfs:comment """A member is a license expression participating in a conjuctive (of type +ConjunctiveLicenseSet) or a disjunctive (of type DisjunctiveLicenseSet) +license set.""" ; + rdfs:range licensing:AnyLicenseInfo ; + ns0:term_status "Stable" ; + sh:or ( [ rdfs:domain expandedlicense:ConjunctiveLicenseSet, + expandedlicense:DisjunctiveLicenseSet ] ) . + +licensing:ListedLicense a owl:Class, + sh:NodeShape ; + rdfs:comment """A ListedLicense represents a License that is listed on the SPDX License List +at https://spdx.org/licenses.""" ; + rdfs:subClassOf licensing:License ; + ns0:term_status "Stable" ; + sh:property [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "deprecatedVersion" ; + sh:path licensing:deprecatedVersion ], + [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "listVersionAdded" ; + sh:path licensing:listVersionAdded ] . + +licensing:ListedLicenseException a owl:Class, + sh:NodeShape ; + rdfs:comment """A ListedLicenseException represents an exception to a License (in other words, +an exception to a license condition or an additional permission beyond those +granted in a License) which is listed on the SPDX Exceptions List at +https://spdx.org/licenses/exceptions-index.html.""" ; + rdfs:subClassOf licensing:LicenseAddition ; + ns0:term_status "Stable" ; + sh:property [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "deprecatedVersion" ; + sh:path licensing:deprecatedVersion ], + [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "listVersionAdded" ; + sh:path licensing:listVersionAdded ] . + +licensing:deprecatedVersion a owl:DatatypeProperty ; + rdfs:comment """A deprecatedVersion for a ListedLicense or ListedLicenseException on the SPDX +License List specifies which version release of the License List was the first +one in which it was marked as deprecated.""" ; + rdfs:range xsd:string ; + ns0:term_status "Stable" ; + sh:or ( [ rdfs:domain licensing:ListedLicense, + licensing:ListedLicenseException ] ) . + +licensing:listVersionAdded a owl:DatatypeProperty ; + rdfs:comment """A listVersionAdded for a ListedLicense or ListedLicenseException on the SPDX +License List specifies which version release of the License List was the first +one in which it was included.""" ; + rdfs:range xsd:string ; + ns0:term_status "Stable" ; + sh:or ( [ rdfs:domain licensing:ListedLicense, + licensing:ListedLicenseException ] ) . + +licensing:obsoletedBy a owl:DatatypeProperty ; + rdfs:comment """An obsoletedBy value for a deprecated License or LicenseAddition specifies +the licenseId of the replacement License or LicenseAddition that is preferred +to be used in its place. It should use the same format as specified for a +licenseId. + +The License's or LicenseAddition's comment value may include more information +about the reason why the licenseId specified in the obsoletedBy value is +preferred.""" ; + rdfs:range xsd:string ; + ns0:term_status "Stable" ; + sh:or ( [ rdfs:domain licensing:License, + licensing:LicenseAddition ] ) . + +security:EpssVulnAssessmentRelationship a owl:Class, + sh:NodeShape ; + rdfs:comment """An EpssVulnAssessmentRelationship relationship describes the likelihood or +probability that a vulnerability will be exploited in the wild using the Exploit +Prediction Scoring System (EPSS) as defined on +[https://www.first.org/epss/model](https://www.first.org/epss/model). + +**Constraints** + +- The relationship type must be set to hasAssessmentFor. + +**Syntax** + +```json +{ + "@type": "EpssVulnAssessmentRelationship", + "@id": "urn:spdx.dev:epss-1", + "relationshipType": "hasAssessmentFor", + "probability": 80, + "from": "urn:spdx.dev:vuln-cve-2020-28498", + "to": ["urn:product-acme-application-1.3"], + "suppliedBy": ["urn:spdx.dev:agent-jane-doe"], + "publishedTime": "2021-03-09T11:04:53Z" +} +```""" ; + rdfs:subClassOf security:VulnAssessmentRelationship ; + ns0:term_status "Stable" ; + sh:property [ sh:datatype xsd:nonNegativeInteger ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:name "probability" ; + sh:path security:probability ], + [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "severity" ; + sh:path security:severity ] . + +security:VexAffectedVulnAssessmentRelationship a owl:Class, + sh:NodeShape ; + rdfs:comment """VexAffectedVulnAssessmentRelationship connects a vulnerability and a number +of elements. The relationship marks these elements as products affected by the +vulnerability. This relationship corresponds to the VEX affected status. + +**Constraints** + +When linking elements using a VexAffectedVulnAssessmentRelationship, the +following requirements must be observed: + +- Elements linked with a VulnVexAffectedAssessmentRelationship are constrained +to the affects relationship type. + +**Syntax** + +```json +{ + "@type": "VexAffectedVulnAssessmentRelationship", + "@id": "urn:spdx.dev:vex-affected-1", + "relationshipType": "affects", + "from": "urn:spdx.dev:vuln-cve-2020-28498", + "to": ["urn:product-acme-application-1.3"], + "assessedElement": "urn:npm-elliptic-6.5.2", + "actionStatement": "Upgrade to version 1.4 of ACME application.", + "suppliedBy": ["urn:spdx.dev:agent-jane-doe"], + "publishedTime": "2021-03-09T11:04:53Z" +} +```""" ; + rdfs:subClassOf security:VexVulnAssessmentRelationship ; + ns0:term_status "Stable" ; + sh:property [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "actionStatement" ; + sh:path security:actionStatement ], + [ sh:datatype core:DateTime ; + sh:name "actionStatementTime" ; + sh:path security:actionStatementTime ] . + +security:modifiedTime a owl:DatatypeProperty ; + rdfs:comment "Specifies a time when a vulnerability assessment was last modified." ; + rdfs:range core:DateTime ; + ns0:term_status "Stable" ; + sh:or ( [ rdfs:domain security:VulnAssessmentRelationship, + security:Vulnerability ] ) . + +security:publishedTime a owl:DatatypeProperty ; + rdfs:comment "Specifies the time when a vulnerability was first published." ; + rdfs:range core:DateTime ; + ns0:term_status "Stable" ; + sh:or ( [ rdfs:domain security:VulnAssessmentRelationship, + security:Vulnerability ] ) . + +security:score a owl:DatatypeProperty ; + rdfs:comment """The score provides information on the severity of a vulnerability per the +Common Vulnerability Scoring System as defined on [https://www.first.org/cvss](https://www.first.org/cvss/).""" ; + rdfs:range xsd:string ; + ns0:term_status "Stable" ; + sh:or ( [ rdfs:domain security:CvssV2VulnAssessmentRelationship, + security:CvssV3VulnAssessmentRelationship ] ) . + +security:vector a owl:DatatypeProperty ; + rdfs:comment """Sepcifies the vector string of a vulnerability, a string combining metrics +from an assessment of its severity.""" ; + rdfs:range xsd:string ; + ns0:term_status "Stable" ; + sh:or ( [ rdfs:domain security:CvssV2VulnAssessmentRelationship, + security:CvssV3VulnAssessmentRelationship ] ) . + +security:withdrawnTime a owl:DatatypeProperty ; + rdfs:comment "Specified the time and date when a vulnerability was withdrawn." ; + rdfs:range core:DateTime ; + ns0:term_status "Stable" ; + sh:or ( [ rdfs:domain security:VulnAssessmentRelationship, + security:Vulnerability ] ) . + +software:Snippet a owl:Class, + sh:NodeShape ; + rdfs:comment """A Snippet describes a certain part of a file and can be used when the file is known to have some content +that has been included from another original source. Snippets are useful for denoting when part of a file +may have been originally created under another license or copied from a place with a known vulnerability.""" ; + rdfs:subClassOf software:SoftwareArtifact ; + ns0:term_status "Stable" ; + sh:property [ sh:class core:PositiveIntegerRange ; + sh:maxCount 1 ; + sh:name "byteRange" ; + sh:path software:byteRange ], + [ sh:class core:PositiveIntegerRange ; + sh:maxCount 1 ; + sh:name "lineRange" ; + sh:path software:lineRange ] . + +software:SoftwareDependencyRelationship a owl:Class, + sh:NodeShape ; + rdfs:comment "TODO" ; + rdfs:subClassOf core:LifecycleScopedRelationship ; + ns0:term_status "Stable" ; + sh:property [ sh:class software:DependencyConditionalityType ; + sh:maxCount 1 ; + sh:name "conditionality" ; + sh:path software:conditionality ], + [ sh:class software:SoftwareDependencyLinkType ; + sh:maxCount 1 ; + sh:name "softwareLinkage" ; + sh:path software:softwareLinkage ] . + +core:AnonymousPayload a owl:Class, + sh:NodeShape ; + rdfs:comment "TODO" ; + rdfs:subClassOf core:Payload ; + ns0:term_status "Stable" ; + sh:property [ sh:class core:CreationInfo ; + sh:maxCount 1 ; + sh:name "creationInfo" ; + sh:path core:creationInfo ], + [ sh:class core:NamespaceMap ; + sh:name "namespaces" ; + sh:path core:namespaces ], + [ sh:class core:ExternalMap ; + sh:name "imports" ; + sh:path core:imports ] . + +core:Bundle a owl:Class, + sh:NodeShape ; + rdfs:comment "A bundle is a collection of Elements that have a shared context." ; + rdfs:subClassOf core:ElementCollection ; + ns0:term_status "Stable" ; + sh:property [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "context" ; + sh:path core:context ] . + +core:creationInfo a owl:DatatypeProperty ; + rdfs:comment "CreationInfo provides information about the creation of the Element." ; + rdfs:range core:CreationInfo ; + ns0:term_status "Stable" ; + sh:or ( [ rdfs:domain core:AnonymousPayload, + core:Element, + core:Payload ] ) . + +core:imports a owl:DatatypeProperty ; + rdfs:comment """Imports provides an ExternalMap of Element identifiers that are used within a document +but defined external to that document.""" ; + rdfs:range core:ExternalMap ; + ns0:term_status "Stable" ; + sh:or ( [ rdfs:domain core:AnonymousPayload, + core:ElementCollection, + core:Payload ] ) . + +core:namespaces a owl:DatatypeProperty ; + rdfs:comment "This field provides a NamespaceMap applicable to an ElementCollection." ; + rdfs:range core:NamespaceMap ; + ns0:term_status "Stable" ; + sh:or ( [ rdfs:domain core:AnonymousPayload, + core:ElementCollection, + core:Payload ] ) . + +security:CvssV2VulnAssessmentRelationship a owl:Class, + sh:NodeShape ; + rdfs:comment """A CvssV2VulnAssessmentRelationship relationship describes the determined score and vector of a vulnerability using version 2.0 of the Common Vulnerability Scoring System +(CVSS) as defined on [https://www.first.org/cvss/v2/guide](https://www.first.org/cvss/v2/guide). It is intented to communicate the results of using a CVSS calculator. + +**Constraints** + +- The value of severity must be one of 'low', 'medium' or 'high' +- The relationship type must be set to hasAssessmentFor. + +**Syntax** + +```json +{ + "@type": "CvssV2VulnAssessmentRelationship", + "@id": "urn:spdx.dev:cvssv2-cve-2020-28498", + "relationshipType": "hasAssessmentFor", + "score": 4.3, + "vector": "(AV:N/AC:M/Au:N/C:P/I:N/A:N)", + "severity": "low", + "from": "urn:spdx.dev:vuln-cve-2020-28498", + "to": ["urn:product-acme-application-1.3"], + "assessedElement": "urn:npm-elliptic-6.5.2", + "externalReferences": [ + { + "@type": "ExternalReference", + "externalReferenceType": "securityAdvisory", + "locator": "https://nvd.nist.gov/vuln/detail/CVE-2020-28498" + }, + { + "@type": "ExternalReference", + "externalReferenceType": "securityAdvisory", + "locator": "https://snyk.io/vuln/SNYK-JS-ELLIPTIC-1064899" + }, + { + "@type": "ExternalReference", + "externalReferenceType": "securityFix", + "locator": "https://github.com/indutny/elliptic/commit/441b742" + } + ], + "suppliedBy": ["urn:spdx.dev:agent-my-security-vendor"], + "publishedTime": "2023-05-06T10:06:13Z" +}, +{ + "@type": "Relationship", + "@id": "urn:spdx.dev:vulnAgentRel-1", + "relationshipType": "publishedBy", + "from": "urn:spdx.dev:cvssv2-cve-2020-28498", + "to": ["urn:spdx.dev:agent-snyk"], + "startTime": "2021-03-08T16:06:50Z" +} +```""" ; + rdfs:subClassOf security:VulnAssessmentRelationship ; + ns0:term_status "Stable" ; + sh:property [ sh:datatype xsd:decimal ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:name "score" ; + sh:path security:score ], + [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "vector" ; + sh:path security:vector ], + [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "severity" ; + sh:path security:severity ] . + +security:CvssV3VulnAssessmentRelationship a owl:Class, + sh:NodeShape ; + rdfs:comment """A CvssV3VulnAssessmentRelationship relationship describes the determined score, +severity, and vector of a vulnerability using version 3.1 of the Common +Vulnerability Scoring System (CVSS) as defined on +[https://www.first.org/cvss/v3.1/specification-document](https://www.first.org/cvss/v3.1/specification-document). It is intented to communicate the results of using a CVSS calculator. + +**Constraints** + +- The value of severity must be one of 'none', 'low', 'medium', 'high' or 'critical'. +- Absence of the property shall be interpreted as 'none'. +- The relationship type must be set to hasAssessmentFor. + +**Syntax** + +```json +{ + "@type": "CvssV3VulnAssessmentRelationship", + "@id": "urn:spdx.dev:cvssv3-cve-2020-28498", + "relationshipType": "hasAssessmentFor", + "severity": "medium", + "score": 6.8, + "vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:N/A:N", + "from": "urn:spdx.dev:vuln-cve-2020-28498", + "to": ["urn:product-acme-application-1.3"], + "assessedElement": "urn:npm-elliptic-6.5.2", + "externalReferences": [ + { + "@type": "ExternalReference", + "externalReferenceType": "securityAdvisory", + "locator": "https://nvd.nist.gov/vuln/detail/CVE-2020-28498" + }, + { + "@type": "ExternalReference", + "externalReferenceType": "securityAdvisory", + "locator": "https://snyk.io/vuln/SNYK-JS-ELLIPTIC-1064899" + }, + { + "@type": "ExternalReference", + "externalReferenceType": "securityFix", + "locator": "https://github.com/indutny/elliptic/commit/441b742" + } + ], + "suppliedBy": ["urn:spdx.dev:agent-my-security-vendor"], + "publishedTime": "2023-05-06T10:06:13Z" +}, +{ + "@type": "Relationship", + "@id": "urn:spdx.dev:vulnAgentRel-1", + "relationshipType": "publishedBy", + "from": "urn:spdx.dev:cvssv3-cve-2020-28498", + "to": "urn:spdx.dev:agent-snyk", + "startTime": "2021-03-08T16:06:50Z" +} +```""" ; + rdfs:subClassOf security:VulnAssessmentRelationship ; + ns0:term_status "Stable" ; + sh:property [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "vector" ; + sh:path security:vector ], + [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "severity" ; + sh:path security:severity ], + [ sh:datatype xsd:decimal ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:name "score" ; + sh:path security:score ] . + +security:ExploitCatalogVulnAssessmentRelationship a owl:Class, + sh:NodeShape ; + rdfs:comment """An ExploitCatalogVulnAssessmentRelationship describes if a vulnerability is +listed in any exploit catalog such as the CISA Known Exploited Vulnerabilities +Catalog (KEV) +[https://www.cisa.gov/known-exploited-vulnerabilities-catalog](https://www.cisa.gov/known-exploited-vulnerabilities-catalog). + +**Constraints** + +- The relationship type must be set to hasAssessmentFor. + +**Syntax** + +```json +{ + "@type": "ExploitCatalogVulnAssessmentRelationship", + "@id": "urn:spdx.dev:exploit-catalog-1", + "relationshipType": "hasAssessmentFor", + "catalogType": "kev", + "locator": "https://www.cisa.gov/known-exploited-vulnerabilities-catalog", + "exploited": "true", + "from": "urn:spdx.dev:vuln-cve-2023-2136", + "to": ["urn:product-google-chrome-112.0.5615.136"], + "suppliedBy": ["urn:spdx.dev:agent-jane-doe"], + "publishedTime": "2021-03-09T11:04:53Z" +} +```""" ; + rdfs:subClassOf security:VulnAssessmentRelationship ; + ns0:term_status "Stable" ; + sh:property [ sh:datatype xsd:anyURI ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:name "locator" ; + sh:path security:locator ], + [ sh:datatype xsd:boolean ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:name "exploited" ; + sh:path security:exploited ], + [ sh:class security:ExploitCatalogType ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:name "catalogType" ; + sh:path security:catalogType ] . + +security:VexNotAffectedVulnAssessmentRelationship a owl:Class, + sh:NodeShape ; + rdfs:comment """VexNotAffectedVulnAssessmentRelationship connects a vulnerability and a number +of elements designating them as products not affected by the vulnerability. +This relationship corresponds to the VEX not_affected status. + +**Constraints** + +When linking elements using a VexNotVulnAffectedAssessmentRelationship, the +following requirements must be observed: + +* Relating elements with a VexNotAffectedVulnAssessmentRelationship is restricted +to the doesNotAffect relationship type. +* The from: end of the relationship must be a /Security/Vulnerability classed +element. +* Both impactStatement and justificationType properties have a cardinality of +0..1 making them optional. Nevertheless, to produce a valid VEX not_affected +statement, one of them MUST be defined. This is specified in the Minimum Elements +for VEX. + +**Syntax** + +```json +{ + "@type": "VexNotAffectedVulnAssessmentRelationship", + "@id": "urn:spdx.dev:vex-not-affected-1", + "relationshipType": "doesNotAffect", + "from": "urn:spdx.dev:vuln-cve-2020-28498", + "to": ["urn:product-acme-application-1.3"], + "assessedElement": "urn:npm-elliptic-6.5.2", + "justificationType": "componentNotPresent", + "impactStatement": "Not using this vulnerable part of this library.", + "suppliedBy": ["urn:spdx.dev:agent-jane-doe"], + "publishedTime": "2021-03-09T11:04:53Z" +} +```""" ; + rdfs:subClassOf security:VexVulnAssessmentRelationship ; + ns0:term_status "Stable" ; + sh:property [ sh:datatype core:DateTime ; + sh:maxCount 1 ; + sh:name "impactStatementTime" ; + sh:path security:impactStatementTime ], + [ sh:class security:VexJustificationType ; + sh:maxCount 1 ; + sh:name "justificationType" ; + sh:path security:justificationType ], + [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "impactStatement" ; + sh:path security:impactStatement ] . + +security:Vulnerability a owl:Class, + sh:NodeShape ; + rdfs:comment """Specifies a vulnerability and its associated information. + +**Syntax** + +```json +{ + "@type": "Vulnerability", + "@id": "urn:spdx.dev:vuln-1", + "summary": "Use of a Broken or Risky Cryptographic Algorithm", + "description": "The npm package `elliptic` before version 6.5.4 are vulnerable to Cryptographic Issues via the secp256k1 implementation in elliptic/ec/key.js. There is no check to confirm that the public key point passed into the derive function actually exists on the secp256k1 curve. This results in the potential for the private key used in this implementation to be revealed after a number of ECDH operations are performed.", + "modified": "2021-03-08T16:02:43Z", + "published": "2021-03-08T16:06:50Z", + "externalIdentifiers": [ + { + "@type": "ExternalIdentifier", + "externalIdentifierType": "cve", + "identifier": "CVE-2020-2849", + "identifierLocator": [ + "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-28498", + "https://www.cve.org/CVERecord?id=CVE-2020-28498" + ], + "issuingAuthority": "urn:spdx.dev:agent-cve.org" + }, + { + "type": "ExternalIdentifier", + "externalIdentifierType": "securityOther", + "identifier": "GHSA-r9p9-mrjm-926w", + "identifierLocator": "https://github.com/advisories/GHSA-r9p9-mrjm-926w" + }, + { + "type": "ExternalIdentifier", + "externalIdentifierType": "securityOther", + "identifier": "SNYK-JS-ELLIPTIC-1064899", + "identifierLocator": "https://security.snyk.io/vuln/SNYK-JS-ELLIPTIC-1064899" + } + ], + "externalReferences": [ + { + "@type": "ExternalReference", + "externalReferenceType": "securityAdvisory", + "locator": "https://nvd.nist.gov/vuln/detail/CVE-2020-28498" + }, + { + "@type": "ExternalReference", + "externalReferenceType": "securityAdvisory", + "locator": "https://ubuntu.com/security/CVE-2020-28498" + }, + { + "@type": "ExternalReference", + "externalReferenceType": "securityOther", + "locator": "https://github.com/indutny/elliptic/pull/244/commits" + }, + { + "@type": "ExternalReference", + "externalReferenceType": "securityOther", + "locator": "https://github.com/christianlundkvist/blog/blob/master/2020_05_26_secp256k1_twist_attacks/secp256k1_twist_attacks.md" + } + ] +}, +{ + "@type": "Relationship", + "@id": "urn:spdx.dev:vulnRelationship-1", + "relationshipType": "hasAssociatedVulnerability", + "from": "urn:npm-elliptic-6.5.2", + "to": ["urn:spdx.dev:vuln-1"], + "startTime": "2021-03-08T16:06:50Z" +}, +{ + "@type": "Relationship", + "@id": "urn:spdx.dev:vulnAgentRel-1", + "relationshipType": "publishedBy", + "from": "urn:spdx.dev:vuln-1", + "to": ["urn:spdx.dev:agent-snyk"], + "startTime": "2021-03-08T16:06:50Z" +} +```""" ; + rdfs:subClassOf core:Element ; + ns0:term_status "Stable" ; + sh:property [ sh:datatype core:DateTime ; + sh:maxCount 1 ; + sh:name "publishedTime" ; + sh:path security:publishedTime ], + [ sh:datatype core:DateTime ; + sh:maxCount 1 ; + sh:name "withdrawnTime" ; + sh:path security:withdrawnTime ], + [ sh:datatype core:DateTime ; + sh:maxCount 1 ; + sh:name "modifiedTime" ; + sh:path security:modifiedTime ] . + +security:severity a owl:DatatypeProperty ; + rdfs:comment """The severity field provides a human readable string, a label that can be used +as an English adjective that qualifies its numerical score.""" ; + rdfs:range xsd:string ; + ns0:term_status "Stable" ; + sh:or ( [ rdfs:domain security:CvssV2VulnAssessmentRelationship, + security:CvssV3VulnAssessmentRelationship, + security:EpssVulnAssessmentRelationship ] ) . + +core:Annotation a owl:Class, + sh:NodeShape ; + rdfs:comment "An Annotation is an assertion made in relation to one or more elements." ; + rdfs:subClassOf core:Element ; + ns0:term_status "Stable" ; + sh:property [ sh:datatype core:MediaType ; + sh:name "contentType" ; + sh:path core:contentType ], + [ sh:class core:Element ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:name "subject" ; + sh:path core:subject ], + [ sh:class core:AnnotationType ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:name "annotationType" ; + sh:path core:annotationType ], + [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "statement" ; + sh:path core:statement ] . + +core:AnnotationType a owl:Class ; + rdfs:comment "AnnotationType specifies the type of an annotation." ; + ns0:term_status "Stable" . + +core:Hash a owl:Class, + sh:NodeShape ; + rdfs:comment """A hash is a grouping of characteristics unique to the result +of applying a mathematical algorithm +that maps data of arbitrary size to a bit string (the hash) +and is a one-way function, that is, +a function which is practically infeasible to invert. +This is commonly used for integrity checking of data.""" ; + rdfs:subClassOf core:IntegrityMethod ; + ns0:term_status "Stable" ; + sh:property [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:name "hashValue" ; + sh:path core:hashValue ], + [ sh:class core:HashAlgorithm ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:name "algorithm" ; + sh:path core:algorithm ] . + +security:ExploitCatalogType a owl:Class ; + rdfs:comment "ExploitCatalogType specifies the type of exploit catalog that a vulnerability is listed in." ; + ns0:term_status "Stable" . + +core:ElementCollection a owl:Class, + sh:NodeShape ; + rdfs:comment "An SpdxCollection is a collection of Elements, not necessarily with unifying context." ; + rdfs:subClassOf core:Element ; + ns0:term_status "Stable" ; + sh:property [ sh:class core:NamespaceMap ; + sh:name "namespaces" ; + sh:path core:namespaces ], + [ sh:class core:Element ; + sh:minCount 1 ; + sh:name "element" ; + sh:path core:element ], + [ sh:class core:ExternalMap ; + sh:name "imports" ; + sh:path core:imports ], + [ sh:class core:Element ; + sh:minCount 1 ; + sh:name "rootElement" ; + sh:path core:rootElement ] . + +core:IntegrityMethod a owl:Class, + sh:NodeShape ; + rdfs:comment """An IntegrityMethod provides an independently reproducible mechanism that permits verification +of a specific Element that correlates to the data in this SPDX document. This identifier enables +a recipient to determine if anything in the original Element has been changed and eliminates +confusion over which version or modification of a specific Element is referenced.""" ; + ns0:term_status "Stable" ; + sh:property [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "comment" ; + sh:path core:comment ] . + +core:MediaType a owl:Class, + sh:NodeShape ; + rdfs:comment """The MediaType is a String constrained to the RFC 2046 specification. It provides a standardized +way of indicating the type of content of an Element. +A list of all possible media types is available at https://www.iana.org/assignments/media-types/media-types.xhtml.""" ; + rdfs:subClassOf xsd:string ; + ns0:term_status "Stable" . + +core:Payload a owl:Class, + sh:NodeShape ; + rdfs:comment "TODO" ; + rdfs:subClassOf owl:Thing ; + ns0:term_status "Stable" ; + sh:property [ sh:class core:CreationInfo ; + sh:maxCount 1 ; + sh:name "creationInfo" ; + sh:path core:creationInfo ], + [ sh:class core:NamespaceMap ; + sh:name "namespaces" ; + sh:path core:namespaces ], + [ sh:class core:ExternalMap ; + sh:name "imports" ; + sh:path core:imports ] . + +core:RelationshipCompleteness a owl:Class ; + rdfs:comment """RelationshipCompleteness indicates whether a relationship is complete or +known to be incomplete or if there is made no assertion either way.""" ; + ns0:term_status "Stable" . + +core:comment a owl:DatatypeProperty ; + rdfs:comment """A comment is an optional field for creators of the Element to provide comments +to the readers/reviewers of the document.""" ; + rdfs:range xsd:string ; + ns0:term_status "Stable" ; + sh:or ( [ rdfs:domain core:CreationInfo, + core:Element, + core:ExternalIdentifier, + core:ExternalReference, + core:IntegrityMethod ] ) . + +ai:SafetyRiskAssessmentType a owl:Class ; + rdfs:comment """Lists the different safety risk type values that can be used to describe the safety risk of AI software +according to [Article 20 of Regulation 765/2008/EC](https://ec.europa.eu/docsroom/documents/17107/attachments/1/translations/en/renditions/pdf).""" ; + ns0:term_status "Stable" . + +core:ExternalReference a owl:Class, + sh:NodeShape ; + rdfs:comment """An External Reference points to a resource outside the scope of the SPDX-3.0 content +that provides additional characteristics of an Element.""" ; + rdfs:subClassOf owl:Thing ; + ns0:term_status "Stable" ; + sh:property [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "comment" ; + sh:path core:comment ], + [ sh:datatype core:MediaType ; + sh:maxCount 1 ; + sh:name "contentType" ; + sh:path core:contentType ], + [ sh:class core:ExternalReferenceType ; + sh:maxCount 1 ; + sh:name "externalReferenceType" ; + sh:path core:externalReferenceType ], + [ sh:datatype xsd:anyURI ; + sh:name "locator" ; + sh:path core:locator ] . + +core:NamespaceMap a owl:Class, + sh:NodeShape ; + rdfs:comment """A namespace map allows the creator of a collection of Elements to use +shorter identifiers ("prefixes") instead of URIs to provide a more +human-readable and smaller serialized representation of the Elements.""" ; + ns0:term_status "Stable" ; + sh:property [ sh:datatype xsd:anyURI ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:name "namespace" ; + sh:path core:namespace ], + [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:name "prefix" ; + sh:path core:prefix ] . + +core:PositiveIntegerRange a owl:Class, + sh:NodeShape ; + rdfs:comment """PositiveIntegerRange is a tuple of two positive integers that define a range. +"begin" must be less than or equal to "end".""" ; + rdfs:subClassOf owl:Thing ; + ns0:term_status "Stable" ; + sh:property [ sh:datatype xsd:positiveInteger ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:name "end" ; + sh:path core:end ], + [ sh:datatype xsd:positiveInteger ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:name "begin" ; + sh:path core:begin ] . + +dataset:ConfidentialityLevelType a owl:Class ; + rdfs:comment "Describes the different confidentiality levels as given by the [Traffic Light Protocol](https://en.wikipedia.org/wiki/Traffic_Light_Protocol)." ; + ns0:term_status "Stable" . + +security:SsvcDecisionType a owl:Class ; + rdfs:comment "SsvcDecisionType specifies the type of decision that's been made according to the Stakeholder-Specific Vulnerability Categorization (SSVC) system [https://www.cisa.gov/stakeholder-specific-vulnerability-categorization-ssvc](https://www.cisa.gov/stakeholder-specific-vulnerability-categorization-ssvc)" ; + ns0:term_status "Stable" . + +security:VexVulnAssessmentRelationship a owl:Class, + sh:NodeShape ; + rdfs:comment """VexVulnAssessmentRelationship is an abstract subclass that defined the common +properties shared by all the SPDX-VEX status relationships. + +**Constraints** + +When linking elements using a VexVulnAssessmentRelationship, the following +requirements must be observed: + +- The from: end must be a /Security/Vulnerability classed element +- The to: end must point to elements representing the VEX _products_. To +specify a different element where the vulnerability was detected, the VEX +relationship can optionally specify _subcomponents_ using the assessedElement +property. + +VEX inherits information from the document level down to its statements. When a +statement is missing information it can be completed by reading the equivalent +field from the containing document. For example, if a VEX relationship is +missing data in its createdBy property, tools must consider the entity +listed in the CreationInfo section of the document as the VEX author. +In the same way, when a VEX relationship does not have a created property, +the document's date must be considered as authoritative.""" ; + rdfs:subClassOf security:VulnAssessmentRelationship ; + ns0:term_status "Stable" ; + sh:property [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "statusNotes" ; + sh:path security:statusNotes ], + [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "vexVersion" ; + sh:path security:vexVersion ] . + +software:SoftwareDependencyLinkType a owl:Class ; + rdfs:comment "TODO" ; + ns0:term_status "Stable" . + +ai:PresenceType a owl:Class ; + rdfs:comment "This type is used to indicate if a given field is present or absent or unknown." ; + ns0:term_status "Stable" . + +core:Artifact a owl:Class, + sh:NodeShape ; + rdfs:comment """An artifact is a distinct article or unit within the digital domain, +such as an electronic file, a software package, a device or an element of data.""" ; + rdfs:subClassOf core:Element ; + ns0:term_status "Stable" ; + sh:property [ sh:class core:Agent ; + sh:name "originatedBy" ; + sh:path core:originatedBy ], + [ sh:datatype core:DateTime ; + sh:maxCount 1 ; + sh:name "builtTime" ; + sh:path core:builtTime ], + [ sh:datatype xsd:string ; + sh:name "standard" ; + sh:path core:standard ], + [ sh:datatype core:DateTime ; + sh:maxCount 1 ; + sh:name "releaseTime" ; + sh:path core:releaseTime ], + [ sh:datatype core:DateTime ; + sh:maxCount 1 ; + sh:name "validUntilTime" ; + sh:path core:validUntilTime ], + [ sh:class core:Agent ; + sh:name "suppliedBy" ; + sh:path core:suppliedBy ] . + +core:ExternalIdentifier a owl:Class, + sh:NodeShape ; + rdfs:comment """An ExternalIdentifier is a reference to a resource outside the scope of SPDX-3.0 content +that uniquely identifies an Element.""" ; + ns0:term_status "Stable" ; + sh:property [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:name "identifier" ; + sh:path core:identifier ], + [ sh:class core:ExternalIdentifierType ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:name "externalIdentifierType" ; + sh:path core:externalIdentifierType ], + [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "comment" ; + sh:path core:comment ], + [ sh:datatype xsd:anyURI ; + sh:maxCount 1 ; + sh:name "issuingAuthority" ; + sh:path core:issuingAuthority ], + [ sh:datatype xsd:anyURI ; + sh:name "identifierLocator" ; + sh:path core:identifierLocator ] . + +dataset:DatasetAvailabilityType a owl:Class ; + rdfs:comment "Describes the possible types of availability of a dataset, indicating whether the dataset can be directly downloaded, can be assembled using a script for scraping the data, is only available after a clickthrough or a registration form." ; + ns0:term_status "Stable" . + +licensing:LicenseAddition a owl:Class, + sh:NodeShape ; + rdfs:comment """A LicenseAddition represents text which is intended to be added to a License +as additional text, but which is not itself intended to be a standalone +License. + +It may be an exception which is listed on the SPDX Exceptions List +(ListedLicenseException), or may be any other additional text (as an exception +or otherwise) which is defined by an SPDX data creator (CustomLicenseAddition).""" ; + rdfs:subClassOf core:Element ; + ns0:term_status "Stable" ; + sh:property [ sh:datatype xsd:boolean ; + sh:maxCount 1 ; + sh:name "isDeprecatedAdditionId" ; + sh:path licensing:isDeprecatedAdditionId ], + [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:name "additionText" ; + sh:path licensing:additionText ], + [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "standardAdditionTemplate" ; + sh:path licensing:standardAdditionTemplate ], + [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "obsoletedBy" ; + sh:path licensing:obsoletedBy ] . + +security:VexJustificationType a owl:Class ; + rdfs:comment "VexJustificationType specifies the type of Vulnerability Exploitability eXchange (VEX) justification." ; + ns0:term_status "Stable" . + +software:DependencyConditionalityType a owl:Class ; + rdfs:comment "TODO" ; + ns0:term_status "Stable" . + +software:Package a owl:Class, + sh:NodeShape ; + rdfs:comment """A package refers to any unit of content that can be associated with a distribution of software. +Typically, a package is composed of one or more files. +Any of the following non-limiting examples may be (but are not required to be) represented in SPDX as a package: + + - a tarball, zip file or other archive + - a directory or sub-directory + - a separately distributed piece of software which another Package or File uses or depends upon (e.g., a Python package, a Go module, ...) + - a container image, and/or each image layer within a container image + - a collection of one or more sub-packages + - a Git repository snapshot from a particular point in time + +Note that some of these could be represented in SPDX as a file as well. +External property restriction on /Core/Element/name: minCount: 1""" ; + rdfs:subClassOf software:SoftwareArtifact ; + ns0:term_status "Stable" ; + sh:property [ sh:datatype xsd:anyURI ; + sh:maxCount 1 ; + sh:name "packageUrl" ; + sh:path software:packageUrl ], + [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "sourceInfo" ; + sh:path software:sourceInfo ], + [ sh:datatype xsd:anyURI ; + sh:maxCount 1 ; + sh:name "downloadLocation" ; + sh:path software:downloadLocation ], + [ sh:datatype xsd:anyURI ; + sh:maxCount 1 ; + sh:name "homePage" ; + sh:path software:homePage ], + [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "packageVersion" ; + sh:path software:packageVersion ] . + +core:ExternalMap a owl:Class, + sh:NodeShape ; + rdfs:comment """An External Map is a map of Element identifiers that are used within a Document +but defined external to that Document. +The external map provides details about the externally-defined Element +such as its provenance, where to retrieve it, and how to verify its integrity.""" ; + rdfs:subClassOf owl:Thing ; + ns0:term_status "Stable" ; + sh:property [ sh:datatype xsd:anyURI ; + sh:maxCount 1 ; + sh:name "locationHint" ; + sh:path core:locationHint ], + [ sh:datatype xsd:anyURI ; + sh:maxCount 1 ; + sh:name "definingDocument" ; + sh:path core:definingDocument ], + [ sh:datatype xsd:anyURI ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:name "externalId" ; + sh:path core:externalId ], + [ sh:class core:IntegrityMethod ; + sh:name "verifiedUsing" ; + sh:path core:verifiedUsing ] . + +core:LifecycleScopeType a owl:Class ; + rdfs:comment "TODO" ; + ns0:term_status "Stable" . + +core:Relationship a owl:Class, + sh:NodeShape ; + rdfs:comment """A Relationship is a grouping of characteristics unique to an assertion +that one Element is related to one or more other Elements in some way.""" ; + rdfs:subClassOf core:Element ; + ns0:term_status "Stable" ; + sh:property [ sh:datatype core:DateTime ; + sh:maxCount 1 ; + sh:name "startTime" ; + sh:path core:startTime ], + [ sh:class core:RelationshipCompleteness ; + sh:maxCount 1 ; + sh:name "completeness" ; + sh:path core:completeness ], + [ sh:datatype core:DateTime ; + sh:maxCount 1 ; + sh:name "endTime" ; + sh:path core:endTime ], + [ sh:class core:RelationshipType ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:name "relationshipType" ; + sh:path core:relationshipType ], + [ sh:class core:Element ; + sh:name "to" ; + sh:path core:to ], + [ sh:class core:Element ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:name "from" ; + sh:path core:from ] . + +software:SBOMType a owl:Class ; + rdfs:comment """The set of SBOM types with definitions as defined in [Types of Software Bill of Material (SBOM) Documents](https://www.cisa.gov/sites/default/files/2023-04/sbom-types-document-508c.pdf), published on April 21, 2023. +An SBOM type describes the most likely type of an SBOM from the producer perspective, so that consumers can draw conclusions about the data inside an SBOM. A single SBOM can have multiple SBOM document types associated with it.""" ; + ns0:term_status "Stable" . + +build:Build a owl:Class, + sh:NodeShape ; + rdfs:comment """A build is a representation of the process in which a piece of software or artifact is built. It encapsulates information related to a build process and +provides an element from which relationships can be created to describe the build's inputs, outputs, and related entities (e.g. builders, identities, etc.). + +Definitions of "BuildType", "ConfigSource", "Parameters" and "Environment" follow +those defined in [SLSA provenance](https://slsa.dev/provenance/v0.2). + +ExternalIdentifier of type "urlScheme" may be used to identify build logs. In this case, the comment of the ExternalIdentifier should be "LogReference". + +Note that buildStart and buildEnd are optional, and may be omitted to simplify creating reproducible builds.""" ; + rdfs:subClassOf core:Element ; + ns0:term_status "Stable" ; + sh:property [ sh:datatype core:DateTime ; + sh:maxCount 1 ; + sh:name "buildEndTime" ; + sh:path build:buildEndTime ], + [ sh:datatype core:DateTime ; + sh:maxCount 1 ; + sh:name "buildStartTime" ; + sh:path build:buildStartTime ], + [ sh:datatype xsd:anyURI ; + sh:name "configSourceUri" ; + sh:path build:configSourceUri ], + [ sh:class core:Hash ; + sh:name "configSourceDigest" ; + sh:path build:configSourceDigest ], + [ sh:class core:DictionaryEntry ; + sh:name "environment" ; + sh:path build:environment ], + [ sh:class core:DictionaryEntry ; + sh:name "parameters" ; + sh:path build:parameters ], + [ sh:datatype xsd:anyURI ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:name "buildType" ; + sh:path build:buildType ], + [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "buildId" ; + sh:path build:buildId ], + [ sh:datatype xsd:string ; + sh:name "configSourceEntrypoint" ; + sh:path build:configSourceEntrypoint ] . + +software:SoftwareArtifact a owl:Class, + sh:NodeShape ; + rdfs:comment """A software artifact is a distinct article or unit related to software +such as a package, a file, or a snippet.""" ; + rdfs:subClassOf core:Artifact ; + ns0:term_status "Stable" ; + sh:property [ sh:datatype xsd:anyURI ; + sh:maxCount 1 ; + sh:name "contentIdentifier" ; + sh:path software:contentIdentifier ], + [ sh:class licensing:AnyLicenseInfo ; + sh:maxCount 1 ; + sh:name "concludedLicense" ; + sh:path software:concludedLicense ], + [ sh:class software:SoftwarePurpose ; + sh:name "additionalPurpose" ; + sh:path software:additionalPurpose ], + [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "attributionText" ; + sh:path software:attributionText ], + [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "copyrightText" ; + sh:path software:copyrightText ], + [ sh:class software:SoftwarePurpose ; + sh:maxCount 1 ; + sh:name "primaryPurpose" ; + sh:path software:primaryPurpose ], + [ sh:class licensing:AnyLicenseInfo ; + sh:maxCount 1 ; + sh:name "declaredLicense" ; + sh:path software:declaredLicense ] . + +core:Agent a owl:Class, + sh:NodeShape ; + rdfs:comment "The Agent class represents anything that has the potential to act on a system. This could be a person, organization, software agent, etc. This is not to be confused with tools that are used to perform tasks." ; + rdfs:subClassOf core:Element ; + ns0:term_status "Stable" . + +core:CreationInfo a owl:Class, + sh:NodeShape ; + rdfs:comment """The CreationInfo provides information about who created the Element, and when and how it was created. + +The dateTime created is often the date of last change (e.g., a git commit date), not the date when the SPDX data was created, as doing so supports reproducible builds.""" ; + ns0:term_status "Stable" ; + sh:property [ sh:datatype xsd:string ; + sh:name "dataLicense" ; + sh:path core:dataLicense ], + [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "comment" ; + sh:path core:comment ], + [ sh:datatype core:SemVer ; + sh:name "specVersion" ; + sh:path core:specVersion ], + [ sh:datatype core:DateTime ; + sh:name "created" ; + sh:path core:created ], + [ sh:class core:Tool ; + sh:name "createdUsing" ; + sh:path core:createdUsing ], + [ sh:class core:ProfileIdentifierType ; + sh:minCount 1 ; + sh:name "profile" ; + sh:path core:profile ], + [ sh:class core:Agent ; + sh:minCount 1 ; + sh:name "createdBy" ; + sh:path core:createdBy ] . + +core:ProfileIdentifierType a owl:Class ; + rdfs:comment "There are a set of profiles that have been defined to be valid for a specific release This file enumerates the values that have been agreed on, and may be applied to the creation information for an an element." ; + ns0:term_status "Stable" . + +licensing:License a owl:Class, + sh:NodeShape ; + rdfs:comment """A License represents a license text, whether listed on the SPDX License List +(ListedLicense) or defined by an SPDX data creator (CustomLicense).""" ; + rdfs:subClassOf expandedlicense:ExtendableLicense ; + ns0:term_status "Stable" ; + sh:property [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "standardLicenseHeader" ; + sh:path licensing:standardLicenseHeader ], + [ sh:datatype xsd:boolean ; + sh:maxCount 1 ; + sh:name "isOsiApproved" ; + sh:path licensing:isOsiApproved ], + [ sh:datatype xsd:boolean ; + sh:maxCount 1 ; + sh:name "isDeprecatedLicenseId" ; + sh:path licensing:isDeprecatedLicenseId ], + [ sh:datatype xsd:boolean ; + sh:maxCount 1 ; + sh:name "isFsfLibre" ; + sh:path licensing:isFsfLibre ], + [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "obsoletedBy" ; + sh:path licensing:obsoletedBy ], + [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:name "licenseText" ; + sh:path licensing:licenseText ], + [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "standardLicenseTemplate" ; + sh:path licensing:standardLicenseTemplate ] . + +security:VulnAssessmentRelationship a owl:Class, + sh:NodeShape ; + rdfs:comment """VulnAssessmentRelationship is the ancestor class common to all vulnerability +assessment relationships. It factors out the common properties shared by them. +External property restriction on /Core/Relationship/to: minCount: 1""" ; + rdfs:subClassOf core:Relationship ; + ns0:term_status "Stable" ; + sh:property [ sh:datatype core:DateTime ; + sh:maxCount 1 ; + sh:name "publishedTime" ; + sh:path security:publishedTime ], + [ sh:datatype core:DateTime ; + sh:maxCount 1 ; + sh:name "modifiedTime" ; + sh:path security:modifiedTime ], + [ sh:class core:Element ; + sh:maxCount 1 ; + sh:name "assessedElement" ; + sh:path security:assessedElement ], + [ sh:datatype core:DateTime ; + sh:maxCount 1 ; + sh:name "withdrawnTime" ; + sh:path security:withdrawnTime ], + [ sh:class core:Agent ; + sh:maxCount 1 ; + sh:name "suppliedBy" ; + sh:path security:suppliedBy ] . + +licensing:AnyLicenseInfo a owl:Class, + sh:NodeShape ; + rdfs:comment """An AnyLicenseInfo is used by licensing properties of software artifacts. +It can be a NoneLicense, a NoAssertionLicense, +single license (either on the SPDX License List or a custom-defined license); +a single license with an "or later" operator applied; the foregoing with +additional text applied; or a set of licenses combined by applying "AND" and +"OR" operators recursively.""" ; + rdfs:subClassOf core:Element ; + ns0:term_status "Stable" . + +core:ExternalIdentifierType a owl:Class ; + rdfs:comment "ExteralIdentifierType specifies the type of an external identifier." ; + ns0:term_status "Stable" . + +dataset:Dataset a owl:Class, + sh:NodeShape ; + rdfs:comment """Metadata information that can be added to a dataset that may be used in a software or to train/test an AI package. +External property restriction on /Core/Artifact/originatedBy: minCount: 1 +External property restriction on /Software/Package/downloadLocation: minCount: 1 +External property restriction on /Software/SoftwareArtifact/primaryPurpose: minCount: 1 +External property restriction on /Core/Artifact/releaseTime: minCount: 1 +External property restriction on /Core/Artifact/builtTime: minCount: 1""" ; + rdfs:subClassOf software:Package ; + ns0:term_status "Stable" ; + sh:property [ sh:class dataset:DatasetType ; + sh:minCount 1 ; + sh:name "datasetType" ; + sh:path dataset:datasetType ], + [ sh:datatype xsd:string ; + sh:name "dataPreprocessing" ; + sh:path dataset:dataPreprocessing ], + [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "datasetUpdateMechanism" ; + sh:path dataset:datasetUpdateMechanism ], + [ sh:datatype xsd:nonNegativeInteger ; + sh:maxCount 1 ; + sh:name "datasetSize" ; + sh:path dataset:datasetSize ], + [ sh:datatype dataset:PresenceType ; + sh:maxCount 1 ; + sh:name "sensitivePersonalInformation" ; + sh:path dataset:sensitivePersonalInformation ], + [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "dataCollectionProcess" ; + sh:path dataset:dataCollectionProcess ], + [ sh:class dataset:ConfidentialityLevelType ; + sh:maxCount 1 ; + sh:name "confidentialityLevel" ; + sh:path dataset:confidentialityLevel ], + [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "datasetNoise" ; + sh:path dataset:datasetNoise ], + [ sh:class core:DictionaryEntry ; + sh:name "sensor" ; + sh:path dataset:sensor ], + [ sh:class dataset:DatasetAvailabilityType ; + sh:maxCount 1 ; + sh:name "datasetAvailability" ; + sh:path dataset:datasetAvailability ], + [ sh:datatype xsd:string ; + sh:name "knownBias" ; + sh:path dataset:knownBias ], + [ sh:datatype xsd:string ; + sh:name "anonymizationMethodUsed" ; + sh:path dataset:anonymizationMethodUsed ], + [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "intendedUse" ; + sh:path dataset:intendedUse ] . + +core:DictionaryEntry a owl:Class, + sh:NodeShape ; + rdfs:comment "The class used for implementing a generic string mapping (also known as associative array, dictionary, or hash map) in SPDX. Each DictionaryEntry contains a key-value pair which maps the key to its associated value. To implement a dictionary, this class is to be used in a collection with unique keys." ; + ns0:term_status "Stable" ; + sh:property [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:minCount 1 ; + sh:name "key" ; + sh:path core:key ], + [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "value" ; + sh:path core:value ] . + +ai:AIPackage a owl:Class, + sh:NodeShape ; + rdfs:comment """Metadata information that can be added to a package to describe an AI application or trained AI model. +External property restriction on /Core/Artifact/suppliedBy: minCount: 1 +External property restriction on /Software/Package/downloadLocation: minCount: 1 +External property restriction on /Software/Package/packageVersion: minCount: 1 +External property restriction on /Software/SoftwareArtifact/primaryPurpose: minCount: 1 +External property restriction on /Core/Artifact/releaseTime: minCount: 1""" ; + rdfs:subClassOf software:Package ; + ns0:term_status "Stable" ; + sh:property [ sh:datatype xsd:string ; + sh:name "standardCompliance" ; + sh:path ai:standardCompliance ], + [ sh:datatype xsd:string ; + sh:name "modelDataPreprocessing" ; + sh:path ai:modelDataPreprocessing ], + [ sh:class ai:PresenceType ; + sh:maxCount 1 ; + sh:name "sensitivePersonalInformation" ; + sh:path ai:sensitivePersonalInformation ], + [ sh:datatype xsd:string ; + sh:name "domain" ; + sh:path ai:domain ], + [ sh:class core:DictionaryEntry ; + sh:name "metric" ; + sh:path ai:metric ], + [ sh:class core:DictionaryEntry ; + sh:name "hyperparameter" ; + sh:path ai:hyperparameter ], + [ sh:datatype xsd:string ; + sh:name "typeOfModel" ; + sh:path ai:typeOfModel ], + [ sh:class core:DictionaryEntry ; + sh:name "metricDecisionThreshold" ; + sh:path ai:metricDecisionThreshold ], + [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "informationAboutTraining" ; + sh:path ai:informationAboutTraining ], + [ sh:class ai:SafetyRiskAssessmentType ; + sh:maxCount 1 ; + sh:name "safetyRiskAssessment" ; + sh:path ai:safetyRiskAssessment ], + [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "energyConsumption" ; + sh:path ai:energyConsumption ], + [ sh:datatype xsd:string ; + sh:name "modelExplainability" ; + sh:path ai:modelExplainability ], + [ sh:class ai:PresenceType ; + sh:maxCount 1 ; + sh:name "autonomyType" ; + sh:path ai:autonomyType ], + [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "informationAboutApplication" ; + sh:path ai:informationAboutApplication ], + [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "limitation" ; + sh:path ai:limitation ] . + +dataset:DatasetType a owl:Class ; + rdfs:comment "Describes the different structures of data within a given dataset. A dataset can have multiple types of data, or even a single type of data but still match multiple types, for example sensor data could also be timeseries or labeled image data could also be considered categorical." ; + ns0:term_status "Stable" . + +core:HashAlgorithm a owl:Class ; + rdfs:comment """A HashAlgorithm is a mathematical algorithm that maps data of arbitrary size to a bit string (the hash) +and is a one-way function, that is, a function which is practically infeasible to invert.""" ; + ns0:term_status "Stable" . + +core:DateTime a owl:Class, + sh:NodeShape ; + rdfs:comment """A Datetime is a string representation of a specific date and time. +It has resolution of seconds and is always expressed in UTC timezone. +The specific format is one of the most commonly used ISO-8601 formats. +Format restriction: pattern: ^\\d\\d\\d\\d-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\dZ$""" ; + rdfs:subClassOf xsd:string ; + ns0:term_status "Stable" . + +software:SoftwarePurpose a owl:Class ; + rdfs:comment """This field provides information about the primary purpose of an Element. +Software Purpose is intrinsic to how the Element is being used rather than the content of the Element. +This field is a reasonable estimate of the most likely usage of the Element +from the producer and consumer perspective from which both parties can draw conclusions +about the context in which the Element exists.""" ; + ns0:term_status "Stable" . + +core:Element a owl:Class, + sh:NodeShape ; + rdfs:comment """An Element is a representation of a fundamental concept either directly inherent +to the Bill of Materials (BOM) domain or indirectly related to the BOM domain +and necessary for contextually characterizing BOM concepts and relationships. +Within SPDX-3.0 structure this is the base class acting as a consistent, +unifying, and interoperable foundation for all explicit +and inter-relatable content objects.""" ; + rdfs:subClassOf core:Payload ; + ns0:term_status "Stable" ; + sh:property [ sh:datatype core:Extension ; + sh:name "extension" ; + sh:path core:extension ], + [ sh:class core:CreationInfo ; + sh:maxCount 1 ; + sh:name "creationInfo" ; + sh:path core:creationInfo ], + [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "description" ; + sh:path core:description ], + [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "name" ; + sh:path core:name ], + [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "comment" ; + sh:path core:comment ], + [ sh:class core:IntegrityMethod ; + sh:name "verifiedUsing" ; + sh:path core:verifiedUsing ], + [ sh:class core:ExternalReference ; + sh:name "externalReference" ; + sh:path core:externalReference ], + [ sh:datatype xsd:string ; + sh:maxCount 1 ; + sh:name "summary" ; + sh:path core:summary ], + [ sh:class core:ExternalIdentifier ; + sh:name "externalIdentifier" ; + sh:path core:externalIdentifier ] . + +core:ExternalReferenceType a owl:Class ; + rdfs:comment "ExteralReferenceType specifies the type of an external reference." ; + ns0:term_status "Stable" . + +core:RelationshipType a owl:Class ; + rdfs:comment """Provides information about the relationship between two Elements. +For example, you can represent a relationship between two different Files, +between a Package and a File, between two Packages, or between one SPDXDocument and another SPDXDocument.""" ; + ns0:term_status "Stable" . +