source: wokkel/compat.py @ 96:8e6130587088

Last change on this file since 96:8e6130587088 was 96:8e6130587088, checked in by Ralph Meijer <ralphm@…>, 10 years ago

Remove copyright dates from individual source files, only update LICENSE.

  • Property exe set to *
File size: 3.6 KB
Line 
1# -*- test-case-name: wokkel.test.test_compat -*-
2#
3# Copyright (c) Twisted Matrix Laboratories.
4# See LICENSE for details.
5
6from twisted.internet import protocol
7from twisted.words.protocols.jabber import xmlstream
8
9class BootstrapMixin(object):
10    """
11    XmlStream factory mixin to install bootstrap event observers.
12
13    This mixin is for factories providing
14    L{IProtocolFactory<twisted.internet.interfaces.IProtocolFactory>} to make
15    sure bootstrap event observers are set up on protocols, before incoming
16    data is processed. Such protocols typically derive from
17    L{utility.EventDispatcher}, like L{XmlStream}.
18
19    You can set up bootstrap event observers using C{addBootstrap}. The
20    C{event} and C{fn} parameters correspond with the C{event} and
21    C{observerfn} arguments to L{utility.EventDispatcher.addObserver}.
22
23    @since: 8.2.
24    @ivar bootstraps: The list of registered bootstrap event observers.
25    @type bootstrap: C{list}
26    """
27
28    def __init__(self):
29        self.bootstraps = []
30
31
32    def installBootstraps(self, dispatcher):
33        """
34        Install registered bootstrap observers.
35
36        @param dispatcher: Event dispatcher to add the observers to.
37        @type dispatcher: L{utility.EventDispatcher}
38        """
39        for event, fn in self.bootstraps:
40            dispatcher.addObserver(event, fn)
41
42
43    def addBootstrap(self, event, fn):
44        """
45        Add a bootstrap event handler.
46
47        @param event: The event to register an observer for.
48        @type event: C{str} or L{xpath.XPathQuery}
49        @param fn: The observer callable to be registered.
50        """
51        self.bootstraps.append((event, fn))
52
53
54    def removeBootstrap(self, event, fn):
55        """
56        Remove a bootstrap event handler.
57
58        @param event: The event the observer is registered for.
59        @type event: C{str} or L{xpath.XPathQuery}
60        @param fn: The registered observer callable.
61        """
62        self.bootstraps.remove((event, fn))
63
64
65
66class XmlStreamServerFactory(BootstrapMixin,
67                             protocol.ServerFactory):
68    """
69    Factory for Jabber XmlStream objects as a server.
70
71    @since: 8.2.
72    @ivar authenticatorFactory: Factory callable that takes no arguments, to
73                                create a fresh authenticator to be associated
74                                with the XmlStream.
75    """
76
77    protocol = xmlstream.XmlStream
78
79    def __init__(self, authenticatorFactory):
80        BootstrapMixin.__init__(self)
81        self.authenticatorFactory = authenticatorFactory
82
83
84    def buildProtocol(self, addr):
85        """
86        Create an instance of XmlStream.
87
88        A new authenticator instance will be created and passed to the new
89        XmlStream. Registered bootstrap event observers are installed as well.
90        """
91        authenticator = self.authenticatorFactory()
92        xs = self.protocol(authenticator)
93        xs.factory = self
94        self.installBootstraps(xs)
95        return xs
96
97
98
99class IQ(xmlstream.IQ):
100    def __init__(self, *args, **kwargs):
101        # Make sure we have a reactor parameter
102        try:
103            reactor = kwargs['reactor']
104        except KeyError:
105            from twisted.internet import reactor
106        kwargs['reactor'] = reactor
107
108        # Check if IQ's init accepts the reactor parameter
109        try:
110            xmlstream.IQ.__init__(self, *args, **kwargs)
111        except TypeError:
112            # Guess not. Remove the reactor parameter and try again.
113            del kwargs['reactor']
114            xmlstream.IQ.__init__(self, *args, **kwargs)
115
116            # Patch the XmlStream instance so that it has a _callLater
117            self._xmlstream._callLater = reactor.callLater
Note: See TracBrowser for help on using the repository browser.