| 133 | | |
|---|
| 134 | | |
|---|
| 135 | | class PerspectiveFactory(object): |
|---|
| 136 | | """ |
|---|
| 137 | | I generate perspectives for clients with varying access |
|---|
| 138 | | privileges. Construct me with an I{interfaceMap} dict and a |
|---|
| 139 | | I{perspectiveList} sequence. |
|---|
| 140 | | |
|---|
| 141 | | Each entry of the interface map is keyed by the name of an access privilege |
|---|
| 142 | | and has as its value a sequence of one or more interfaces that must be |
|---|
| 143 | | provided by the perspective object in order to grant the client such |
|---|
| 144 | | access. |
|---|
| 145 | | |
|---|
| 146 | | The perspective list contains all of the perspective classes that implement |
|---|
| 147 | | the interfaces in the interface map. Each perspective that I generate will |
|---|
| 148 | | be an instance of a composite of those classes that implement a required |
|---|
| 149 | | interfaces. |
|---|
| 150 | | """ |
|---|
| 151 | | def __init__(self, interfaceMap, perspectiveList): |
|---|
| 152 | | self.interfaceMap = interfaceMap |
|---|
| 153 | | self.perspectiveList = perspectiveList |
|---|
| 154 | | self.implementorMap = {} |
|---|
| 155 | | |
|---|
| 156 | | def implementor(self, interface): |
|---|
| 157 | | """ |
|---|
| 158 | | Returns the first perspective class in my C{perspectiveList} sequence |
|---|
| 159 | | that implements the supplied I{interface}, raising an exception if none |
|---|
| 160 | | do so. |
|---|
| 161 | | """ |
|---|
| 162 | | result = self.implementorMap.get(interface, None) |
|---|
| 163 | | if result is None: |
|---|
| 164 | | for candidate in self.perspectiveList: |
|---|
| 165 | | if interface.implementedBy(candidate): |
|---|
| 166 | | result = self.implementorMap[interface] = candidate |
|---|
| 167 | | break |
|---|
| 168 | | else: |
|---|
| 169 | | raise NotImplementedError( |
|---|
| 170 | | "No perspective class implements '%s'" % repr(interface)) |
|---|
| 171 | | return result |
|---|
| 172 | | |
|---|
| 173 | | def perspective(self, privileges, **kw): |
|---|
| 174 | | """ |
|---|
| 175 | | Returns to the client a perspective instance that provides interfaces |
|---|
| 176 | | in accordance with the supplied list of I{privileges}. Any keywords |
|---|
| 177 | | supplied define the names and values of attributes that the instance is |
|---|
| 178 | | assigned. |
|---|
| 179 | | |
|---|
| 180 | | The interfaces provided by the perspective are mapped out in my |
|---|
| 181 | | I{interfaceMap} dict. |
|---|
| 182 | | """ |
|---|
| 183 | | baseClasses = [pb.Avatar] |
|---|
| 184 | | for thisPrivilege in privileges: |
|---|
| 185 | | requiredInterfaces = self.interfaceMap.get(thisPrivilege, []) |
|---|
| 186 | | for thisInterface in requiredInterfaces: |
|---|
| 187 | | implementor = self.implementor(thisInterface) |
|---|
| 188 | | if implementor is not None and implementor not in baseClasses: |
|---|
| 189 | | baseClasses.append(implementor) |
|---|
| 190 | | # Create and instantiate the user's custom perspective class |
|---|
| 191 | | Perspective = new.classobj('Perspective', tuple(baseClasses), {}) |
|---|
| 192 | | thisPerspective = Perspective() |
|---|
| 193 | | # Set the perspective's instance attributes |
|---|
| 194 | | for name, value in kw.iteritems(): |
|---|
| 195 | | setattr(thisPerspective, name, value) |
|---|
| 196 | | # The perspective is ready to give to the client |
|---|
| 197 | | return thisPerspective |
|---|