xref: /aosp_15_r20/external/spdx-tools/rdfloader/parser2v3/parse_spdx_document.go (revision ba677afa8f67bb56cbc794f4d0e378e0da058e16)
1// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
2
3package parser2v3
4
5import (
6	"fmt"
7
8	gordfParser "github.com/spdx/gordf/rdfloader/parser"
9	"github.com/spdx/tools-golang/spdx/common"
10	"github.com/spdx/tools-golang/spdx/v2_3"
11)
12
13func (parser *rdfParser2_3) parseSpdxDocumentNode(spdxDocNode *gordfParser.Node) (err error) {
14	// shorthand for document's creation info.
15	ci := parser.doc.CreationInfo
16
17	// parse the document header information (SPDXID and document namespace)
18	// the Subject.ID is of type baseURI#spdxID
19	baseUri, offset, err := ExtractSubs(spdxDocNode.ID, "#")
20	if err != nil {
21		return err
22	}
23	parser.doc.DocumentNamespace = baseUri               // 2.5
24	parser.doc.SPDXIdentifier = common.ElementID(offset) // 2.3
25
26	// parse other associated triples.
27	for _, subTriple := range parser.nodeToTriples(spdxDocNode) {
28		objectValue := subTriple.Object.ID
29		switch subTriple.Predicate.ID {
30		case RDF_TYPE:
31			continue
32		case SPDX_SPEC_VERSION: // 2.1: specVersion
33			// cardinality: exactly 1
34			parser.doc.SPDXVersion = objectValue
35		case SPDX_DATA_LICENSE: // 2.2: dataLicense
36			// cardinality: exactly 1
37			dataLicense, err := parser.getAnyLicenseFromNode(subTriple.Object)
38			if err != nil {
39				return err
40			}
41			parser.doc.DataLicense = dataLicense.ToLicenseString()
42		case SPDX_NAME: // 2.4: DocumentName
43			// cardinality: exactly 1
44			parser.doc.DocumentName = objectValue
45		case SPDX_EXTERNAL_DOCUMENT_REF: // 2.6: externalDocumentReferences
46			// cardinality: min 0
47			var extRef v2_3.ExternalDocumentRef
48			extRef, err = parser.getExternalDocumentRefFromNode(subTriple.Object)
49			if err != nil {
50				return err
51			}
52			parser.doc.ExternalDocumentReferences = append(parser.doc.ExternalDocumentReferences, extRef)
53		case SPDX_CREATION_INFO: // 2.7 - 2.10:
54			// cardinality: exactly 1
55			err = parser.parseCreationInfoFromNode(ci, subTriple.Object)
56		case RDFS_COMMENT: // 2.11: Document Comment
57			// cardinality: max 1
58			parser.doc.DocumentComment = objectValue
59		case SPDX_REVIEWED: // reviewed:
60			// cardinality: min 0
61			err = parser.setReviewFromNode(subTriple.Object)
62		case SPDX_DESCRIBES_PACKAGE: // describes Package
63			// cardinality: min 0
64			var pkg *v2_3.Package
65			pkg, err = parser.getPackageFromNode(subTriple.Object)
66			if err != nil {
67				return err
68			}
69			parser.doc.Packages = append(parser.doc.Packages, pkg)
70		case SPDX_HAS_EXTRACTED_LICENSING_INFO: // hasExtractedLicensingInfo
71			// cardinality: min 0
72			extractedLicensingInfo, err := parser.getExtractedLicensingInfoFromNode(subTriple.Object)
73			if err != nil {
74				return fmt.Errorf("error setting extractedLicensingInfo in spdxDocument: %v", err)
75			}
76			othLicense := parser.extractedLicenseToOtherLicense(extractedLicensingInfo)
77			parser.doc.OtherLicenses = append(parser.doc.OtherLicenses, &othLicense)
78		case SPDX_RELATIONSHIP: // relationship
79			// cardinality: min 0
80			err = parser.parseRelationship(subTriple)
81		case SPDX_ANNOTATION: // annotations
82			// cardinality: min 0
83			err = parser.parseAnnotationFromNode(subTriple.Object)
84		default:
85			return fmt.Errorf("invalid predicate while parsing SpdxDocument: %v", subTriple.Predicate)
86		}
87		if err != nil {
88			return err
89		}
90	}
91	return nil
92}
93
94func (parser *rdfParser2_3) getExternalDocumentRefFromNode(node *gordfParser.Node) (edr v2_3.ExternalDocumentRef, err error) {
95	for _, triple := range parser.nodeToTriples(node) {
96		switch triple.Predicate.ID {
97		case SPDX_EXTERNAL_DOCUMENT_ID:
98			// cardinality: exactly 1
99			edr.DocumentRefID = triple.Object.ID
100		case SPDX_SPDX_DOCUMENT:
101			// cardinality: exactly 1
102			// assumption: "spdxDocument" property of an external document
103			// reference is just a uri which doesn't follow a spdxDocument definition
104			edr.URI = triple.Object.ID
105		case SPDX_CHECKSUM:
106			// cardinality: exactly 1
107			alg, checksum, err := parser.getChecksumFromNode(triple.Object)
108			if err != nil {
109				return edr, err
110			}
111			edr.Checksum.Value = checksum
112			edr.Checksum.Algorithm = alg
113		case RDF_TYPE:
114			continue
115		default:
116			return edr, fmt.Errorf("unknown predicate ID (%s) while parsing externalDocumentReference", triple.Predicate.ID)
117		}
118	}
119	return edr, nil
120}
121