-
Notifications
You must be signed in to change notification settings - Fork 53
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #40 from RishabhBhatnagar/gordf
Add Support For RDFLoader Including Licenses
- Loading branch information
Showing
16 changed files
with
2,192 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"github.com/spdx/tools-golang/rdfloader" | ||
"os" | ||
"strings" | ||
) | ||
|
||
func getFilePathFromUser() string { | ||
if len(os.Args) == 1 { | ||
// user hasn't specified the rdf file path | ||
panic("kindly provide path of the rdf file to be loaded as a spdx-document while running this file") | ||
} | ||
return os.Args[1] | ||
} | ||
|
||
func main() { | ||
// example to use the rdfLoader. | ||
filePath := getFilePathFromUser() | ||
file, err := os.Open(filePath) | ||
if err != nil { | ||
panic(fmt.Errorf("error opening File: %s", err)) | ||
} | ||
|
||
// loading the spdx-document | ||
doc, err := rdfloader.Load2_2(file) | ||
if err != nil { | ||
fmt.Println(fmt.Errorf("error parsing given spdx document: %s", err)) | ||
os.Exit(1) | ||
} | ||
|
||
// Printing some of the document Information | ||
fmt.Println(strings.Repeat("=", 80)) | ||
fmt.Println("Some Attributes of the Document:") | ||
fmt.Printf("Document Name: %s\n", doc.CreationInfo.DocumentName) | ||
fmt.Printf("DataLicense: %s\n", doc.CreationInfo.DataLicense) | ||
fmt.Printf("Document NameSpace: %s\n", doc.CreationInfo.DocumentNamespace) | ||
fmt.Printf("SPDX Document Version: %s\n", doc.CreationInfo.SPDXVersion) | ||
fmt.Println(strings.Repeat("=", 80)) | ||
} |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later | ||
|
||
package parser2v2 | ||
|
||
import ( | ||
"fmt" | ||
gordfParser "github.com/RishabhBhatnagar/gordf/rdfloader/parser" | ||
"github.com/spdx/tools-golang/spdx" | ||
) | ||
|
||
// creates a new instance of annotation and sets the annotation attributes | ||
// associated with the given node. | ||
// The newly created annotation is appended to the doc. | ||
func (parser *rdfParser2_2) parseAnnotationFromNode(node *gordfParser.Node) (err error) { | ||
ann := &spdx.Annotation2_2{} | ||
for _, subTriple := range parser.nodeToTriples(node) { | ||
switch subTriple.Predicate.ID { | ||
case SPDX_ANNOTATOR: | ||
// cardinality: exactly 1 | ||
err = setAnnotatorFromString(subTriple.Object.ID, ann) | ||
case SPDX_ANNOTATION_DATE: | ||
// cardinality: exactly 1 | ||
ann.AnnotationDate = subTriple.Object.ID | ||
case RDFS_COMMENT: | ||
// cardinality: exactly 1 | ||
ann.AnnotationComment = subTriple.Object.ID | ||
case SPDX_ANNOTATION_TYPE: | ||
// cardinality: exactly 1 | ||
err = setAnnotationType(subTriple.Object.ID, ann) | ||
case RDF_TYPE: | ||
// cardinality: exactly 1 | ||
continue | ||
default: | ||
err = fmt.Errorf("unknown predicate %s while parsing annotation", subTriple.Predicate.ID) | ||
} | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
return setAnnotationToParser(parser, ann) | ||
} | ||
|
||
func setAnnotationToParser(parser *rdfParser2_2, annotation *spdx.Annotation2_2) error { | ||
if parser.doc == nil { | ||
return fmt.Errorf("uninitialized spdx document") | ||
} | ||
if parser.doc.Annotations == nil { | ||
parser.doc.Annotations = []*spdx.Annotation2_2{} | ||
} | ||
parser.doc.Annotations = append(parser.doc.Annotations, annotation) | ||
return nil | ||
} | ||
|
||
func setAnnotatorFromString(annotatorString string, ann *spdx.Annotation2_2) error { | ||
subkey, subvalue, err := ExtractSubs(annotatorString, ":") | ||
if err != nil { | ||
return err | ||
} | ||
if subkey == "Person" || subkey == "Organization" || subkey == "Tool" { | ||
ann.AnnotatorType = subkey | ||
ann.Annotator = subvalue | ||
return nil | ||
} | ||
return fmt.Errorf("unrecognized Annotator type %v while parsing annotation", subkey) | ||
} | ||
|
||
func setAnnotationType(annType string, ann *spdx.Annotation2_2) error { | ||
switch annType { | ||
case SPDX_ANNOTATION_TYPE_OTHER: | ||
ann.AnnotationType = "OTHER" | ||
case SPDX_ANNOTATION_TYPE_REVIEW: | ||
ann.AnnotationType = "REVIEW" | ||
default: | ||
return fmt.Errorf("unknown annotation type %s", annType) | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later | ||
|
||
package parser2v2 | ||
|
||
import ( | ||
"fmt" | ||
gordfParser "github.com/RishabhBhatnagar/gordf/rdfloader/parser" | ||
"github.com/spdx/tools-golang/spdx" | ||
) | ||
|
||
// Cardinality: Mandatory, one. | ||
func (parser *rdfParser2_2) parseCreationInfoFromNode(ci *spdx.CreationInfo2_2, node *gordfParser.Node) error { | ||
for _, triple := range parser.nodeToTriples(node) { | ||
switch triple.Predicate.ID { | ||
case SPDX_LICENSE_LIST_VERSION: // 2.7 | ||
// cardinality: max 1 | ||
ci.LicenseListVersion = triple.Object.ID | ||
case SPDX_CREATOR: // 2.8 | ||
// cardinality: min 1 | ||
err := setCreator(triple.Object.ID, ci) | ||
if err != nil { | ||
return err | ||
} | ||
case SPDX_CREATED: // 2.9 | ||
// cardinality: exactly 1 | ||
ci.Created = triple.Object.ID | ||
case RDFS_COMMENT: // 2.10 | ||
ci.CreatorComment = triple.Object.ID | ||
case RDF_TYPE: | ||
continue | ||
default: | ||
return fmt.Errorf("unknown predicate %v while parsing a creation info", triple.Predicate) | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func setCreator(creator string, ci *spdx.CreationInfo2_2) error { | ||
entityType, entity, err := ExtractSubs(creator, ":") | ||
if err != nil { | ||
return fmt.Errorf("error setting creator of a creation info: %s", err) | ||
} | ||
switch entityType { | ||
case "Person": | ||
ci.CreatorPersons = append(ci.CreatorPersons, entity) | ||
case "Organization": | ||
ci.CreatorOrganizations = append(ci.CreatorOrganizations, entity) | ||
case "Tool": | ||
ci.CreatorTools = append(ci.CreatorTools, entity) | ||
default: | ||
return fmt.Errorf("unknown creatorType %v in a creation info", entityType) | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later | ||
|
||
package parser2v2 | ||
|
||
import ( | ||
"fmt" | ||
gordfParser "github.com/RishabhBhatnagar/gordf/rdfloader/parser" | ||
"github.com/spdx/tools-golang/spdx" | ||
"strings" | ||
) | ||
|
||
// returns a file instance and the error if any encountered. | ||
func (parser *rdfParser2_2) getFileFromNode(fileNode *gordfParser.Node) (file *spdx.File2_2, err error) { | ||
file = &spdx.File2_2{} | ||
|
||
err = setFileIdentifier(fileNode.ID, file, parser) // 4.2 | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
for _, subTriple := range parser.nodeToTriples(fileNode) { | ||
switch subTriple.Predicate.ID { | ||
case SPDX_FILE_NAME: // 4.1 | ||
// cardinality: exactly 1 | ||
file.FileName = subTriple.Object.ID | ||
case SPDX_NAME: | ||
// cardinality: exactly 1 | ||
// todo: check where it will be set in the golang-tools spdx-data-model | ||
case RDF_TYPE: | ||
// cardinality: exactly 1 | ||
case SPDX_FILE_TYPE: // 4.3 | ||
// cardinality: min 0 | ||
fileType := "" | ||
fileType, err = parser.getFileTypeFromUri(subTriple.Object.ID) | ||
file.FileType = append(file.FileType, fileType) | ||
case SPDX_CHECKSUM: // 4.4 | ||
// cardinality: min 1 | ||
err = parser.setFileChecksumFromNode(file, subTriple.Object) | ||
case SPDX_LICENSE_CONCLUDED: // 4.5 | ||
// cardinality: (exactly 1 anyLicenseInfo) or (None) or (Noassertion) | ||
anyLicense, err := parser.getAnyLicenseFromNode(subTriple.Object) | ||
if err != nil { | ||
return nil, fmt.Errorf("error parsing licenseConcluded: %v", err) | ||
} | ||
file.LicenseConcluded = anyLicense.ToLicenseString() | ||
case SPDX_LICENSE_INFO_IN_FILE: // 4.6 | ||
// cardinality: min 1 | ||
lastPart := getLastPartOfURI(subTriple.Object.ID) | ||
file.LicenseInfoInFile = append(file.LicenseInfoInFile, lastPart) | ||
case SPDX_LICENSE_COMMENTS: // 4.7 | ||
// cardinality: max 1 | ||
file.LicenseComments = subTriple.Object.ID | ||
case SPDX_COPYRIGHT_TEXT: // 4.8 | ||
// cardinality: exactly 1 | ||
file.FileCopyrightText = subTriple.Object.ID | ||
case SPDX_LICENSE_INFO_FROM_FILES: | ||
// todo: implement it. It is not defined in the tools-golang model. | ||
// deprecated artifactOf (see sections 4.9, 4.10, 4.11) | ||
case SPDX_ARTIFACT_OF: | ||
// cardinality: min 0 | ||
var artifactOf *spdx.ArtifactOfProject2_2 | ||
artifactOf, err = parser.getArtifactFromNode(subTriple.Object) | ||
file.ArtifactOfProjects = append(file.ArtifactOfProjects, artifactOf) | ||
case RDFS_COMMENT: // 4.12 | ||
// cardinality: max 1 | ||
file.FileComment = subTriple.Object.ID | ||
case SPDX_NOTICE_TEXT: // 4.13 | ||
// cardinality: max 1 | ||
file.FileNotice = subTriple.Object.ID | ||
case SPDX_FILE_CONTRIBUTOR: // 4.14 | ||
// cardinality: min 0 | ||
file.FileContributor = append(file.FileContributor, subTriple.Object.ID) | ||
case SPDX_FILE_DEPENDENCY: | ||
// cardinality: min 0 | ||
file, err := parser.getFileFromNode(subTriple.Object) | ||
if err != nil { | ||
return nil, fmt.Errorf("error setting a file dependency in a file: %v", err) | ||
} | ||
parser.files[file.FileSPDXIdentifier] = file | ||
case SPDX_ATTRIBUTION_TEXT: | ||
// cardinality: min 0 | ||
file.FileAttributionTexts = append(file.FileAttributionTexts, subTriple.Object.ID) | ||
case SPDX_ANNOTATION: // unknown section | ||
err = parser.parseAnnotationFromNode(subTriple.Object) | ||
case SPDX_RELATIONSHIP: // unknown section | ||
err = parser.parseRelationship(subTriple) | ||
default: | ||
return nil, fmt.Errorf("unknown triple predicate id %s", subTriple.Predicate.ID) | ||
} | ||
if err != nil { | ||
return nil, err | ||
} | ||
} | ||
return file, nil | ||
} | ||
|
||
func (parser *rdfParser2_2) setFileChecksumFromNode(file *spdx.File2_2, checksumNode *gordfParser.Node) error { | ||
checksumAlgorithm, checksumValue, err := parser.getChecksumFromNode(checksumNode) | ||
if err != nil { | ||
return nil | ||
} | ||
switch checksumAlgorithm { | ||
case "MD5": | ||
file.FileChecksumMD5 = checksumValue | ||
case "SHA1": | ||
file.FileChecksumSHA1 = checksumValue | ||
case "SHA256": | ||
file.FileChecksumSHA256 = checksumValue | ||
case "": | ||
return fmt.Errorf("empty checksum algorithm and value") | ||
default: | ||
return fmt.Errorf("unknown checksumAlgorithm %s while parsing a file", checksumAlgorithm) | ||
} | ||
return nil | ||
} | ||
|
||
func (parser *rdfParser2_2) getArtifactFromNode(node *gordfParser.Node) (*spdx.ArtifactOfProject2_2, error) { | ||
artifactOf := &spdx.ArtifactOfProject2_2{} | ||
// setting artifactOfProjectURI attribute (which is optional) | ||
if node.NodeType == gordfParser.IRI { | ||
artifactOf.URI = node.ID | ||
} | ||
// parsing rest triples and attributes of the artifact. | ||
for _, triple := range parser.nodeToTriples(node) { | ||
switch triple.Predicate.ID { | ||
case RDF_TYPE: | ||
case DOAP_HOMEPAGE: | ||
artifactOf.HomePage = triple.Object.ID | ||
case DOAP_NAME: | ||
artifactOf.Name = triple.Object.ID | ||
default: | ||
return nil, fmt.Errorf("error parsing artifactOf predicate %s", triple.Predicate.ID) | ||
} | ||
} | ||
return artifactOf, nil | ||
} | ||
|
||
func (parser *rdfParser2_2) getFileTypeFromUri(uri string) (string, error) { | ||
// fileType is given as a uri. for example: http://spdx.org/rdf/terms#fileType_text | ||
lastPart := getLastPartOfURI(uri) | ||
if !strings.HasPrefix(lastPart, "fileType_") { | ||
return "", fmt.Errorf("fileType Uri must begin with fileTYpe_. found: %s", lastPart) | ||
} | ||
return strings.TrimPrefix(lastPart, "fileType_"), nil | ||
} | ||
|
||
// populates parser.doc.UnpackagedFiles by a list of files which are not | ||
// associated with a package by the hasFile attribute | ||
// assumes: all the packages are already parsed. | ||
func (parser *rdfParser2_2) setUnpackagedFiles() { | ||
for fileID := range parser.files { | ||
if !parser.assocWithPackage[fileID] { | ||
parser.doc.UnpackagedFiles[fileID] = parser.files[fileID] | ||
} | ||
} | ||
} | ||
|
||
func setFileIdentifier(idURI string, file *spdx.File2_2, parser *rdfParser2_2) (err error) { | ||
idURI = strings.TrimSpace(idURI) | ||
uriFragment := getLastPartOfURI(idURI) | ||
file.FileSPDXIdentifier, err = ExtractElementID(uriFragment) | ||
if err != nil { | ||
return fmt.Errorf("error setting file identifier: %s", err) | ||
} | ||
return nil | ||
} |
Oops, something went wrong.