aboutsummaryrefslogtreecommitdiff
path: root/rdfloader/parser2v2/utils.go
blob: fd9ab7707b52cd4247efdfc1b22346cbd6d9cccb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
package parser2v2

import (
	"errors"
	"fmt"
	gordfParser "github.com/RishabhBhatnagar/gordf/rdfloader/parser"
	"github.com/RishabhBhatnagar/gordf/rdfwriter"
	urilib "github.com/RishabhBhatnagar/gordf/uri"
	"github.com/spdx/tools-golang/spdx"
	"regexp"
	"strings"
)

func getLastPartOfURI(uri string) string {
	if strings.Contains(uri, "#") {
		parts := strings.Split(uri, "#")
		return parts[len(parts)-1]
	}
	parts := strings.Split(uri, "/")
	return parts[len(parts)-1]
}

func (parser *rdfParser2_2) filterAllTriplesByString(subject, predicate, object string) (retTriples []*gordfParser.Triple) {
	for _, triple := range parser.gordfParserObj.Triples {
		if triple.Subject.ID == subject && triple.Predicate.ID == predicate && triple.Object.ID == object {
			retTriples = append(retTriples, triple)
		}
	}
	return retTriples
}

func (parser *rdfParser2_2) filterTriplesByRegex(triples []*gordfParser.Triple, subject, predicate, object string) (retTriples []*gordfParser.Triple, err error) {
	var subjectCompiled, objectCompiled, predicateCompiled *regexp.Regexp
	subjectCompiled, err = regexp.Compile(subject)
	if err != nil {
		return
	}
	predicateCompiled, err = regexp.Compile(predicate)
	if err != nil {
		return
	}
	objectCompiled, err = regexp.Compile(object)
	if err != nil {
		return
	}
	for _, triple := range triples {
		if subjectCompiled.MatchString(triple.Subject.ID) && predicateCompiled.MatchString(triple.Predicate.ID) && objectCompiled.MatchString(triple.Object.ID) {
			retTriples = append(retTriples, triple)
		}
	}
	return
}

func isUriValid(uri string) bool {
	_, err := urilib.NewURIRef(uri)
	return err == nil
}

func (parser *rdfParser2_2) getNodeTypeFromTriples(triples []*gordfParser.Triple, node *gordfParser.Node) (string, error) {
	if node == nil {
		return "", errors.New("empty node passed to find node type")
	}
	typeTriples := rdfwriter.FilterTriples(triples, &node.ID, &RDF_TYPE, nil)
	switch len(typeTriples) {
	case 0:
		return "", fmt.Errorf("node{%v} not associated with any type triple", node)
	case 1:
		return typeTriples[0].Object.ID, nil
	default:
		return "", fmt.Errorf("node{%v} is associated with more than one type triples", node)
	}
}

func (parser *rdfParser2_2) getNodeType(node *gordfParser.Node) (string, error) {
	return parser.getNodeTypeFromTriples(parser.gordfParserObj.Triples, node)
}

func (parser *rdfParser2_2) nodeToTriples(node *gordfParser.Node) []*gordfParser.Triple {
	if node == nil {
		return []*gordfParser.Triple{}
	}
	return parser.nodeStringToTriples[node.String()]
}

func boolFromString(boolString string) (bool, error) {
	switch strings.ToLower(boolString) {
	case "true":
		return true, nil
	case "false":
		return false, nil
	default:
		return false, fmt.Errorf("boolean string can be either true/false")
	}
}

/* Function Below this line is taken from the tvloader/parser2v2/utils.go */

// used to extract DocumentRef and SPDXRef values from an SPDX Identifier
// which can point either to this document or to a different one
func ExtractDocElementID(value string) (spdx.DocElementID, error) {
	docRefID := ""
	idStr := value

	// check prefix to see if it's a DocumentRef ID
	if strings.HasPrefix(idStr, "DocumentRef-") {
		// extract the part that comes between "DocumentRef-" and ":"
		strs := strings.Split(idStr, ":")
		// should be exactly two, part before and part after
		if len(strs) < 2 {
			return spdx.DocElementID{}, fmt.Errorf("no colon found although DocumentRef- prefix present")
		}
		if len(strs) > 2 {
			return spdx.DocElementID{}, fmt.Errorf("more than one colon found")
		}

		// trim the prefix and confirm non-empty
		docRefID = strings.TrimPrefix(strs[0], "DocumentRef-")
		if docRefID == "" {
			return spdx.DocElementID{}, fmt.Errorf("document identifier has nothing after prefix")
		}
		// and use remainder for element ID parsing
		idStr = strs[1]
	}

	// check prefix to confirm it's got the right prefix for element IDs
	if !strings.HasPrefix(idStr, "SPDXRef-") {
		return spdx.DocElementID{}, fmt.Errorf("missing SPDXRef- prefix for element identifier")
	}

	// make sure no colons are present
	if strings.Contains(idStr, ":") {
		// we know this means there was no DocumentRef- prefix, because
		// we would have handled multiple colons above if it was
		return spdx.DocElementID{}, fmt.Errorf("invalid colon in element identifier")
	}

	// trim the prefix and confirm non-empty
	eltRefID := strings.TrimPrefix(idStr, "SPDXRef-")
	if eltRefID == "" {
		return spdx.DocElementID{}, fmt.Errorf("element identifier has nothing after prefix")
	}

	// we're good
	return spdx.DocElementID{DocumentRefID: docRefID, ElementRefID: spdx.ElementID(eltRefID)}, nil
}

// used to extract SPDXRef values only from an SPDX Identifier which can point
// to this document only. Use extractDocElementID for parsing IDs that can
// refer either to this document or a different one.
func ExtractElementID(value string) (spdx.ElementID, error) {
	// check prefix to confirm it's got the right prefix for element IDs
	if !strings.HasPrefix(value, "SPDXRef-") {
		return spdx.ElementID(""), fmt.Errorf("missing SPDXRef- prefix for element identifier")
	}

	// make sure no colons are present
	if strings.Contains(value, ":") {
		return spdx.ElementID(""), fmt.Errorf("invalid colon in element identifier")
	}

	// trim the prefix and confirm non-empty
	eltRefID := strings.TrimPrefix(value, "SPDXRef-")
	if eltRefID == "" {
		return spdx.ElementID(""), fmt.Errorf("element identifier has nothing after prefix")
	}

	// we're good
	return spdx.ElementID(eltRefID), nil
}

// used to extract key / value from embedded substrings
// returns subkey, subvalue, nil if no error, or "", "", error otherwise
func ExtractSubs(value string, sep string) (string, string, error) {
	// parse the value to see if it's a valid subvalue format
	sp := strings.SplitN(value, sep, 2)
	if len(sp) == 1 {
		return "", "", fmt.Errorf("invalid subvalue format for %s (no %s found)", value, sep)
	}

	subkey := strings.TrimSpace(sp[0])
	subvalue := strings.TrimSpace(sp[1])

	return subkey, subvalue, nil
}