spdx_tools.spdx.writer.rdf.license_expression_writer

 1# SPDX-FileCopyrightText: 2023 spdx contributors
 2#
 3# SPDX-License-Identifier: Apache-2.0
 4from beartype.typing import List, Union
 5from boolean import Expression
 6from license_expression import AND, OR, ExpressionInfo, LicenseExpression, LicenseSymbol, LicenseWithExceptionSymbol
 7from rdflib import RDF, BNode, Graph, URIRef
 8from rdflib.term import Literal, Node
 9
10from spdx_tools.common.spdx_licensing import spdx_licensing
11from spdx_tools.spdx.model import SpdxNoAssertion, SpdxNone
12from spdx_tools.spdx.rdfschema.namespace import LICENSE_NAMESPACE, SPDX_NAMESPACE
13
14
15def add_license_expression_or_none_or_no_assertion(
16    value: Union[
17        List[Union[LicenseExpression, SpdxNoAssertion, SpdxNone]], LicenseExpression, SpdxNoAssertion, SpdxNone
18    ],
19    graph: Graph,
20    parent: Node,
21    predicate: Node,
22    doc_namespace: str,
23):
24    if isinstance(value, SpdxNoAssertion):
25        graph.add((parent, predicate, SPDX_NAMESPACE.noassertion))
26        return
27    if isinstance(value, SpdxNone):
28        graph.add((parent, predicate, SPDX_NAMESPACE.none))
29        return
30    if isinstance(value, list):
31        for license_expression in value:
32            add_license_expression_or_none_or_no_assertion(license_expression, graph, parent, predicate, doc_namespace)
33    if isinstance(value, LicenseExpression):
34        add_license_expression_to_graph(value, graph, parent, predicate, doc_namespace)
35
36
37def add_license_expression_to_graph(
38    license_expression: Expression, graph: Graph, parent: Node, predicate: Node, doc_namespace: str
39):
40    if isinstance(license_expression, AND):
41        member_node = BNode()
42        graph.add((member_node, RDF.type, SPDX_NAMESPACE.ConjunctiveLicenseSet))
43        graph.add((parent, predicate, member_node))
44        for arg in license_expression.args:
45            add_license_expression_to_graph(arg, graph, member_node, SPDX_NAMESPACE.member, doc_namespace)
46    if isinstance(license_expression, OR):
47        member_node = BNode()
48        graph.add((member_node, RDF.type, SPDX_NAMESPACE.DisjunctiveLicenseSet))
49        graph.add((parent, predicate, member_node))
50        for arg in license_expression.args:
51            add_license_expression_to_graph(arg, graph, member_node, SPDX_NAMESPACE.member, doc_namespace)
52    if isinstance(license_expression, LicenseWithExceptionSymbol):
53        member_node = BNode()
54        graph.add((member_node, RDF.type, SPDX_NAMESPACE.WithExceptionOperator))
55        graph.add((parent, predicate, member_node))
56
57        add_license_expression_to_graph(
58            license_expression.license_symbol, graph, member_node, SPDX_NAMESPACE.member, doc_namespace
59        )
60        add_license_exception_to_graph(license_expression.exception_symbol, graph, member_node)
61
62    if isinstance(license_expression, LicenseSymbol):
63        if license_or_exception_is_on_spdx_licensing_list(license_expression):
64            graph.add((parent, predicate, LICENSE_NAMESPACE[str(license_expression)]))
65        else:
66            # assuming that the license expression is a LicenseRef to an instance of ExtractedLicensingInfo
67            graph.add((parent, predicate, URIRef(f"{doc_namespace}#{license_expression}")))
68
69
70def license_or_exception_is_on_spdx_licensing_list(license_symbol: LicenseSymbol) -> bool:
71    symbol_info: ExpressionInfo = spdx_licensing.validate(license_symbol)
72    return not symbol_info.errors
73
74
75def add_license_exception_to_graph(license_exception: LicenseSymbol, graph: Graph, parent: Node):
76    if license_or_exception_is_on_spdx_licensing_list(license_exception):
77        exception_node = LICENSE_NAMESPACE[str(license_exception)]
78        graph.add((parent, SPDX_NAMESPACE.licenseException, exception_node))
79    else:
80        exception_node = BNode()
81        graph.add((exception_node, SPDX_NAMESPACE.licenseExceptionId, Literal(license_exception)))
82        graph.add((parent, SPDX_NAMESPACE.licenseException, exception_node))
83
84    graph.add((exception_node, RDF.type, SPDX_NAMESPACE.LicenseException))
def add_license_expression_or_none_or_no_assertion( value: Union[list[Union[boolean.boolean.Expression, spdx_tools.spdx.model.spdx_no_assertion.SpdxNoAssertion, spdx_tools.spdx.model.spdx_none.SpdxNone]], boolean.boolean.Expression, spdx_tools.spdx.model.spdx_no_assertion.SpdxNoAssertion, spdx_tools.spdx.model.spdx_none.SpdxNone], graph: rdflib.graph.Graph, parent: rdflib.term.Node, predicate: rdflib.term.Node, doc_namespace: str):
16def add_license_expression_or_none_or_no_assertion(
17    value: Union[
18        List[Union[LicenseExpression, SpdxNoAssertion, SpdxNone]], LicenseExpression, SpdxNoAssertion, SpdxNone
19    ],
20    graph: Graph,
21    parent: Node,
22    predicate: Node,
23    doc_namespace: str,
24):
25    if isinstance(value, SpdxNoAssertion):
26        graph.add((parent, predicate, SPDX_NAMESPACE.noassertion))
27        return
28    if isinstance(value, SpdxNone):
29        graph.add((parent, predicate, SPDX_NAMESPACE.none))
30        return
31    if isinstance(value, list):
32        for license_expression in value:
33            add_license_expression_or_none_or_no_assertion(license_expression, graph, parent, predicate, doc_namespace)
34    if isinstance(value, LicenseExpression):
35        add_license_expression_to_graph(value, graph, parent, predicate, doc_namespace)
def add_license_expression_to_graph( license_expression: boolean.boolean.Expression, graph: rdflib.graph.Graph, parent: rdflib.term.Node, predicate: rdflib.term.Node, doc_namespace: str):
38def add_license_expression_to_graph(
39    license_expression: Expression, graph: Graph, parent: Node, predicate: Node, doc_namespace: str
40):
41    if isinstance(license_expression, AND):
42        member_node = BNode()
43        graph.add((member_node, RDF.type, SPDX_NAMESPACE.ConjunctiveLicenseSet))
44        graph.add((parent, predicate, member_node))
45        for arg in license_expression.args:
46            add_license_expression_to_graph(arg, graph, member_node, SPDX_NAMESPACE.member, doc_namespace)
47    if isinstance(license_expression, OR):
48        member_node = BNode()
49        graph.add((member_node, RDF.type, SPDX_NAMESPACE.DisjunctiveLicenseSet))
50        graph.add((parent, predicate, member_node))
51        for arg in license_expression.args:
52            add_license_expression_to_graph(arg, graph, member_node, SPDX_NAMESPACE.member, doc_namespace)
53    if isinstance(license_expression, LicenseWithExceptionSymbol):
54        member_node = BNode()
55        graph.add((member_node, RDF.type, SPDX_NAMESPACE.WithExceptionOperator))
56        graph.add((parent, predicate, member_node))
57
58        add_license_expression_to_graph(
59            license_expression.license_symbol, graph, member_node, SPDX_NAMESPACE.member, doc_namespace
60        )
61        add_license_exception_to_graph(license_expression.exception_symbol, graph, member_node)
62
63    if isinstance(license_expression, LicenseSymbol):
64        if license_or_exception_is_on_spdx_licensing_list(license_expression):
65            graph.add((parent, predicate, LICENSE_NAMESPACE[str(license_expression)]))
66        else:
67            # assuming that the license expression is a LicenseRef to an instance of ExtractedLicensingInfo
68            graph.add((parent, predicate, URIRef(f"{doc_namespace}#{license_expression}")))
def license_or_exception_is_on_spdx_licensing_list(license_symbol: license_expression.LicenseSymbol) -> bool:
71def license_or_exception_is_on_spdx_licensing_list(license_symbol: LicenseSymbol) -> bool:
72    symbol_info: ExpressionInfo = spdx_licensing.validate(license_symbol)
73    return not symbol_info.errors
def add_license_exception_to_graph( license_exception: license_expression.LicenseSymbol, graph: rdflib.graph.Graph, parent: rdflib.term.Node):
76def add_license_exception_to_graph(license_exception: LicenseSymbol, graph: Graph, parent: Node):
77    if license_or_exception_is_on_spdx_licensing_list(license_exception):
78        exception_node = LICENSE_NAMESPACE[str(license_exception)]
79        graph.add((parent, SPDX_NAMESPACE.licenseException, exception_node))
80    else:
81        exception_node = BNode()
82        graph.add((exception_node, SPDX_NAMESPACE.licenseExceptionId, Literal(license_exception)))
83        graph.add((parent, SPDX_NAMESPACE.licenseException, exception_node))
84
85    graph.add((exception_node, RDF.type, SPDX_NAMESPACE.LicenseException))