Statistics
| Branch: | Tag: | Revision:

root / ncclient / glue.py @ 1d540e60

History | View | Annotate | Download (3 kB)

1 2bfd0fef Shikhar Bhushan
# Copyright 2009 Shikhar Bhushan
2 2bfd0fef Shikhar Bhushan
#
3 2bfd0fef Shikhar Bhushan
# Licensed under the Apache License, Version 2.0 (the "License");
4 2bfd0fef Shikhar Bhushan
# you may not use this file except in compliance with the License.
5 2bfd0fef Shikhar Bhushan
# You may obtain a copy of the License at
6 2bfd0fef Shikhar Bhushan
#
7 2bfd0fef Shikhar Bhushan
#    http://www.apache.org/licenses/LICENSE-2.0
8 2bfd0fef Shikhar Bhushan
#
9 2bfd0fef Shikhar Bhushan
# Unless required by applicable law or agreed to in writing, software
10 2bfd0fef Shikhar Bhushan
# distributed under the License is distributed on an "AS IS" BASIS,
11 2bfd0fef Shikhar Bhushan
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 2bfd0fef Shikhar Bhushan
# See the License for the specific language governing permissions and
13 2bfd0fef Shikhar Bhushan
# limitations under the License.
14 2bfd0fef Shikhar Bhushan
15 2bfd0fef Shikhar Bhushan
"TODO: docstring"
16 2bfd0fef Shikhar Bhushan
17 2bfd0fef Shikhar Bhushan
from cStringIO import StringIO
18 1d540e60 Shikhar Bhushan
from threading import Thread
19 2bfd0fef Shikhar Bhushan
from Queue import Queue
20 2bfd0fef Shikhar Bhushan
from threading import Lock
21 2bfd0fef Shikhar Bhushan
from xml.etree import cElementTree as ET
22 2bfd0fef Shikhar Bhushan
23 1d540e60 Shikhar Bhushan
import logging
24 1d540e60 Shikhar Bhushan
logger = logging.getLogger('ncclient.glue')
25 2bfd0fef Shikhar Bhushan
26 2bfd0fef Shikhar Bhushan
def parse_root(raw):
27 2bfd0fef Shikhar Bhushan
    '''Parse the top-level element from a string representing an XML document.
28 2bfd0fef Shikhar Bhushan
    
29 2bfd0fef Shikhar Bhushan
    Returns a `(tag, attributes)` tuple, where `tag` is a string representing
30 2bfd0fef Shikhar Bhushan
    the qualified name of the root element and `attributes` is an
31 2bfd0fef Shikhar Bhushan
    `{attribute: value}` dictionary.
32 2bfd0fef Shikhar Bhushan
    '''
33 2bfd0fef Shikhar Bhushan
    fp = StringIO(raw)
34 2bfd0fef Shikhar Bhushan
    for event, element in ET.iterparse(fp, events=('start',)):
35 2bfd0fef Shikhar Bhushan
        return (element.tag, element.attrib)
36 2bfd0fef Shikhar Bhushan
37 2bfd0fef Shikhar Bhushan
38 1d540e60 Shikhar Bhushan
class Subject(Thread):
39 bf31e33e Shikhar Bhushan
    
40 bf31e33e Shikhar Bhushan
    'Meant for subclassing by transport.Session'
41 2bfd0fef Shikhar Bhushan
42 2bfd0fef Shikhar Bhushan
    def __init__(self):
43 2bfd0fef Shikhar Bhushan
        "TODO: docstring"
44 1d540e60 Shikhar Bhushan
        Thread.__init__(self)
45 e91a5349 Shikhar Bhushan
        self._q = Queue()
46 1d540e60 Shikhar Bhushan
        self._listeners = set() # TODO(?) weakref
47 2bfd0fef Shikhar Bhushan
        self._lock = Lock()
48 e91a5349 Shikhar Bhushan
    
49 2bfd0fef Shikhar Bhushan
    def _dispatch_received(self, raw):
