~cbehrens/nova/lp844160-build-works-with-zones

« back to all changes in this revision

Viewing changes to vendor/Twisted-10.0.0/twisted/python/roots.py

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- test-case-name: twisted.test.test_roots -*-
 
2
# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
 
3
# See LICENSE for details.
 
4
 
 
5
"""
 
6
Twisted Python Roots: an abstract hierarchy representation for Twisted.
 
7
 
 
8
Maintainer: Glyph Lefkowitz
 
9
"""
 
10
 
 
11
# System imports
 
12
import types
 
13
from twisted.python import reflect
 
14
 
 
15
class NotSupportedError(NotImplementedError):
 
16
    """
 
17
    An exception meaning that the tree-manipulation operation
 
18
    you're attempting to perform is not supported.
 
19
    """
 
20
 
 
21
 
 
22
class Request:
 
23
    """I am an abstract representation of a request for an entity.
 
24
 
 
25
    I also function as the response.  The request is responded to by calling
 
26
    self.write(data) until there is no data left and then calling
 
27
    self.finish().
 
28
    """
 
29
    # This attribute should be set to the string name of the protocol being
 
30
    # responded to (e.g. HTTP or FTP)
 
31
    wireProtocol = None
 
32
    def write(self, data):
 
33
        """Add some data to the response to this request.
 
34
        """
 
35
        raise NotImplementedError("%s.write" % reflect.qual(self.__class__))
 
36
 
 
37
    def finish(self):
 
38
        """The response to this request is finished; flush all data to the network stream.
 
39
        """
 
40
        raise NotImplementedError("%s.finish" % reflect.qual(self.__class__))
 
41
 
 
42
 
 
43
class Entity:
 
44
    """I am a terminal object in a hierarchy, with no children.
 
45
 
 
46
    I represent a null interface; certain non-instance objects (strings and
 
47
    integers, notably) are Entities.
 
48
 
 
49
    Methods on this class are suggested to be implemented, but are not
 
50
    required, and will be emulated on a per-protocol basis for types which do
 
51
    not handle them.
 
52
    """
 
53
    def render(self, request):
 
54
        """
 
55
        I produce a stream of bytes for the request, by calling request.write()
 
56
        and request.finish().
 
57
        """
 
58
        raise NotImplementedError("%s.render" % reflect.qual(self.__class__))
 
59
 
 
60
 
 
61
class Collection:
 
62
    """I represent a static collection of entities.
 
63
 
 
64
    I contain methods designed to represent collections that can be dynamically
 
65
    created.
 
66
    """
 
67
 
 
68
    def __init__(self, entities=None):
 
69
        """Initialize me.
 
70
        """
 
71
        if entities is not None:
 
72
            self.entities = entities
 
73
        else:
 
74
            self.entities = {}
 
75
 
 
76
    def getStaticEntity(self, name):
 
77
        """Get an entity that was added to me using putEntity.
 
78
 
 
79
        This method will return 'None' if it fails.
 
80
        """
 
81
        return self.entities.get(name)
 
82
 
 
83
    def getDynamicEntity(self, name, request):
 
84
        """Subclass this to generate an entity on demand.
 
85
 
 
86
        This method should return 'None' if it fails.
 
87
        """
 
88
 
 
89
    def getEntity(self, name, request):
 
90
        """Retrieve an entity from me.
 
91
 
 
92
        I will first attempt to retrieve an entity statically; static entities
 
93
        will obscure dynamic ones.  If that fails, I will retrieve the entity
 
94
        dynamically.
 
95
 
 
96
        If I cannot retrieve an entity, I will return 'None'.
 
97
        """
 
98
        ent = self.getStaticEntity(name)
 
99
        if ent is not None:
 
100
            return ent
 
101
        ent = self.getDynamicEntity(name, request)
 
102
        if ent is not None:
 
103
            return ent
 
104
        return None
 
105
 
 
106
    def putEntity(self, name, entity):
 
107
        """Store a static reference on 'name' for 'entity'.
 
108
 
 
109
        Raises a KeyError if the operation fails.
 
110
        """
 
111
        self.entities[name] = entity
 
112
 
 
113
    def delEntity(self, name):
 
114
        """Remove a static reference for 'name'.
 
115
 
 
116
        Raises a KeyError if the operation fails.
 
117
        """
 
118
        del self.entities[name]
 
119
 
 
120
    def storeEntity(self, name, request):
 
121
        """Store an entity for 'name', based on the content of 'request'.
 
122
        """
 
