Package puremvc :: Package patterns :: Module facade
[hide private]
[frames] | no frames]

Source Code for Module puremvc.patterns.facade

  1  """ 
  2   PureMVC Python Port by Toby de Havilland <toby.de.havilland@puremvc.org> 
  3   PureMVC Python Port by Daniele Esposti <expo@expobrain.net> 
  4   PureMVC - Copyright(c) 2006-08 Futurescale, Inc., Some rights reserved. 
  5   Your reuse is governed by the Creative Commons Attribution 3.0 License 
  6  """ 
  7   
  8  from puremvc import MultitonError 
  9  import puremvc.interfaces 
 10  import puremvc.patterns.observer 
11 12 13 -class Facade(puremvc.interfaces.IFacade):
14 """ 15 A base Multiton C{IFacade} implementation. 16 17 In PureMVC, the C{Facade} class assumes these 18 responsibilities: 19 20 Initializing the C{Model}, C{View} and C{Controller} Singletons. 21 22 Providing all the methods defined by the C{IModel, IView, & IController} interfaces. 23 24 Providing the ability to override the specific C{Model}, C{View} and C{Controller} Singletons created. 25 26 Providing a single point of contact to the application for registering C{Commands} and notifying C{Observers} 27 28 29 @see: L{Model<puremvc.core.Model>} 30 @see: L{View<puremvc.core.View>} 31 @see: L{Controller<puremvc.core.Controller>} 32 @see: L{Notification<puremvc.patterns.observer.Notification>} 33 @see: L{Mediator<puremvc.patterns.mediator.Mediator>} 34 @see: L{Proxy<puremvc.patterns.proxy.Proxy>} 35 @see: L{SimpleCommand<puremvc.patterns.command.SimpleCommand>} 36 @see: L{MacroCommand<puremvc.patterns.command.MacroCommand>} 37 """ 38 39 """The Multiton Facade instanceMap.""" 40 instanceMap = {} 41 42 """Message Constants""" 43 MULTITON_MSG = "Facade instance for this Multiton key already constructed!" 44
45 - def __init__(self, key):
46 """ 47 Constructor. 48 49 This C{IFacade} implementation is a Multiton, so you should not call 50 the constructor directly, but instead call the static Factory method, 51 passing the unique key for this instance 52 C{Facade.getInstance( multitonKey )} 53 54 @raise MultitonError: if instance for this Multiton key has already 55 been constructed 56 """ 57 # References to Model, View and Controller 58 self.controller = None 59 self.model = None 60 self.view = None 61 62 # The Multiton Key for this app 63 self.multitonKey = key 64 65 if self.instanceMap.get(key): 66 raise MultitonError(self.MULTITON_MSG) 67 68 self.initializeNotifier(key) 69 self.instanceMap[key] = self 70 71 self.initializeFacade()
72
73 - def initializeFacade(self):
74 """ 75 Initialize the Multiton C{Facade} instance. 76 77 Called automatically by the constructor. Override in your subclass to 78 do any subclass specific initializations. Be sure to call 79 C{super.initializeFacade()}, though. 80 """ 81 self.initializeController() 82 self.initializeModel() 83 self.initializeView()
84 85 @classmethod
86 - def getInstance(cls, key):
87 """ 88 Facade Multiton Factory method 89 90 @return: the Multiton instance of the Facade 91 """ 92 if cls.instanceMap.get(key) is None: 93 cls.instanceMap[key] = cls(key) 94 95 return cls.instanceMap[key]
96
97 - def initializeController(self):
98 """ 99 Initialize the C{Controller}. 100 101 Called by the C{initializeFacade} method. 102 Override this method in your subclass of C{Facade} 103 if one or both of the following are true: 104 105 You wish to initialize a different C{IController}. 106 You have C{Commands} to register with the C{Controller} at startup. 107 108 If you don't want to initialize a different C{IController}, 109 call C{super.initializeController()} at the beginning of your method, then register C{Proxy}s. 110 111 Note: This method is <i>rarely<i> overridden; in practice you are more 112 likely to use a C{Command} to create and register C{Proxy}s 113 with the C{Model}, since C{Proxy}s with mutable data will likely 114 need to send C{INotification}s and thus will likely want to fetch a reference to 115 the C{Facade} during their construction. 116 """ 117 if self.controller is None: 118 from puremvc.core import Controller 119 120 self.controller = Controller.getInstance(self.multitonKey)
121
122 - def initializeModel(self):
123 """ 124 Initialize the C{Model}. 125 126 Called by the C{initializeFacade} method. 127 Override this method in your subclass of C{Facade} 128 if one or both of the following are true: 129 130 You wish to initialize a different C{IModel}. 131 132 You have C{Proxy}s to register with the Model that do not 133 retrieve a reference to the Facade at construction time. 134 135 If you don't want to initialize a different C{IModel}, 136 call C{super.initializeModel()} at the beginning of your 137 method, then register C{Proxy}s. 138 139 Note: This method is <i>rarely</i> overridden; in practice you are more 140 likely to use a C{Command} to create and register C{Proxy}s with the 141 C{Model}, since C{Proxy}s with mutable data will likely need to send 142 C{INotification}s and thus will likely want to fetch a reference to 143 the C{Facade} during their construction. 144 """ 145 if self.model is None: 146 from puremvc.core import Model 147 148 self.model = Model.getInstance(self.multitonKey)
149
150 - def initializeView(self):
151 """ 152 Initialize the C{View}. 153 154 Called by the C{initializeFacade} method. 155 Override this method in your subclass of C{Facade} 156 if one or both of the following are true: 157 158 You wish to initialize a different C{IView}. 159 160 You have C{Observers} to register with the C{View} 161 162 If you don't want to initialize a different C{IView}, 163 call C{super.initializeView()} at the beginning of your 164 method, then register C{IMediator} instances. 165 166 Note: This method is <i>rarely</i> overridden; in practice you are more 167 likely to use a C{Command} to create and register C{Mediator}s with the 168 C{View}, since C{IMediator} instances will need to send 169 C{INotification}s and thus will likely want to fetch a reference 170 to the C{Facade} during their construction. 171 """ 172 if self.view is None: 173 from puremvc.core import View 174 175 self.view = View.getInstance(self.multitonKey)
176
177 - def registerCommand(self, notificationName, commandClassRef):
178 """ 179 Register an C{ICommand} with the C{Controller} by Notification name. 180 181 @param notificationName: the name of the C{INotification} to associate the C{ICommand} with 182 @param commandClassRef: a reference to the Class of the C{ICommand} 183 """ 184 self.controller.registerCommand(notificationName, commandClassRef)
185
186 - def removeCommand(self, notificationName):
187 """ 188 Remove a previously registered C{ICommand} to C{INotification} mapping from the Controller. 189 190 @param notificationName: the name of the C{INotification} to remove the C{ICommand} mapping for 191 """ 192 self.controller.removeCommand(notificationName)
193
194 - def hasCommand(self, notificationName):
195 """ 196 Check if a Command is registered for a given Notification 197 198 @param notificationName: the name of the C{INotification} 199 @return: whether a Command is currently registered for the given C{notificationName}. 200 """ 201 return self.controller.hasCommand(notificationName)
202
203 - def registerProxy(self, proxy):
204 """ 205 Register an C{IProxy} with the C{Model} by name. 206 207 @param proxy: the C{IProxy} instance to be registered with the C{Model}. 208 """ 209 self.model.registerProxy(proxy)
210
211 - def retrieveProxy(self, proxyName):
212 """ 213 Retrieve an C{IProxy} from the C{Model} by name. 214 215 @param proxyName: the name of the proxy to be retrieved. 216 @return: the C{IProxy} instance previously registered with the given C{proxyName}. 217 """ 218 return self.model.retrieveProxy(proxyName)
219
220 - def removeProxy(self, proxyName):
221 """ 222 Remove an C{IProxy} from the C{Model} by name. 223 224 @param proxyName: the C{IProxy} to remove from the C{Model}. 225 @return: the C{IProxy} that was removed from the C{Model} 226 """ 227 if self.model: 228 return self.model.removeProxy(proxyName)
229
230 - def hasProxy(self, proxyName):
231 """ 232 Check if a Proxy is registered 233 234 @param proxyName: the name of the C{IProxy} 235 @return: whether a Proxy is currently registered with the given C{proxyName}. 236 """ 237 return self.model.hasProxy(proxyName)
238
239 - def registerMediator(self, mediator):
240 """ 241 Register a C{IMediator} with the C{View}. 242 243 @param mediator: a reference to the C{IMediator} 244 """ 245 if (self.view is not None): 246 self.view.registerMediator(mediator)
247
248 - def retrieveMediator(self, mediatorName):
249 """ 250 Retrieve an C{IMediator} from the C{View}. 251 252 @param mediatorName: the name of the C{IMediator} 253 @return: the C{IMediator} previously registered with the given C{mediatorName}. 254 """ 255 return self.view.retrieveMediator(mediatorName)
256
257 - def removeMediator(self, mediatorName):
258 """ 259 Remove an C{IMediator} from the C{View}. 260 261 @param mediatorName: name of the C{IMediator} to be removed. 262 @return: the C{IMediator} that was removed from the C{View} 263 """ 264 if self.view: 265 return self.view.removeMediator(mediatorName)
266
267 - def hasMediator(self, mediatorName):
268 """ 269 Check if a Mediator is registered or not 270 271 @param mediatorName: the name of the C{IMediator} 272 @return: whether a Mediator is registered with the given C{mediatorName}. 273 """ 274 return self.view.hasMediator(mediatorName)
275
276 - def sendNotification(self, notificationName, body=None, noteType=None):
277 """ 278 Create and send an C{INotification}. 279 280 Keeps us from having to construct new notification 281 instances in our implementation code. 282 283 @param notificationName: the name of the notiification to send 284 @param body: the body of the notification (optional) 285 @param noteType: the type of the notification (optional) 286 """ 287 self.notifyObservers(puremvc.patterns.observer.Notification(notificationName, body, noteType))
288
289 - def notifyObservers(self, notification):
290 """ 291 Notify C{Observer}s. 292 293 This method is left public mostly for backward 294 compatibility, and to allow you to send custom 295 notification classes using the facade. 296 297 Usually you should just call sendNotification 298 and pass the parameters, never having to 299 construct the notification yourself. 300 301 @param notification: the C{INotification} to have the C{View} notify C{Observers} of. 302 """ 303 if (self.view is not None): 304 self.view.notifyObservers(notification)
305
306 - def initializeNotifier(self, key):
307 """ 308 Set the Multiton key for this facade instance. 309 310 Not called directly, but instead from the constructor when getInstance 311 is invoked. It is necessary to be public in order to implement 312 INotifier. 313 """ 314 self.multitonKey = key
315 316 @classmethod
317 - def hasCore(cls, key):
318 """ 319 Check if a Core is registered or not 320 321 @param key: the multiton key for the Core in question 322 @return: whether a Core is registered with the given C{key}. 323 """ 324 return cls.instanceMap.get(key) is not None
325 326 @classmethod
327 - def removeCore(cls, key):
328 """ 329 Remove a Core. 330 331 Remove the Model, View, Controller and Facade instances for the given 332 key. 333 334 @param key: of the Core to remove 335 """ 336 if cls.instanceMap.get(key): 337 from puremvc.core import Controller, Model, View 338 339 Model.removeModel(key) 340 View.removeView(key) 341 Controller.removeController(key) 342 343 cls.instanceMap.pop(key)
344