50 2bfd0fef Shikhar Bhushan
        "TODO: docstring"
51 2bfd0fef Shikhar Bhushan
        root = parse_root(raw)
52 2bfd0fef Shikhar Bhushan
        with self._lock:
53 2bfd0fef Shikhar Bhushan
            listeners = list(self._listeners)
54 2bfd0fef Shikhar Bhushan
        for l in listeners:
55 1d540e60 Shikhar Bhushan
            logger.debug('[dispatching] message to %s' % l)
56 4f748648 Shikhar Bhushan
            l.callback(root, raw)
57 2bfd0fef Shikhar Bhushan
    
58 2bfd0fef Shikhar Bhushan
    def _dispatch_error(self, err):
59 2bfd0fef Shikhar Bhushan
        "TODO: docstring"
60 2bfd0fef Shikhar Bhushan
        with self._lock:
61 2bfd0fef Shikhar Bhushan
            listeners = list(self._listeners)
62 2bfd0fef Shikhar Bhushan
        for l in listeners:
63 1d540e60 Shikhar Bhushan
            logger.debug('[dispatching] error to %s' % l)
64 2bfd0fef Shikhar Bhushan
            l.errback(err)
65 2bfd0fef Shikhar Bhushan
    
66 2bfd0fef Shikhar Bhushan
    def add_listener(self, listener):
67 2bfd0fef Shikhar Bhushan
        "TODO: docstring"
68 1d540e60 Shikhar Bhushan
        logger.debug('[installing listener] %r' % listener)
69 2bfd0fef Shikhar Bhushan
        with self._lock:
70 2bfd0fef Shikhar Bhushan
            self._listeners.add(listener)
71 2bfd0fef Shikhar Bhushan
    
72 2bfd0fef Shikhar Bhushan
    def remove_listener(self, listener):
73 2bfd0fef Shikhar Bhushan
        "TODO: docstring"
74 1d540e60 Shikhar Bhushan
        logger.debug('[discarding listener] %r' % listener)
75 2bfd0fef Shikhar Bhushan
        with self._lock:
76 2bfd0fef Shikhar Bhushan
            self._listeners.discard(listener)
77 2bfd0fef Shikhar Bhushan
    
78 ea04739a Shikhar Bhushan
    def get_listener_instance(self, cls):
79 ea04739a Shikhar Bhushan
        '''This is useful when we want to maintain one listener of a particular
80 ea04739a Shikhar Bhushan
        type per subject i.e. a multiton.
81 ea04739a Shikhar Bhushan
        '''
82 ea04739a Shikhar Bhushan
        with self._lock:
83 ea04739a Shikhar Bhushan
            for listener in self._listeners:
84 ea04739a Shikhar Bhushan
                if isinstance(listener, cls):
85 ea04739a Shikhar Bhushan
                    return listener
86 ea04739a Shikhar Bhushan
    
87 2bfd0fef Shikhar Bhushan
    def send(self, message):
88 2bfd0fef Shikhar Bhushan
        "TODO: docstring"
89 1d540e60 Shikhar Bhushan
        logger.debug('[queueing] %s' % message)
90 e91a5349 Shikhar Bhushan
        self._q.put(message)
91 2bfd0fef Shikhar Bhushan
92 2bfd0fef Shikhar Bhushan
93 ea04739a Shikhar Bhushan
class Listener(object):
94 2bfd0fef Shikhar Bhushan
    
95 4f748648 Shikhar Bhushan
    "TODO: docstring"
96 4f748648 Shikhar Bhushan
    
97 4f748648 Shikhar Bhushan
    def callback(self, root, raw):
98 2bfd0fef Shikhar Bhushan
        raise NotImplementedError
99 2bfd0fef Shikhar Bhushan
    
100 2bfd0fef Shikhar Bhushan
    def errback(self, err):
101 2bfd0fef Shikhar Bhushan
        raise NotImplementedError