Completed
Push — master ( 291ee9...9d841e )
by Matěj
20s queued 12s
created

ssg._id_translate.IDTranslator.translate()   F

Complexity

Conditions 12

Size

Total Lines 39
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 12
eloc 34
nop 3
dl 0
loc 39
rs 2.7855
c 0
b 0
f 0

How to fix   Complexity   

Complexity

Complex classes like ssg._id_translate.IDTranslator.translate() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
from ssg._xml import ElementTree
0 ignored issues
show
Coding Style introduced by
This module should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
2
from ssg._constants import oval_namespace as oval_ns
3
from ssg._constants import ocil_namespace as ocil_ns
4
5
ovaltag_to_abbrev = {
0 ignored issues
show
Coding Style Naming introduced by
The name ovaltag_to_abbrev does not conform to the constant naming conventions ((([A-Z_][A-Z0-9_]*)|(__.*__))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
6
    'definition': 'def',
7
    'criteria': 'crit',
8
    'test': 'tst',
9
    'object': 'obj',
10
    'state': 'ste',
11
    'variable': 'var',
12
}
13
14
ociltag_to_abbrev = {
0 ignored issues
show
Coding Style Naming introduced by
The name ociltag_to_abbrev does not conform to the constant naming conventions ((([A-Z_][A-Z0-9_]*)|(__.*__))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
15
    'questionnaire': 'questionnaire',
16
    'action': 'testaction',
17
    'question': 'question',
18
    'artifact': 'artifact',
19
    'variable': 'variable',
20
}
21
22
ovalrefattr_to_tag = {
0 ignored issues
show
Coding Style Naming introduced by
The name ovalrefattr_to_tag does not conform to the constant naming conventions ((([A-Z_][A-Z0-9_]*)|(__.*__))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
23
    "definition_ref": "definition",
24
    "test_ref": "test",
25
    "object_ref": "object",
26
    "state_ref": "state",
27
    "var_ref": "variable",
28
}
29
30
ocilrefattr_to_tag = {
0 ignored issues
show
Coding Style Naming introduced by
The name ocilrefattr_to_tag does not conform to the constant naming conventions ((([A-Z_][A-Z0-9_]*)|(__.*__))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
31
    "question_ref": "question",
32
}
33
34
ocilrefchild_to_tag = {
0 ignored issues
show
Coding Style Naming introduced by
The name ocilrefchild_to_tag does not conform to the constant naming conventions ((([A-Z_][A-Z0-9_]*)|(__.*__))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
35
    "test_action_ref": "action",
36
}
37
38
39
def _split_namespace(tag):
40
    """returns a tuple of (namespace,name) removing any fragment id
41
    from namespace"""
42
43
    if tag[0] == "{":
0 ignored issues
show
unused-code introduced by
Unnecessary "else" after "return"
Loading history...
44
        namespace, name = tag[1:].split("}", 1)
45
        return namespace.split("#")[0], name
46
    else:
47
        return (None, tag)
48
49
50
def _namespace_to_prefix(tag):
51
    namespace, _ = _split_namespace(tag)
52
    if namespace == ocil_ns:
53
        return "ocil"
54
    if namespace == oval_ns:
55
        return "oval"
56
57
    raise RuntimeError(
58
        "Error: unknown checksystem referenced in tag : %s" % tag
59
    )
60
61
62
def _tagname_to_abbrev(tag):
63
    namespace, tag = _split_namespace(tag)
64
    if tag == "extend_definition":
65
        return tag
66
    # grab the last part of the tag name to determine its type
67
    tag = tag.rsplit("_", 1)[-1]
68
    if namespace == ocil_ns:
69
        return ociltag_to_abbrev[tag]
70
    if namespace == oval_ns:
71
        return ovaltag_to_abbrev[tag]
72
73
    raise RuntimeError(
74
        "Error: unknown checksystem referenced in tag : %s" % tag
75
    )
76
77
78
class IDTranslator(object):
0 ignored issues
show
Unused Code introduced by
The variable __class__ seems to be unused.
Loading history...
79
    """This class is designed to handle the mapping of meaningful, human-readable
80
    names to IDs in the formats required by the SCAP checking systems, such as
81
    OVAL and OCIL."""
82
83
    def __init__(self, content_id):
84
        self.content_id = content_id
85
86
    def generate_id(self, tagname, name):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
87
        return "%s:%s-%s:%s:1" % (
88
            _namespace_to_prefix(tagname),
89
            self.content_id, name,
90
            _tagname_to_abbrev(tagname)
91
        )
92
93
    def translate(self, tree, store_defname=False):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
94
        for element in tree.getiterator():
95
            idname = element.get("id")
96
            if idname:
97
                # store the old name if requested (for OVAL definitions)
98
                if store_defname and \
99
                        element.tag == "{%s}definition" % oval_ns:
100
                    metadata = element.find("{%s}metadata" % oval_ns)
101
                    if metadata is None:
102
                        metadata = ElementTree.SubElement(element, "metadata")
103
                    defnam = ElementTree.Element(
104
                        "reference", ref_id=idname, source=self.content_id)
105
                    metadata.append(defnam)
106
107
                # set the element to the new identifier
108
                element.set("id", self.generate_id(element.tag, idname))
109
                # continue
110
            if element.tag == "{%s}filter" % oval_ns:
111
                element.text = self.generate_id("{%s}state" % oval_ns,
112
                                                element.text)
113
                continue
114
            if element.tag == "{%s#independent}var_ref" % oval_ns:
115
                element.text = self.generate_id("{%s}variable" % oval_ns,
116
                                                element.text)
117
                continue
118
            for attr in element.keys():
119
                if attr in ovalrefattr_to_tag.keys():
120
                    element.set(attr, self.generate_id(
121
                        "{%s}%s" % (oval_ns, ovalrefattr_to_tag[attr]),
122
                        element.get(attr)))
123
                if attr in ocilrefattr_to_tag.keys():
124
                    element.set(attr, self.generate_id(
125
                        "{%s}%s" % (ocil_ns, ocilrefattr_to_tag[attr]),
126
                        element.get(attr)))
127
            if element.tag == "{%s}test_action_ref" % ocil_ns:
128
                element.text = self.generate_id("{%s}action" % ocil_ns,
129
                                                element.text)
130
131
        return tree
132