~jocave/checkbox/hybrid-amd-gpu-mods

« back to all changes in this revision

Viewing changes to checkbox-old/checkbox/report.py

  • Committer: Tarmac
  • Author(s): Brendan Donegan
  • Date: 2013-06-03 11:12:58 UTC
  • mfrom: (2154.2.1 bug1185759)
  • Revision ID: tarmac-20130603111258-1b3m5ydvkf1accts
"[r=zkrynicki][bug=1185759][author=brendan-donegan] automatic merge by tarmac"

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#
 
2
# This file is part of Checkbox.
 
3
#
 
4
# Copyright 2008 Canonical Ltd.
 
5
#
 
6
# Checkbox is free software: you can redistribute it and/or modify
 
7
# it under the terms of the GNU General Public License as published by
 
8
# the Free Software Foundation, either version 3 of the License, or
 
9
# (at your option) any later version.
 
10
#
 
11
# Checkbox is distributed in the hope that it will be useful,
 
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
# GNU General Public License for more details.
 
15
#
 
16
# You should have received a copy of the GNU General Public License
 
17
# along with Checkbox.  If not, see <http://www.gnu.org/licenses/>.
 
18
#
 
19
import posixpath
 
20
 
 
21
from lxml import etree
 
22
from xml.dom.minidom import Document, Element, parseString
 
23
 
 
24
 
 
25
class ReportManager:
 
26
    """The central point for dumping and loading information.
 
27
 
 
28
    This keeps references to all reports which have been added to the
 
29
    instance of this manager. These reports will be able to register
 
30
    handlers to understand the formats for dumping and loading actions.
 
31
    """
 
32
 
 
33
    def __init__(self, name, version=None, stylesheet=None, schema=None):
 
34
        self.name = name
 
35
        self.version = version
 
36
        self.stylesheet = stylesheet
 
37
        self.schema = schema
 
38
        self.dumps_table = {}
 
39
        self.loads_table = {}
 
40
 
 
41
    def handle_dumps(self, type, handler):
 
42
        """
 
43
        Call back method for reports to register dump handlers.
 
44
        """
 
45
        if type in self.dumps_table:
 
46
            raise Exception("Dumps type already handled: %s" % type)
 
47
        self.dumps_table[type] = handler
 
48
 
 
49
    def handle_loads(self, type, handler):
 
50
        """
 
51
        Call back method for reports to register load handlers.
 
52
        """
 
53
        if type in self.loads_table:
 
54
            raise Exception("Loads type already handled: %s" % type)
 
55
        self.loads_table[type] = handler
 
56
 
 
57
    def call_dumps(self, obj, node):
 
58
        """
 
59
        Convenience method for reports to call the dump handler
 
60
        corresponding to the type of the given object.
 
61
        """
 
62
        return self.dumps_table[type(obj)](obj, node)
 
63
 
 
64
    def call_loads(self, node):
 
65
        """
 
66
        Convenience method for reports to call the load handler
 
67
        corresponding to the content of the given node.
 
68
        """
 
69
        if node.localName in self.loads_table:
 
70
            ret = self.loads_table[node.localName](node)
 
71
        elif isinstance(node, Element) and node.hasAttribute("type"):
 
72
            type = node.getAttribute("type")
 
73
            ret = self.loads_table[type](node)
 
74
        else:
 
75
            ret = self.loads_table["default"](node)
 
76
        return ret
 
77
 
 
78
    def add(self, report):
 
79
        """
 
80
        Add a new report to the manager.
 
81
        """
 
82
        report.register(self)
 
83
 
 
84
    def dumps(self, obj):
 
85
        """
 
86
        Dump the given object which may be a container of any objects
 
87
        supported by the reports added to the manager.
 
88
        """
 
89
        document = Document()
 
90
 
 
91
        if self.stylesheet:
 
92
            type = "text/xsl"
 
93
            href = "file://%s" % posixpath.abspath(self.stylesheet)
 
94
            style = document.createProcessingInstruction("xml-stylesheet",
 
95
                "type=\"%s\" href=\"%s\"" % (type, href))
 
96
            document.appendChild(style)
 
97
 
 
98
        node = document.createElement(self.name)
 
99
        document.appendChild(node)
 
100
 
 
101
        if self.version:
 
102
            node.setAttribute("version", self.version)
 
103
 
 
104
        try:
 
105
            self.call_dumps(obj, node)
 
106
        except KeyError as e:
 
107
            raise ValueError("Unsupported type: %s" % e)
 
108
 
 
109
        return document
 
110
 
 
111
    def loads(self, string):
 
112
        """
 
113
        Load the given string which may be a container of any nodes
 
114
        supported by the reports added to the manager.
 
115
        """
 
116
        document = parseString(string)
 
117
        node = document.childNodes[0]
 
118
        assert(node.localName == self.name)
 
119
 
 
120
        try:
 
121
            ret = self.call_loads(document)
 
122
        except KeyError as e:
 
123
            raise ValueError("Unsupported type: %s" % e)
 
124
 
 
125
        return ret
 
126
 
 
127
    def validate(self, string):
 
128
        """
 
129
        Validate the given string
 
130
        """
 
131
        if not self.schema:
 
132
            return False
 
133
 
 
134
        file = open(self.schema)
 
135
        try:
 
136
            schema = file.read()
 
137
        finally:
 
138
            file.close()
 
139
 
 
140
        relaxng_doc = etree.fromstring(schema)
 
141
        relaxng = etree.RelaxNG(relaxng_doc)
 
142
 
 
143
        doc = etree.fromstring(string)
 
144
        return relaxng.validate(doc)
 
145
 
 
146
 
 
147
class Report:
 
148
    """A convenience for writing reports.
 
149
 
 
150
    This provides a register method which will set the manager attribute
 
151
    and optionally call the C{register_dumps} and C{register_loads}
 
152
    methods.
 
153
    """
 
154
 
 
155
    def _create_element(self, name, parent):
 
156
        element = parent.ownerDocument.createElement(name)
 
157
        parent.appendChild(element)
 
158
        return element
 
159
 
 
160
    def _create_text_node(self, text, parent):
 
161
        text_node = parent.ownerDocument.createTextNode(text)
 
162
        parent.appendChild(text_node)
 
163
        return text_node
 
164
 
 
165
    def register(self, manager):
 
166
        self._manager = manager
 
167
        if hasattr(self, "register_dumps"):
 
168
            self.register_dumps()
 
169
        if hasattr(self, "register_loads"):
 
170
            self.register_loads()