1// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 2 3package parser2v3 4 5import ( 6 "errors" 7 "fmt" 8 "strings" 9 10 gordfParser "github.com/spdx/gordf/rdfloader/parser" 11 "github.com/spdx/gordf/rdfwriter" 12) 13 14// AnyLicense is a baseClass for all the licenses 15// All the types of licenses is a sub-type of AnyLicense, 16// either directly or indirectly. 17// This function acts as a mux for all the licenses. Based on the input, it 18// decides which type of license it is and passes control to that type of 19// license parser to parse the given input. 20func (parser *rdfParser2_3) getAnyLicenseFromNode(node *gordfParser.Node) (AnyLicenseInfo, error) { 21 22 currState := parser.cache[node.ID] 23 if currState == nil { 24 // there is no entry about the state of current package node. 25 // this is the first time we're seeing this node. 26 parser.cache[node.ID] = &nodeState{ 27 object: nil, // not storing the object as we won't retrieve it later. 28 Color: WHITE, 29 } 30 } else if currState.Color == GREY { 31 // we have already started parsing this license node. 32 // We have a cyclic dependency! 33 return nil, errors.New("Couldn't parse license: found a cyclic dependency on " + node.ID) 34 } 35 36 // setting color of the state to grey to indicate that we've started to 37 // parse this node once. 38 parser.cache[node.ID].Color = GREY 39 40 // setting state color to black when we're done parsing this node. 41 defer func() { parser.cache[node.ID].Color = BLACK }() 42 43 associatedTriples := rdfwriter.FilterTriples(parser.gordfParserObj.Triples, &node.ID, nil, nil) 44 if len(associatedTriples) == 0 { 45 // just a license uri string was found. 46 return parser.getSpecialLicenseFromNode(node) 47 } 48 49 // we have some attributes associated with the license node. 50 nodeType, err := getNodeTypeFromTriples(associatedTriples, node) 51 if err != nil { 52 return nil, fmt.Errorf("error parsing license triple: %v", err) 53 } 54 switch nodeType { 55 case SPDX_DISJUNCTIVE_LICENSE_SET: 56 return parser.getDisjunctiveLicenseSetFromNode(node) 57 case SPDX_CONJUNCTIVE_LICENSE_SET: 58 return parser.getConjunctiveLicenseSetFromNode(node) 59 case SPDX_EXTRACTED_LICENSING_INFO: 60 return parser.getExtractedLicensingInfoFromNode(node) 61 case SPDX_LISTED_LICENSE, SPDX_LICENSE: 62 return parser.getLicenseFromNode(node) 63 case SPDX_WITH_EXCEPTION_OPERATOR: 64 return parser.getWithExceptionOperatorFromNode(node) 65 case SPDX_OR_LATER_OPERATOR: 66 return parser.getOrLaterOperatorFromNode(node) 67 case SPDX_SIMPLE_LICENSING_INFO: 68 return parser.getSimpleLicensingInfoFromNode(node) 69 } 70 return nil, fmt.Errorf("Unknown subTag (%s) found while parsing AnyLicense", nodeType) 71} 72 73func (parser *rdfParser2_3) getLicenseExceptionFromNode(node *gordfParser.Node) (exception LicenseException, err error) { 74 associatedTriples := rdfwriter.FilterTriples(parser.gordfParserObj.Triples, &node.ID, nil, nil) 75 for _, triple := range associatedTriples { 76 value := triple.Object.ID 77 switch triple.Predicate.ID { 78 case RDF_TYPE: 79 continue 80 case SPDX_LICENSE_EXCEPTION_ID: 81 exception.licenseExceptionId = value 82 case SPDX_LICENSE_EXCEPTION_TEXT: 83 exception.licenseExceptionText = value 84 case RDFS_SEE_ALSO: 85 if !isUriValid(value) { 86 return exception, fmt.Errorf("invalid uri (%s) for seeAlso attribute of LicenseException", value) 87 } 88 exception.seeAlso = value 89 case SPDX_NAME: 90 exception.name = value 91 case SPDX_EXAMPLE: 92 exception.example = value 93 case RDFS_COMMENT: 94 exception.comment = value 95 default: 96 return exception, fmt.Errorf("invalid predicate(%s) for LicenseException", triple.Predicate) 97 } 98 } 99 return exception, nil 100} 101 102func (parser *rdfParser2_3) getSimpleLicensingInfoFromNode(node *gordfParser.Node) (SimpleLicensingInfo, error) { 103 simpleLicensingTriples := rdfwriter.FilterTriples(parser.gordfParserObj.Triples, &node.ID, nil, nil) 104 return parser.getSimpleLicensingInfoFromTriples(simpleLicensingTriples) 105} 106 107func (parser *rdfParser2_3) getWithExceptionOperatorFromNode(node *gordfParser.Node) (operator WithExceptionOperator, err error) { 108 associatedTriples := rdfwriter.FilterTriples(parser.gordfParserObj.Triples, &node.ID, nil, nil) 109 var memberFound bool 110 for _, triple := range associatedTriples { 111 switch triple.Predicate.ID { 112 case RDF_TYPE: 113 continue 114 case SPDX_MEMBER: 115 if memberFound { 116 return operator, 117 fmt.Errorf("more than one member found in the WithExceptionOperator (expected only 1)") 118 } 119 memberFound = true 120 member, err := parser.getSimpleLicensingInfoFromNode(triple.Object) 121 if err != nil { 122 return operator, fmt.Errorf("error parsing member of a WithExceptionOperator: %v", err) 123 } 124 operator.member = member 125 case SPDX_LICENSE_EXCEPTION: 126 operator.licenseException, err = parser.getLicenseExceptionFromNode(triple.Object) 127 if err != nil { 128 return operator, fmt.Errorf("error parsing licenseException of WithExceptionOperator: %v", err) 129 } 130 default: 131 return operator, fmt.Errorf("unknown predicate (%s) for a WithExceptionOperator", triple.Predicate.ID) 132 } 133 } 134 return operator, nil 135} 136 137func (parser *rdfParser2_3) getOrLaterOperatorFromNode(node *gordfParser.Node) (operator OrLaterOperator, err error) { 138 associatedTriples := rdfwriter.FilterTriples(parser.gordfParserObj.Triples, &node.ID, nil, nil) 139 n := len(associatedTriples) 140 if n != 2 { 141 return operator, fmt.Errorf("orLaterOperator must be associated with exactly one tag. found %v triples", n-1) 142 } 143 for _, triple := range associatedTriples { 144 switch triple.Predicate.ID { 145 case RDF_TYPE: 146 continue 147 case SPDX_MEMBER: 148 operator.member, err = parser.getSimpleLicensingInfoFromNode(triple.Object) 149 if err != nil { 150 return operator, fmt.Errorf("error parsing simpleLicensingInfo of OrLaterOperator: %v", err) 151 } 152 default: 153 return operator, fmt.Errorf("unknown predicate %s", triple.Predicate.ID) 154 } 155 } 156 return operator, nil 157} 158 159// SpecialLicense is a type of license which is not defined in any of the 160// spdx documents, it is a type of license defined for the sake of brevity. 161// It can be [NONE|NOASSERTION|LicenseRef-<string>] 162func (parser *rdfParser2_3) getSpecialLicenseFromNode(node *gordfParser.Node) (lic SpecialLicense, err error) { 163 uri := strings.TrimSpace(node.ID) 164 switch uri { 165 case SPDX_NONE_CAPS, SPDX_NONE_SMALL: 166 return SpecialLicense{ 167 value: NONE, 168 }, nil 169 case SPDX_NOASSERTION_SMALL, SPDX_NOASSERTION_CAPS: 170 return SpecialLicense{ 171 value: NOASSERTION, 172 }, nil 173 } 174 175 // the license is neither NONE nor NOASSERTION 176 // checking if the license is among the standardLicenses 177 licenseAbbreviation := getLastPartOfURI(uri) 178 for _, stdLicense := range AllStandardLicenseIDS() { 179 if licenseAbbreviation == stdLicense { 180 return SpecialLicense{ 181 value: SpecialLicenseValue(stdLicense), 182 }, nil 183 } 184 } 185 return lic, fmt.Errorf("found a custom license uri (%s) without any associated fields", uri) 186} 187 188func (parser *rdfParser2_3) getDisjunctiveLicenseSetFromNode(node *gordfParser.Node) (DisjunctiveLicenseSet, error) { 189 licenseSet := DisjunctiveLicenseSet{ 190 members: []AnyLicenseInfo{}, 191 } 192 for _, triple := range parser.nodeToTriples(node) { 193 switch triple.Predicate.ID { 194 case RDF_TYPE: 195 continue 196 case SPDX_MEMBER: 197 member, err := parser.getAnyLicenseFromNode(triple.Object) 198 if err != nil { 199 return licenseSet, fmt.Errorf("error parsing disjunctive license set: %v", err) 200 } 201 licenseSet.members = append(licenseSet.members, member) 202 } 203 } 204 return licenseSet, nil 205} 206 207func (parser *rdfParser2_3) getConjunctiveLicenseSetFromNode(node *gordfParser.Node) (ConjunctiveLicenseSet, error) { 208 licenseSet := ConjunctiveLicenseSet{ 209 members: []AnyLicenseInfo{}, 210 } 211 for _, triple := range parser.nodeToTriples(node) { 212 switch triple.Predicate.ID { 213 case RDF_TYPE: 214 continue 215 case SPDX_MEMBER: 216 member, err := parser.getAnyLicenseFromNode(triple.Object) 217 if err != nil { 218 return licenseSet, fmt.Errorf("error parsing conjunctive license set: %v", err) 219 } 220 licenseSet.members = append(licenseSet.members, member) 221 default: 222 return licenseSet, fmt.Errorf("unknown subTag for ConjunctiveLicenseSet: %s", triple.Predicate.ID) 223 } 224 } 225 return licenseSet, nil 226} 227 228func (parser *rdfParser2_3) getSimpleLicensingInfoFromTriples(triples []*gordfParser.Triple) (lic SimpleLicensingInfo, err error) { 229 for _, triple := range triples { 230 switch triple.Predicate.ID { 231 case RDFS_COMMENT: 232 lic.comment = triple.Object.ID 233 case SPDX_LICENSE_ID: 234 lic.licenseID = triple.Object.ID 235 case SPDX_NAME: 236 lic.name = triple.Object.ID 237 case RDFS_SEE_ALSO: 238 if !isUriValid(triple.Object.ID) { 239 return lic, fmt.Errorf("%s is not a valid uri for seeAlso attribute of a License", triple.Object.ID) 240 } 241 lic.seeAlso = append(lic.seeAlso, triple.Object.ID) 242 case SPDX_EXAMPLE: 243 lic.example = triple.Object.ID 244 case RDF_TYPE: 245 continue 246 default: 247 return lic, fmt.Errorf("unknown predicate(%s) for simple licensing info", triple.Predicate) 248 } 249 } 250 return lic, nil 251} 252 253func (parser *rdfParser2_3) getLicenseFromNode(node *gordfParser.Node) (lic License, err error) { 254 associatedTriples := rdfwriter.FilterTriples(parser.gordfParserObj.Triples, &node.ID, nil, nil) 255 var restTriples []*gordfParser.Triple 256 for _, triple := range associatedTriples { 257 value := triple.Object.ID 258 switch triple.Predicate.ID { 259 case SPDX_IS_OSI_APPROVED: 260 lic.isOsiApproved, err = boolFromString(value) 261 if err != nil { 262 return lic, fmt.Errorf("error parsing isOsiApproved attribute of a License: %v", err) 263 } 264 case SPDX_LICENSE_TEXT: 265 lic.licenseText = value 266 case SPDX_STANDARD_LICENSE_HEADER: 267 lic.standardLicenseHeader = value 268 case SPDX_STANDARD_LICENSE_TEMPLATE: 269 lic.standardLicenseTemplate = value 270 case SPDX_STANDARD_LICENSE_HEADER_TEMPLATE: 271 lic.standardLicenseHeaderTemplate = value 272 case SPDX_IS_DEPRECATED_LICENSE_ID: 273 lic.isDeprecatedLicenseID, err = boolFromString(value) 274 if err != nil { 275 return lic, fmt.Errorf("error parsing isDeprecatedLicenseId attribute of a License: %v", err) 276 } 277 case SPDX_IS_FSF_LIBRE: 278 lic.isFsfLibre, err = boolFromString(value) 279 if err != nil { 280 return lic, fmt.Errorf("error parsing isFsfLibre attribute of a License: %v", err) 281 } 282 default: 283 restTriples = append(restTriples, triple) 284 } 285 } 286 lic.SimpleLicensingInfo, err = parser.getSimpleLicensingInfoFromTriples(restTriples) 287 if err != nil { 288 return lic, fmt.Errorf("error setting simple licensing information of a License: %s", err) 289 } 290 return lic, nil 291} 292