Changeset 34:5d34b8c88a55 for wokkel


Ignore:
Timestamp:
Oct 10, 2008, 4:35:43 PM (14 years ago)
Author:
Ralph Meijer <ralphm@…>
Branch:
default
Convert:
svn:b33ecbfc-034c-dc11-8662-000475d9059e/trunk@88
Message:

Backport XmlStreamServerFactory?.

Author: ralphm.
Fixes #29.

This also replaces XmlStreamFactoryMixin? with BootstrapMixin? for DeferredClientFactory?.

Location:
wokkel
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • wokkel/client.py

    r14 r34  
    1717
    1818try:
    19     from twisted.words.xish.xmlstream import XmlStreamFactoryMixin
     19    from twisted.words.xish.xmlstream import BootstrapMixin
    2020except ImportError:
    21     from wokkel.compat import XmlStreamFactoryMixin
     21    from wokkel.compat import BootstrapMixin
    2222
    2323from wokkel.subprotocols import StreamManager, XMPPHandler
     
    128128
    129129
    130 class DeferredClientFactory(XmlStreamFactoryMixin, protocol.ClientFactory):
     130class DeferredClientFactory(BootstrapMixin, protocol.ClientFactory):
    131131    protocol = xmlstream.XmlStream
    132132
    133133    def __init__(self, jid, password):
    134         self.authenticator = client.XMPPAuthenticator(jid, password)
    135         XmlStreamFactoryMixin.__init__(self, self.authenticator)
     134        BootstrapMixin.__init__(self)
     135
     136        self.jid = jid
     137        self.password = password
    136138
    137139        deferred = defer.Deferred()
    138140        self.deferred = deferred
    139 
    140141        self.addBootstrap(xmlstream.INIT_FAILED_EVENT, deferred.errback)
    141142
     
    147148        self.addHandler(ConnectionInitializedHandler())
    148149
     150
     151    def buildProtocol(self, addr):
     152        """
     153        Create an instance of XmlStream.
     154
     155        A new authenticator instance will be created and passed to the new
     156        XmlStream. Registered bootstrap event observers are installed as well.
     157        """
     158        self.authenticator = client.XMPPAuthenticator(self.jid, self.password)
     159        xs = self.protocol(self.authenticator)
     160        xs.factory = self
     161        self.installBootstraps(xs)
     162        return xs
     163
     164
    149165    def clientConnectionFailed(self, connector, reason):
    150166        self.deferred.errback(reason)
     167
    151168
    152169    def addHandler(self, handler):
     
    155172        """
    156173        self.streamManager.addHandler(handler)
     174
    157175
    158176    def removeHandler(self, handler):
  • wokkel/compat.py

    r8 r34  
    11# -*- test-case-name: wokkel.test.test_compat -*-
    22#
    3 # Copyright (c) 2001-2007 Twisted Matrix Laboratories.
     3# Copyright (c) 2001-2008 Twisted Matrix Laboratories.
    44# See LICENSE for details.
    55
     6from twisted.internet import protocol
     7from twisted.words.protocols.jabber import xmlstream
    68from twisted.words.xish import domish
    79
     
    3941
    4042
    41 class XmlStreamFactoryMixin(object):
     43
     44class BootstrapMixin(object):
    4245    """
    43     XmlStream factory mixin that takes care of event handlers.
     46    XmlStream factory mixin to install bootstrap event observers.
    4447
    45     To make sure certain event observers are set up before incoming data is
    46     processed, you can set up bootstrap event observers using C{addBootstrap}.
     48    This mixin is for factories providing
     49    L{IProtocolFactory<twisted.internet.interfaces.IProtocolFactory>} to make
     50    sure bootstrap event observers are set up on protocols, before incoming
     51    data is processed. Such protocols typically derive from
     52    L{utility.EventDispatcher}, like L{XmlStream}.
    4753
    48     The C{event} and C{fn} parameters correspond with the C{event} and
     54    You can set up bootstrap event observers using C{addBootstrap}. The
     55    C{event} and C{fn} parameters correspond with the C{event} and
    4956    C{observerfn} arguments to L{utility.EventDispatcher.addObserver}.
     57
     58    @ivar bootstraps: The list of registered bootstrap event observers.
     59    @type bootstrap: C{list}
    5060    """
    5161
    52     def __init__(self, *args, **kwargs):
     62    def __init__(self):
    5363        self.bootstraps = []
    54         self.args = args
    55         self.kwargs = kwargs
    5664
    57     def buildProtocol(self, addr):
     65
     66    def installBootstraps(self, dispatcher):
    5867        """
    59         Create an instance of XmlStream.
     68        Install registered bootstrap observers.
    6069
    61         The returned instance will have bootstrap event observers registered
    62         and will proceed to handle input on an incoming connection.
     70        @param dispatcher: Event dispatcher to add the observers to.
     71        @type dispatcher: L{utility.EventDispatcher}
    6372        """
    64         xs = self.protocol(*self.args, **self.kwargs)
    65         xs.factory = self
    6673        for event, fn in self.bootstraps:
    67             xs.addObserver(event, fn)
    68         return xs
     74            dispatcher.addObserver(event, fn)
     75
    6976
    7077    def addBootstrap(self, event, fn):
     
    7481        self.bootstraps.append((event, fn))
    7582
     83
    7684    def removeBootstrap(self, event, fn):
    7785        """
     
    7987        """
    8088        self.bootstraps.remove((event, fn))
     89
     90
     91
     92class XmlStreamServerFactory(BootstrapMixin,
     93                             protocol.ServerFactory):
     94    """
     95    Factory for Jabber XmlStream objects as a server.
     96
     97    @since: 8.2.
     98    @ivar authenticatorFactory: Factory callable that takes no arguments, to
     99                                create a fresh authenticator to be associated
     100                                with the XmlStream.
     101    """
     102
     103    protocol = xmlstream.XmlStream
     104
     105    def __init__(self, authenticatorFactory):
     106        xmlstream.BootstrapMixin.__init__(self)
     107        self.authenticatorFactory = authenticatorFactory
     108
     109
     110    def buildProtocol(self, addr):
     111        """
     112        Create an instance of XmlStream.
     113
     114        A new authenticator instance will be created and passed to the new
     115        XmlStream. Registered bootstrap event observers are installed as well.
     116        """
     117        authenticator = self.authenticatorFactory()
     118        xs = self.protocol(authenticator)
     119        xs.factory = self
     120        self.installBootstraps(xs)
     121        return xs
  • wokkel/test/test_client.py

    r8 r34  
    77
    88from twisted.trial import unittest
     9from twisted.words.protocols.jabber import xmlstream
     10from twisted.words.protocols.jabber.client import XMPPAuthenticator
    911from twisted.words.protocols.jabber.jid import JID
    1012from twisted.words.protocols.jabber.xmlstream import STREAM_AUTHD_EVENT
     
    1214
    1315from wokkel.client import DeferredClientFactory
     16from wokkel.test.test_compat import BootstrapMixinTest
    1417
    15 class DeferredClientFactoryTest(unittest.TestCase):
     18class DeferredClientFactoryTest(BootstrapMixinTest):
     19
     20
     21    def setUp(self):
     22        self.factory = DeferredClientFactory(JID('user@example.org'), 'secret')
     23
     24
     25    def test_buildProtocol(self):
     26        """
     27        The authenticator factory should be passed to its protocol and it
     28        should instantiate the authenticator and save it.
     29        L{xmlstream.XmlStream}s do that, but we also want to ensure it really
     30        is one.
     31        """
     32        xs = self.factory.buildProtocol(None)
     33        self.assertIdentical(self.factory, xs.factory)
     34        self.assertIsInstance(xs, xmlstream.XmlStream)
     35        self.assertIsInstance(xs.authenticator, XMPPAuthenticator)
     36
    1637
    1738    def test_deferredOnInitialized(self):
     
    2041        """
    2142
    22         f = DeferredClientFactory(JID('user@example.org'), 'secret')
    23         xmlstream = f.buildProtocol(None)
    24         xmlstream.dispatch(xmlstream, STREAM_AUTHD_EVENT)
    25         return f.deferred
     43        xs = self.factory.buildProtocol(None)
     44        xs.dispatch(xs, STREAM_AUTHD_EVENT)
     45        return self.factory.deferred
     46
    2647
    2748    def test_deferredOnNotInitialized(self):
     
    3051        """
    3152
    32         f = DeferredClientFactory(JID('user@example.org'), 'secret')
    33         xmlstream = f.buildProtocol(None)
    34 
    3553        class TestException(Exception):
    3654            pass
    3755
    38         xmlstream.dispatch(TestException(), INIT_FAILED_EVENT)
    39         self.assertFailure(f.deferred, TestException)
    40         return f.deferred
     56        xs = self.factory.buildProtocol(None)
     57        xs.dispatch(TestException(), INIT_FAILED_EVENT)
     58        self.assertFailure(self.factory.deferred, TestException)
     59        return self.factory.deferred
     60
    4161
    4262    def test_deferredOnConnectionFailure(self):
     
    4565        """
    4666
    47         f = DeferredClientFactory(JID('user@example.org'), 'secret')
    48         xmlstream = f.buildProtocol(None)
    49 
    5067        class TestException(Exception):
    5168            pass
    5269
    53         f.clientConnectionFailed(self, TestException())
    54         self.assertFailure(f.deferred, TestException)
    55         return f.deferred
     70        xs = self.factory.buildProtocol(None)
     71        self.factory.clientConnectionFailed(self, TestException())
     72        self.assertFailure(self.factory.deferred, TestException)
     73        return self.factory.deferred
  • wokkel/test/test_compat.py

    r8 r34  
    1010from twisted.trial import unittest
    1111from twisted.words.xish import domish, utility
    12 from wokkel.compat import toResponse, XmlStreamFactoryMixin
     12from wokkel.compat import toResponse, BootstrapMixin
    1313
    1414class DummyProtocol(protocol.Protocol, utility.EventDispatcher):
     
    1616    I am a protocol with an event dispatcher without further processing.
    1717
    18     This protocol is only used for testing XmlStreamFactoryMixin to make
     18    This protocol is only used for testing BootstrapMixin to make
    1919    sure the bootstrap observers are added to the protocol instance.
    2020    """
     
    2828
    2929
    30 class XmlStreamFactoryMixinTest(unittest.TestCase):
    3130
    32     def test_buildProtocol(self):
     31class BootstrapMixinTest(unittest.TestCase):
     32    """
     33    Tests for L{BootstrapMixin}.
     34
     35    @ivar factory: Instance of the factory or mixin under test.
     36    """
     37
     38    def setUp(self):
     39        self.factory = BootstrapMixin()
     40
     41
     42    def test_installBootstraps(self):
    3343        """
    34         Test building of protocol.
    35 
    36         Arguments passed to Factory should be passed to protocol on
    37         instantiation. Bootstrap observers should be setup.
     44        Dispatching an event should fire registered bootstrap observers.
    3845        """
    3946        d = defer.Deferred()
     47        dispatcher = DummyProtocol()
     48        self.factory.addBootstrap('//event/myevent', d.callback)
     49        self.factory.installBootstraps(dispatcher)
     50        dispatcher.dispatch(None, '//event/myevent')
     51        return d
    4052
    41         f = XmlStreamFactoryMixin(None, test=None)
    42         f.protocol = DummyProtocol
    43         f.addBootstrap('//event/myevent', d.callback)
    44         xs = f.buildProtocol(None)
    45 
    46         self.assertEquals(f, xs.factory)
    47         self.assertEquals((None,), xs.args)
    48         self.assertEquals({'test': None}, xs.kwargs)
    49         xs.dispatch(None, '//event/myevent')
    50         return d
    5153
    5254    def test_addAndRemoveBootstrap(self):
     
    5759            pass
    5860
    59         f = XmlStreamFactoryMixin(None, test=None)
     61        self.factory.addBootstrap('//event/myevent', cb)
     62        self.assertIn(('//event/myevent', cb), self.factory.bootstraps)
    6063
    61         f.addBootstrap('//event/myevent', cb)
    62         self.assertIn(('//event/myevent', cb), f.bootstraps)
     64        self.factory.removeBootstrap('//event/myevent', cb)
     65        self.assertNotIn(('//event/myevent', cb), self.factory.bootstraps)
    6366
    64         f.removeBootstrap('//event/myevent', cb)
    65         self.assertNotIn(('//event/myevent', cb), f.bootstraps)
     67
    6668
    6769class ToResponseTest(unittest.TestCase):
Note: See TracChangeset for help on using the changeset viewer.