Statistics
| Branch: | Tag: | Revision:

root / ncclient / content / builders.py @ dfdcbb0c

History | View | Annotate | Download (3.5 kB)

1
# Copyright 2009 Shikhar Bhushan
2
#
3
# Licensed under the Apache License, Version 2.0 (the "License");
4
# you may not use this file except in compliance with the License.
5
# You may obtain a copy of the License at
6
#
7
#    http://www.apache.org/licenses/LICENSE-2.0
8
#
9
# Unless required by applicable law or agreed to in writing, software
10
# distributed under the License is distributed on an "AS IS" BASIS,
11
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
# See the License for the specific language governing permissions and
13
# limitations under the License.
14

    
15
from xml.etree import cElementTree as ET
16

    
17
from common import BASE_NS
18
from common import qualify as _
19

    
20
try:
21
    register_namespace = ET.register_namespace
22
except AttributeError:
23
    def register_namespace(prefix, uri):
24
        from xml.etree import ElementTree
25
        # cElementTree uses ElementTree's _namespace_map
26
        ElementTree._namespace_map[uri] = prefix
27

    
28
register_namespace('netconf', BASE_NS)
29

    
30
class TreeBuilder:
31
    '''Build an ElementTree.Element instance from an XML tree specification
32
    based on nested dictionaries.
33
    '''
34
    
35
    def __init__(self, spec):
36
        self._root = TreeBuilder.build(spec)
37
        
38
    def to_string(self, encoding='utf-8'):
39
        # etree does not include the <?xml..?> processing instruction
40
        # if encoding is utf-8. this is a problem with cisco routers.
41
        prepend = '<?xml version="1.0" encoding="UTF-8"?>' if encoding=='utf-8' else ''
42
        return prepend + ET.tostring(self._root, encoding)
43
    
44
    @property
45
    def tree(self):
46
        return self._root
47
    
48
    @staticmethod
49
    def build(spec):
50
        'Returns constructed ElementTree.Element'
51
        if spec.has_key('tag'):
52
            ele = ET.Element(spec.get('tag'), spec.get('attributes', {}))
53
            ele.text = spec.get('text', '')
54
            children = spec.get('children', [])
55
            if isinstance(children, dict):
56
                children = [children]
57
            for child in children:
58
                ele.append(TreeBuilder.build(child))
59
            return ele
60
        elif spec.has_key('comment'):
61
            return ET.Comment(spec.get('comment'))
62
        else:
63
            raise ValueError('Invalid tree spec')
64

    
65

    
66
class HelloBuilder:
67
        
68
    @staticmethod
69
    def build(capabilities, encoding='utf-8'):
70
        children = [{'tag': 'capability', 'text': uri } for uri in capabilities]
71
        spec = {
72
            'tag': _('hello', BASE_NS),
73
            'children': [{
74
                        'tag': u'capabilities',
75
                        'children': children
76
                        }]
77
            }
78
        return TreeBuilder(spec).to_string(encoding)
79

    
80
class RPCBuilder:
81
    
82
    @staticmethod
83
    def build(msgid, op, encoding='utf-8'):
84
        if isinstance(op, basestring):
85
            return RPCBuilder.build_from_string(msgid, op, encoding)
86
        else:
87
            return RPCBuilder.build_from_spec(msgid, op, encoding)
88
    
89
    @staticmethod
90
    def build_from_spec(msgid, opspec, encoding='utf-8'):
91
        spec = {
92
            'tag': _('rpc', BASE_NS),
93
            'attributes': {'message-id': msgid},
94
            'children': opspec
95
            }
96
        return TreeBuilder(spec).to_string(encoding)
97
    
98
    @staticmethod
99
    def build_from_string(msgid, opstr, encoding='utf-8'):
100
        decl = '<?xml version="1.0" encoding="%s"?>' % encoding
101
        doc = (u'''<rpc message-id="%s" xmlns="%s">%s</rpc>''' %
102
               (msgid, BASE_NS, opstr)).encode(encoding)
103
        return (decl + doc)