aboutsummaryrefslogtreecommitdiff
path: root/jsonloader/parser2v2/parse_creation_info.go
blob: 9e818e8344e6244665f7edccbb90d4e0541e96bd (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
// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later

package parser2v2

import (
	"fmt"
	"reflect"
	"strings"

	"github.com/spdx/tools-golang/spdx"
)

func (spec JSONSpdxDocument) parseJsonCreationInfo2_2(key string, value interface{}, doc *spdxDocument2_2) error {
	// create an SPDX Creation Info data struct if we don't have one already

	if doc.CreationInfo == nil {
		doc.CreationInfo = &spdx.CreationInfo2_2{
			ExternalDocumentReferences: map[string]spdx.ExternalDocumentRef2_2{},
		}
	}
	ci := doc.CreationInfo
	switch key {
	case "dataLicense":
		ci.DataLicense = value.(string)
	case "spdxVersion":
		ci.SPDXVersion = value.(string)
	case "SPDXID":
		id, err := extractElementID(value.(string))
		if err != nil {
			return fmt.Errorf("%s", err)
		}
		ci.SPDXIdentifier = id
	case "documentNamespace":
		ci.DocumentNamespace = value.(string)
	case "name":
		ci.DocumentName = value.(string)
	case "comment":
		ci.DocumentComment = value.(string)
	case "creationInfo":
		creationInfo := value.(map[string]interface{})
		for key, val := range creationInfo {
			switch key {
			case "comment":
				ci.CreatorComment = val.(string)
			case "created":
				ci.Created = val.(string)
			case "licenseListVersion":
				ci.LicenseListVersion = val.(string)
			case "creators":
				err := parseCreators(creationInfo["creators"], ci)
				if err != nil {
					return fmt.Errorf("%s", err)
				}
			}
		}
	case "externalDocumentRefs":
		err := parseExternalDocumentRefs(value, ci)
		if err != nil {
			return fmt.Errorf("%s", err)
		}
	default:
		return fmt.Errorf("unrecognized key %v", key)

	}

	return nil
}

// ===== Helper functions =====

func parseCreators(creators interface{}, ci *spdx.CreationInfo2_2) error {
	if reflect.TypeOf(creators).Kind() == reflect.Slice {
		s := reflect.ValueOf(creators)

		for i := 0; i < s.Len(); i++ {
			subkey, subvalue, err := extractSubs(s.Index(i).Interface().(string))
			if err != nil {
				return err
			}
			switch subkey {
			case "Person":
				ci.CreatorPersons = append(ci.CreatorPersons, subvalue)
			case "Organization":
				ci.CreatorOrganizations = append(ci.CreatorOrganizations, subvalue)
			case "Tool":
				ci.CreatorTools = append(ci.CreatorTools, subvalue)
			default:
				return fmt.Errorf("unrecognized Creator type %v", subkey)
			}

		}
	}
	return nil
}

func parseExternalDocumentRefs(references interface{}, ci *spdx.CreationInfo2_2) error {
	if reflect.TypeOf(references).Kind() == reflect.Slice {
		s := reflect.ValueOf(references)

		for i := 0; i < s.Len(); i++ {
			ref := s.Index(i).Interface().(map[string]interface{})
			documentRefID := ref["externalDocumentId"].(string)
			if !strings.HasPrefix(documentRefID, "DocumentRef-") {
				return fmt.Errorf("expected first element to have DocumentRef- prefix")
			}
			documentRefID = strings.TrimPrefix(documentRefID, "DocumentRef-")
			if documentRefID == "" {
				return fmt.Errorf("document identifier has nothing after prefix")
			}
			checksum := ref["checksum"].(map[string]interface{})
			edr := spdx.ExternalDocumentRef2_2{
				DocumentRefID: documentRefID,
				URI:           ref["spdxDocument"].(string),
				Alg:           checksum["algorithm"].(string),
				Checksum:      checksum["checksumValue"].(string),
			}

			ci.ExternalDocumentReferences[documentRefID] = edr
		}
	}
	return nil
}