spdx_tools.spdx.jsonschema.snippet_converter
1# SPDX-FileCopyrightText: 2022 spdx contributors 2# 3# SPDX-License-Identifier: Apache-2.0 4from beartype.typing import Any, Dict, Tuple, Type 5 6from spdx_tools.spdx.jsonschema.annotation_converter import AnnotationConverter 7from spdx_tools.spdx.jsonschema.converter import TypedConverter 8from spdx_tools.spdx.jsonschema.json_property import JsonProperty 9from spdx_tools.spdx.jsonschema.optional_utils import apply_if_present 10from spdx_tools.spdx.jsonschema.snippet_properties import SnippetProperty 11from spdx_tools.spdx.model import Document, Snippet 12 13 14class SnippetConverter(TypedConverter[Snippet]): 15 annotation_converter: AnnotationConverter 16 17 def __init__(self): 18 self.annotation_converter = AnnotationConverter() 19 20 def json_property_name(self, snippet_property: SnippetProperty) -> str: 21 if snippet_property == SnippetProperty.SPDX_ID: 22 return "SPDXID" 23 return super().json_property_name(snippet_property) 24 25 def _get_property_value( 26 self, snippet: Snippet, snippet_property: SnippetProperty, document: Document = None 27 ) -> Any: 28 if snippet_property == SnippetProperty.SPDX_ID: 29 return snippet.spdx_id 30 elif snippet_property == SnippetProperty.ANNOTATIONS: 31 snippet_annotations = filter( 32 lambda annotation: annotation.spdx_id == snippet.spdx_id, document.annotations 33 ) 34 return [self.annotation_converter.convert(annotation) for annotation in snippet_annotations] or None 35 elif snippet_property == SnippetProperty.ATTRIBUTION_TEXTS: 36 return snippet.attribution_texts or None 37 elif snippet_property == SnippetProperty.COMMENT: 38 return snippet.comment 39 elif snippet_property == SnippetProperty.COPYRIGHT_TEXT: 40 return apply_if_present(str, snippet.copyright_text) 41 elif snippet_property == SnippetProperty.LICENSE_COMMENTS: 42 return snippet.license_comment 43 elif snippet_property == SnippetProperty.LICENSE_CONCLUDED: 44 return apply_if_present(str, snippet.license_concluded) 45 elif snippet_property == SnippetProperty.LICENSE_INFO_IN_SNIPPETS: 46 return [str(license_expression) for license_expression in snippet.license_info_in_snippet] or None 47 elif snippet_property == SnippetProperty.NAME: 48 return snippet.name 49 elif snippet_property == SnippetProperty.RANGES: 50 ranges = [convert_byte_range_to_dict(snippet.byte_range, snippet.file_spdx_id)] 51 if snippet.line_range: 52 ranges.append(convert_line_range_to_dict(snippet.line_range, snippet.file_spdx_id)) 53 return ranges 54 elif snippet_property == SnippetProperty.SNIPPET_FROM_FILE: 55 return snippet.file_spdx_id 56 57 def get_json_type(self) -> Type[JsonProperty]: 58 return SnippetProperty 59 60 def get_data_model_type(self) -> Type[Snippet]: 61 return Snippet 62 63 def requires_full_document(self) -> bool: 64 return True 65 66 67def convert_line_range_to_dict(line_range: Tuple[int, int], file_id: str) -> Dict: 68 return _convert_range_to_dict(line_range, file_id, "lineNumber") 69 70 71def convert_byte_range_to_dict(byte_range: Tuple[int, int], file_id: str) -> Dict: 72 return _convert_range_to_dict(byte_range, file_id, "offset") 73 74 75def _convert_range_to_dict(int_range: Tuple[int, int], file_id: str, pointer_property: str) -> Dict: 76 return { 77 "startPointer": _pointer(file_id, int_range[0], pointer_property), 78 "endPointer": _pointer(file_id, int_range[1], pointer_property), 79 } 80 81 82def _pointer(reference: str, target: int, pointer_property: str) -> Dict: 83 return {"reference": reference, pointer_property: target}
class
SnippetConverter(spdx_tools.spdx.jsonschema.converter.TypedConverter[spdx_tools.spdx.model.snippet.Snippet]):
15class SnippetConverter(TypedConverter[Snippet]): 16 annotation_converter: AnnotationConverter 17 18 def __init__(self): 19 self.annotation_converter = AnnotationConverter() 20 21 def json_property_name(self, snippet_property: SnippetProperty) -> str: 22 if snippet_property == SnippetProperty.SPDX_ID: 23 return "SPDXID" 24 return super().json_property_name(snippet_property) 25 26 def _get_property_value( 27 self, snippet: Snippet, snippet_property: SnippetProperty, document: Document = None 28 ) -> Any: 29 if snippet_property == SnippetProperty.SPDX_ID: 30 return snippet.spdx_id 31 elif snippet_property == SnippetProperty.ANNOTATIONS: 32 snippet_annotations = filter( 33 lambda annotation: annotation.spdx_id == snippet.spdx_id, document.annotations 34 ) 35 return [self.annotation_converter.convert(annotation) for annotation in snippet_annotations] or None 36 elif snippet_property == SnippetProperty.ATTRIBUTION_TEXTS: 37 return snippet.attribution_texts or None 38 elif snippet_property == SnippetProperty.COMMENT: 39 return snippet.comment 40 elif snippet_property == SnippetProperty.COPYRIGHT_TEXT: 41 return apply_if_present(str, snippet.copyright_text) 42 elif snippet_property == SnippetProperty.LICENSE_COMMENTS: 43 return snippet.license_comment 44 elif snippet_property == SnippetProperty.LICENSE_CONCLUDED: 45 return apply_if_present(str, snippet.license_concluded) 46 elif snippet_property == SnippetProperty.LICENSE_INFO_IN_SNIPPETS: 47 return [str(license_expression) for license_expression in snippet.license_info_in_snippet] or None 48 elif snippet_property == SnippetProperty.NAME: 49 return snippet.name 50 elif snippet_property == SnippetProperty.RANGES: 51 ranges = [convert_byte_range_to_dict(snippet.byte_range, snippet.file_spdx_id)] 52 if snippet.line_range: 53 ranges.append(convert_line_range_to_dict(snippet.line_range, snippet.file_spdx_id)) 54 return ranges 55 elif snippet_property == SnippetProperty.SNIPPET_FROM_FILE: 56 return snippet.file_spdx_id 57 58 def get_json_type(self) -> Type[JsonProperty]: 59 return SnippetProperty 60 61 def get_data_model_type(self) -> Type[Snippet]: 62 return Snippet 63 64 def requires_full_document(self) -> bool: 65 return True
Base class for all converters between an instance of the tools-python data model and the corresponding dictionary representation, following the json schema. The generic type T is the type according to the data model. Each converter has several methods:
- get_json_type and get_data_model_type: return the data model type and the corresponding JsonProperty subclass. These methods are abstract in the base class and need to be implemented in subclasses.
- json_property_name: converts an enum value of a JsonProperty subclass to the corresponding property name in the json schema. The default implementation simply converts from snake case to camel case. Can be overridden in case of exceptions like "SPDXID".
- convert: converts an instance of type T (one of the data model types) to a dictionary representation. In some cases, the full document is required (see below). The logic should be generic for all types.
- requires_full_document: indicates whether the full document is required for conversion. Returns False by default, can be overridden as needed for specific types.
- _get_property_value: Retrieves the value of a specific json property from the data model instance. In some cases, the full document is required.
annotation_converter: spdx_tools.spdx.jsonschema.annotation_converter.AnnotationConverter
def
json_property_name( self, snippet_property: spdx_tools.spdx.jsonschema.snippet_properties.SnippetProperty) -> str:
Inherited Members
def
convert_line_range_to_dict(line_range: tuple[int, int], file_id: str) -> dict:
def
convert_byte_range_to_dict(byte_range: tuple[int, int], file_id: str) -> dict: