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 urilib "github.com/spdx/gordf/uri" 13*ba677afaSXin Li "github.com/spdx/tools-golang/spdx/common" 14*ba677afaSXin Li) 15*ba677afaSXin Li 16*ba677afaSXin Li// a uri is of type baseURI#fragment or baseFragment/subFragment 17*ba677afaSXin Li// returns fragment or subFragment when given as an input. 18*ba677afaSXin Lifunc getLastPartOfURI(uri string) string { 19*ba677afaSXin Li if strings.Contains(uri, "#") { 20*ba677afaSXin Li parts := strings.Split(uri, "#") 21*ba677afaSXin Li return parts[len(parts)-1] 22*ba677afaSXin Li } 23*ba677afaSXin Li parts := strings.Split(uri, "/") 24*ba677afaSXin Li return parts[len(parts)-1] 25*ba677afaSXin Li} 26*ba677afaSXin Li 27*ba677afaSXin Lifunc isUriValid(uri string) bool { 28*ba677afaSXin Li _, err := urilib.NewURIRef(uri) 29*ba677afaSXin Li return err == nil 30*ba677afaSXin Li} 31*ba677afaSXin Li 32*ba677afaSXin Lifunc getNodeTypeFromTriples(triples []*gordfParser.Triple, node *gordfParser.Node) (string, error) { 33*ba677afaSXin Li if node == nil { 34*ba677afaSXin Li return "", errors.New("empty node passed to find node type") 35*ba677afaSXin Li } 36*ba677afaSXin Li typeTriples := rdfwriter.FilterTriples(triples, &node.ID, &RDF_TYPE, nil) 37*ba677afaSXin Li switch len(typeTriples) { 38*ba677afaSXin Li case 0: 39*ba677afaSXin Li return "", fmt.Errorf("node{%v} not associated with any type triple", node) 40*ba677afaSXin Li case 1: 41*ba677afaSXin Li return typeTriples[0].Object.ID, nil 42*ba677afaSXin Li default: 43*ba677afaSXin Li return "", fmt.Errorf("node{%v} is associated with more than one type triples", node) 44*ba677afaSXin Li } 45*ba677afaSXin Li} 46*ba677afaSXin Li 47*ba677afaSXin Lifunc (parser *rdfParser2_2) nodeToTriples(node *gordfParser.Node) []*gordfParser.Triple { 48*ba677afaSXin Li if node == nil { 49*ba677afaSXin Li return []*gordfParser.Triple{} 50*ba677afaSXin Li } 51*ba677afaSXin Li return parser.nodeStringToTriples[node.String()] 52*ba677afaSXin Li} 53*ba677afaSXin Li 54*ba677afaSXin Li// returns which boolean was given as an input 55*ba677afaSXin Li// string(bool) is the only possible input for which it will not raise any error. 56*ba677afaSXin Lifunc boolFromString(boolString string) (bool, error) { 57*ba677afaSXin Li switch strings.ToLower(boolString) { 58*ba677afaSXin Li case "true": 59*ba677afaSXin Li return true, nil 60*ba677afaSXin Li case "false": 61*ba677afaSXin Li return false, nil 62*ba677afaSXin Li default: 63*ba677afaSXin Li return false, fmt.Errorf("boolean string can be either true/false") 64*ba677afaSXin Li } 65*ba677afaSXin Li} 66*ba677afaSXin Li 67*ba677afaSXin Li/* Function Below this line is taken from the tvloader/parser2v2/utils.go */ 68*ba677afaSXin Li 69*ba677afaSXin Li// used to extract DocumentRef and SPDXRef values from an SPDX Identifier 70*ba677afaSXin Li// which can point either to this document or to a different one 71*ba677afaSXin Lifunc ExtractDocElementID(value string) (common.DocElementID, error) { 72*ba677afaSXin Li docRefID := "" 73*ba677afaSXin Li idStr := value 74*ba677afaSXin Li 75*ba677afaSXin Li // check prefix to see if it's a DocumentRef ID 76*ba677afaSXin Li if strings.HasPrefix(idStr, "DocumentRef-") { 77*ba677afaSXin Li // extract the part that comes between "DocumentRef-" and ":" 78*ba677afaSXin Li strs := strings.Split(idStr, ":") 79*ba677afaSXin Li // should be exactly two, part before and part after 80*ba677afaSXin Li if len(strs) < 2 { 81*ba677afaSXin Li return common.DocElementID{}, fmt.Errorf("no colon found although DocumentRef- prefix present") 82*ba677afaSXin Li } 83*ba677afaSXin Li if len(strs) > 2 { 84*ba677afaSXin Li return common.DocElementID{}, fmt.Errorf("more than one colon found") 85*ba677afaSXin Li } 86*ba677afaSXin Li 87*ba677afaSXin Li // trim the prefix and confirm non-empty 88*ba677afaSXin Li docRefID = strings.TrimPrefix(strs[0], "DocumentRef-") 89*ba677afaSXin Li if docRefID == "" { 90*ba677afaSXin Li return common.DocElementID{}, fmt.Errorf("document identifier has nothing after prefix") 91*ba677afaSXin Li } 92*ba677afaSXin Li // and use remainder for element ID parsing 93*ba677afaSXin Li idStr = strs[1] 94*ba677afaSXin Li } 95*ba677afaSXin Li 96*ba677afaSXin Li // check prefix to confirm it's got the right prefix for element IDs 97*ba677afaSXin Li if !strings.HasPrefix(idStr, "SPDXRef-") { 98*ba677afaSXin Li return common.DocElementID{}, fmt.Errorf("missing SPDXRef- prefix for element identifier") 99*ba677afaSXin Li } 100*ba677afaSXin Li 101*ba677afaSXin Li // make sure no colons are present 102*ba677afaSXin Li if strings.Contains(idStr, ":") { 103*ba677afaSXin Li // we know this means there was no DocumentRef- prefix, because 104*ba677afaSXin Li // we would have handled multiple colons above if it was 105*ba677afaSXin Li return common.DocElementID{}, fmt.Errorf("invalid colon in element identifier") 106*ba677afaSXin Li } 107*ba677afaSXin Li 108*ba677afaSXin Li // trim the prefix and confirm non-empty 109*ba677afaSXin Li eltRefID := strings.TrimPrefix(idStr, "SPDXRef-") 110*ba677afaSXin Li if eltRefID == "" { 111*ba677afaSXin Li return common.DocElementID{}, fmt.Errorf("element identifier has nothing after prefix") 112*ba677afaSXin Li } 113*ba677afaSXin Li 114*ba677afaSXin Li // we're good 115*ba677afaSXin Li return common.DocElementID{DocumentRefID: docRefID, ElementRefID: common.ElementID(eltRefID)}, nil 116*ba677afaSXin Li} 117*ba677afaSXin Li 118*ba677afaSXin Li// used to extract SPDXRef values only from an SPDX Identifier which can point 119*ba677afaSXin Li// to this document only. Use extractDocElementID for parsing IDs that can 120*ba677afaSXin Li// refer either to this document or a different one. 121*ba677afaSXin Lifunc ExtractElementID(value string) (common.ElementID, error) { 122*ba677afaSXin Li // check prefix to confirm it's got the right prefix for element IDs 123*ba677afaSXin Li if !strings.HasPrefix(value, "SPDXRef-") { 124*ba677afaSXin Li return common.ElementID(""), fmt.Errorf("missing SPDXRef- prefix for element identifier") 125*ba677afaSXin Li } 126*ba677afaSXin Li 127*ba677afaSXin Li // make sure no colons are present 128*ba677afaSXin Li if strings.Contains(value, ":") { 129*ba677afaSXin Li return common.ElementID(""), fmt.Errorf("invalid colon in element identifier") 130*ba677afaSXin Li } 131*ba677afaSXin Li 132*ba677afaSXin Li // trim the prefix and confirm non-empty 133*ba677afaSXin Li eltRefID := strings.TrimPrefix(value, "SPDXRef-") 134*ba677afaSXin Li if eltRefID == "" { 135*ba677afaSXin Li return common.ElementID(""), fmt.Errorf("element identifier has nothing after prefix") 136*ba677afaSXin Li } 137*ba677afaSXin Li 138*ba677afaSXin Li // we're good 139*ba677afaSXin Li return common.ElementID(eltRefID), nil 140*ba677afaSXin Li} 141*ba677afaSXin Li 142*ba677afaSXin Li// used to extract key / value from embedded substrings 143*ba677afaSXin Li// returns subkey, subvalue, nil if no error, or "", "", error otherwise 144*ba677afaSXin Lifunc ExtractSubs(value string, sep string) (string, string, error) { 145*ba677afaSXin Li // parse the value to see if it's a valid subvalue format 146*ba677afaSXin Li sp := strings.SplitN(value, sep, 2) 147*ba677afaSXin Li if len(sp) == 1 { 148*ba677afaSXin Li return "", "", fmt.Errorf("invalid subvalue format for %s (no %s found)", value, sep) 149*ba677afaSXin Li } 150*ba677afaSXin Li 151*ba677afaSXin Li subkey := strings.TrimSpace(sp[0]) 152*ba677afaSXin Li subvalue := strings.TrimSpace(sp[1]) 153*ba677afaSXin Li 154*ba677afaSXin Li return subkey, subvalue, nil 155*ba677afaSXin Li} 156