aboutsummaryrefslogtreecommitdiff
path: root/jsonloader/parser2v2/parser.go
blob: b1fbe8a74653b8b427a1f3bb4e6af366691e05dd (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
// Package jsonloader is used to load and parse SPDX JSON documents
// into tools-golang data structures.
// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later

package parser2v2

import (
	"encoding/json"
	"fmt"

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

//TODO : return spdx.Document2_2
func Load2_2(content []byte) (*spdx.Document2_2, error) {
	// check whetehr the Json is valid or not
	if !json.Valid(content) {
		return nil, fmt.Errorf("%s", "Invalid JSON Specification")
	}
	result := spdxDocument2_2{}
	// unmarshall the json into the result struct
	err := json.Unmarshal(content, &result)
	resultfinal := spdx.Document2_2(result)

	if err != nil {
		return nil, fmt.Errorf("%s", err)
	}

	return &resultfinal, nil
}

func (doc *spdxDocument2_2) UnmarshalJSON(data []byte) error {
	var specs JSONSpdxDocument
	//unmarshall the json into the intermediate stricture map[string]interface{}
	err := json.Unmarshal(data, &specs)
	if err != nil {
		return err
	}
	// parse the data from the intermediate structure to the spdx.Document2_2{}
	err = specs.newDocument(doc)
	if err != nil {
		return err
	}
	return nil
}

func (spec JSONSpdxDocument) newDocument(doc *spdxDocument2_2) error {
	// raneg through all the keys in the map and send them to appropriate arsing functions
	for key, val := range spec {
		switch key {
		case "dataLicense", "spdxVersion", "SPDXID", "documentNamespace", "name", "comment", "creationInfo", "externalDocumentRefs":
			err := spec.parseJsonCreationInfo2_2(key, val, doc)
			if err != nil {
				return err
			}
		case "annotations":
			// if the json spec doenn't has any files then only this case will be executed
			if spec["files"] == nil {

				id, err := extractDocElementID(spec["SPDXID"].(string))
				if err != nil {
					return fmt.Errorf("%s", err)
				}
				err = spec.parseJsonAnnotations2_2(key, val, doc, id)
				if err != nil {
					return err
				}
			}
		case "relationships":
			err := spec.parseJsonRelationships2_2(key, val, doc)
			if err != nil {
				return err
			}
		case "files":
			//first parse all the files
			err := spec.parseJsonFiles2_2(key, val, doc)
			if err != nil {
				return err
			}
			//then parse the snippets
			if spec["snippets"] != nil {
				err = spec.parseJsonSnippets2_2("snippets", spec["snippets"], doc)
				if err != nil {
					return err
				}
			}
			//then parse the packages
			if spec["packages"] != nil {
				err = spec.parseJsonPackages2_2("packages", spec["packages"], doc)
				if err != nil {
					return err
				}
			}
			// then parse the annotations
			if spec["annotations"] != nil {
				id, err := extractDocElementID(spec["SPDXID"].(string))
				if err != nil {
					return fmt.Errorf("%s", err)
				}
				err = spec.parseJsonAnnotations2_2("annotations", spec["annotations"], doc, id)
				if err != nil {
					return err
				}
			}

		case "packages":
			// if the json spec doesn't has any files to parse then this switch case will be executed
			if spec["files"] == nil {
				err := spec.parseJsonPackages2_2("packages", spec["packages"], doc)
				if err != nil {
					return err
				}
			}
		case "hasExtractedLicensingInfos":
			err := spec.parseJsonOtherLicenses2_2(key, val, doc)
			if err != nil {
				return err
			}
		case "revieweds":
			err := spec.parseJsonReviews2_2(key, val, doc)
			if err != nil {
				return err
			}
		case "snippets", "documentDescribes":
			//redundant case
		default:
			return fmt.Errorf("unrecognized key here %v", key)
		}

	}
	return nil
}