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