root/livinglogic.python.xist/src/ll/xist/sims.py @ 3109:55f21964e0a3

Revision 3109:55f21964e0a3, 6.3 KB (checked in by Walter Doerwald <walter@…>, 12 years ago)

Add docformat.

  • Property exe set to *
Line 
1# -*- coding: utf-8 -*-
2
3## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany
4## Copyright 1999-2008 by Walter Dörwald
5##
6## All Rights Reserved
7##
8## See xist/__init__.py for the license
9
10
11"""
12This module contains classes for a very simple validation model.
13"""
14
15
16import warnings
17from ll.xist import xsc
18
19
20__docformat__ = "xist"
21
22
23class SIMSWarning(xsc.Warning):
24    """
25    Base class for all warning classes in this module.
26    """
27
28
29class EmptyElementWithContentWarning(SIMSWarning):
30    """
31    Warning that is issued when an element has content, but it shouldn't
32    (i.e. <lit>model</lit> is <pyref class="Empty"><class>Empty</class></pyref>)
33    """
34
35    def __init__(self, node):
36        self.node = node
37
38    def __str__(self):
39        s = "element %r" % self.node
40        if self.node.startloc is not None:
41            s += " at %s" % self.node.startloc
42        s += " has EMPTY content model, but has content"
43        return s
44
45
46class WrongElementWarning(SIMSWarning):
47    """
48    Warning that is issued when an element contains another element of a
49    certain type, but shouldn't.
50    """
51
52    def __init__(self, node, badnode, elements):
53        self.node = node
54        self.badnode = badnode
55        self.elements = elements
56
57    def __str__(self):
58        return "element %r may not contain element %r" % (self.node, self.badnode)
59
60
61class ElementWarning(SIMSWarning):
62    """
63    Warning that is issued when an element contains another element but
64    shouldn't contain any.
65    """
66
67    def __init__(self, node, badnode):
68        self.node = node
69        self.badnode = badnode
70
71    def __str__(self):
72        return "element %r may not contain other elements" % self.node
73
74
75class IllegalTextWarning(SIMSWarning):
76    """
77    Warning that is issued when an element contains a text node but shouldn't.
78    """
79
80    def __init__(self, node, badnode):
81        self.node = node
82        self.badnode = badnode
83
84    def __str__(self):
85        return "element %r may not contain text nodes" % self.node
86
87
88def badtext(node):
89    """
90    Return whether <arg>node</arg> is a text node (i.e.
91    <pyref module="ll.xist" class="Text"><class>Text</class></pyref>
92    that does not consist of whitespace only).
93    """
94    if isinstance(node, xsc.Text):
95        if node and not node.isspace():
96            return True
97    return False
98
99
100class Empty(object):
101    """
102    This validator checks that an element has no content.
103    """
104    empty = True
105
106    def __repr__(self):
107        return "Empty()"
108
109    def checkvalid(self, node):
110        """
111        check that the content of <arg>node</arg> is valid.
112        """
113        if isinstance(node, xsc.Element):
114            if len(node):
115                warnings.warn(EmptyElementWithContentWarning(node))
116
117
118class NoElements(object):
119    """
120    This validator checks that an element does not have child elements
121    from the same namespace.
122    """
123    empty = False
124
125    def __repr__(self):
126        return "NoElements()"
127
128    def checkvalid(self, node):
129        """
130        check that the content of <arg>node</arg> is valid.
131        """
132        if isinstance(node, xsc.Element):
133            for child in node.content:
134                if isinstance(child, xsc.Element) and node.xmlns is not None and child.xmlns is not None and child.xmlns == node.xmlns:
135                    warnings.warn(ElementWarning(node, child))
136
137
138class NoElementsOrText(object):
139    """
140    This validator checks that an element does have neither child elements
141    from the same namespace nor real (i.e. not-whitespace) text nodes.
142    """
143    empty = False
144
145    def __repr__(self):
146        return "NoElementsOrText()"
147
148    def checkvalid(self, node):
149        """
150        check that the content of <arg>node</arg> is valid.
151        """
152        if isinstance(node, xsc.Element):
153            for child in node.content:
154                if badtext(child):
155                    warnings.warn(IllegalTextWarning(node, child))
156                elif isinstance(child, xsc.Element) and node.xmlns is not None and child.xmlns is not None and child.xmlns == node.xmlns:
157                    warnings.warn(ElementWarning(node, child))
158
159
160class Elements(object):
161    """
162    This validator checks that an element does have neither child elements
163    from any of the namespaces of those elements specified in the constructor
164    except for those elements itself nor real (i.e. not-whitespace) text nodes.
165    """
166    empty = False
167
168    def __init__(self, *elements):
169        """
170        Every element in <lit>elements</lit> may be in the content of the
171        node to which this validator is attached. Any other element from one
172        of the namespaces of those elements is invalid. Elements from other
173        namespaces are OK.
174        """
175        self.elements = elements
176
177    def __repr__(self):
178        return "Elements(%s)" % ", ".join("%s.%s" % (cls.__module__, cls.__name__) for cls in self.elements)
179
180    def checkvalid(self, node):
181        """
182        check that the content of <arg>node</arg> is valid.
183        """
184        ns = None
185        if isinstance(node, xsc.Element):
186            for child in node.content:
187                if badtext(child):
188                    warnings.warn(IllegalTextWarning(node, child))
189                elif isinstance(child, xsc.Element) and node.xmlns is not None and not isinstance(child, self.elements):
190                    if ns is None: # Calculate the first time we need it
191                        ns = set(el.xmlns for el in self.elements if el.xmlns is not None)
192                    if child.xmlns in ns:
193                        warnings.warn(WrongElementWarning(node, child, self.elements))
194
195
196class ElementsOrText(Elements):
197    """
198    This validator checks that an element doesn't have child elements
199    from the same namespace except those specified in the constructor.
200    """
201
202    def __init__(self, *elements):
203        """
204        Every element in <lit>elements</lit> may be in the content of the
205        node to which this validator is attached. Any other element from one
206        of the namespaces of those elements is invalid. Elements from other
207        namespaces are OK.
208        """
209        self.elements = elements
210
211    def __repr__(self):
212        return "ElementsOrText(%s)" % ", ".join("%s.%s" % (cls.__module__, cls.__name__) for cls in self.elements)
213
214    def checkvalid(self, node):
215        """
216        check that the content of <arg>node</arg> is valid.
217        """
218        ns = None
219        if isinstance(node, xsc.Element):
220            for child in node.content:
221                if isinstance(child, xsc.Element) and node.xmlns is not None and not isinstance(child, self.elements):
222                    if ns is None: # Calculate the first time we need it
223                        ns = set(el.xmlns for el in self.elements if el.xmlns is not None)
224                    if child.xmlns in ns:
225                        warnings.warn(WrongElementWarning(node, child, self.elements))
226
227
228class Any(object):
229    """
230    This validator declares any content to be valid.
231    """
232    empty = False
233
234    def __repr__(self):
235        return "Any()"
236
237    def checkvalid(self, node):
238        """
239        Check that the content of <arg>node</arg> is valid.
240        This method does nothing as anything is valid.
241        """
242
243
244# always show warnings from sims errors
245warnings.filterwarnings("always", category=SIMSWarning)
Note: See TracBrowser for help on using the browser.