123
        raise NotSupportedError("%s.storeEntity" % reflect.qual(self.__class__))
 
124
 
 
125
    def removeEntity(self, name, request):
 
126
        """Remove an entity for 'name', based on the content of 'request'.
 
127
        """
 
128
        raise NotSupportedError("%s.removeEntity" % reflect.qual(self.__class__))
 
129
 
 
130
    def listStaticEntities(self):
 
131
        """Retrieve a list of all name, entity pairs that I store references to.
 
132
 
 
133
        See getStaticEntity.
 
134
        """
 
135
        return self.entities.items()
 
136
 
 
137
    def listDynamicEntities(self, request):
 
138
        """A list of all name, entity that I can generate on demand.
 
139
 
 
140
        See getDynamicEntity.
 
141
        """
 
142
        return []
 
143
 
 
144
    def listEntities(self, request):
 
145
        """Retrieve a list of all name, entity pairs I contain.
 
146
 
 
147
        See getEntity.
 
148
        """
 
149
        return self.listStaticEntities() + self.listDynamicEntities(request)
 
150
 
 
151
    def listStaticNames(self):
 
152
        """Retrieve a list of the names of entities that I store references to.
 
153
 
 
154
        See getStaticEntity.
 
155
        """
 
156
        return self.entities.keys()
 
157
 
 
158
 
 
159
    def listDynamicNames(self):
 
160
        """Retrieve a list of the names of entities that I store references to.
 
161
 
 
162
        See getDynamicEntity.
 
163
        """
 
164
        return []
 
165
 
 
166
 
 
167
    def listNames(self, request):
 
168
        """Retrieve a list of all names for entities that I contain.
 
169
 
 
170
        See getEntity.
 
171
        """
 
172
        return self.listStaticNames()
 
173
 
 
174
 
 
175
class ConstraintViolation(Exception):
 
176
    """An exception raised when a constraint is violated.
 
177
    """
 
178
 
 
179
 
 
180
class Constrained(Collection):
 
181
    """A collection that has constraints on its names and/or entities."""
 
182
 
 
183
    def nameConstraint(self, name):
 
184
        """A method that determines whether an entity may be added to me with a given name.
 
185
 
 
186
        If the constraint is satisfied, return 1; if the constraint is not
 
187
        satisfied, either return 0 or raise a descriptive ConstraintViolation.
 
188
        """
 
189
        return 1
 
190
 
 
191
    def entityConstraint(self, entity):
 
192
        """A method that determines whether an entity may be added to me.
 
193
 
 
194
        If the constraint is satisfied, return 1; if the constraint is not
 
195
        satisfied, either return 0 or raise a descriptive ConstraintViolation.
 
196
        """
 
197
        return 1
 
198
 
 
199
    def reallyPutEntity(self, name, entity):
 
200
        Collection.putEntity(self, name, entity)
 
201
 
 
202
    def putEntity(self, name, entity):
 
203
        """Store an entity if it meets both constraints.
 
204
 
 
205
        Otherwise raise a ConstraintViolation.
 
206
        """
 
207
        if self.nameConstraint(name):
 
208
            if self.entityConstraint(entity):
 
209
                self.reallyPutEntity(name, entity)
 
210
            else:
 
211
                raise ConstraintViolation("Entity constraint violated.")
 
212
        else:
 
213
            raise ConstraintViolation("Name constraint violated.")
 
214
 
 
215
 
 
216
class Locked(Constrained):
 
217
    """A collection that can be locked from adding entities."""
 
218
 
 
219
    locked = 0
 
220
 
 
221
    def lock(self):
 
222
        self.locked = 1
 
223
 
 
224
    def entityConstraint(self, entity):
 
225
        return not self.locked
 
226
 
 
227
 
 
228
class Homogenous(Constrained):
 
229
    """A homogenous collection of entities.
 
230
 
 
231
    I will only contain entities that are an instance of the class or type
 
232
    specified by my 'entityType' attribute.
 
233
    """
 
234
 
 
235
    entityType = types.InstanceType
 
236
 
 
237
    def entityConstraint(self, entity):
 
238
        if isinstance(entity, self.entityType):
 
239
            return 1
 
240
        else:
 
241
            raise ConstraintViolation("%s of incorrect type (%s)" %
 
242
                                      (entity, self.entityType))
 
243
 
 
244
    def getNameType(self):
 
245
        return "Name"
 
246
 
 
247
    def getEntityType(self):
 
248
        return self.entityType.__name__