Package omero :: Module clients
[hide private]
[frames] | no frames]

Source Code for Module omero.clients

  1  #!/usr/bin/env python 
  2  """ 
  3   
  4     Copyright 2009 Glencoe Software, Inc. All rights reserved. 
  5     Use is subject to license terms supplied in LICENSE.txt 
  6   
  7  """ 
  8   
  9  __save__ = __name__ 
 10  __name__ = 'omero' 
 11  try: 
 12      import exceptions, traceback, threading, logging 
 13      import Ice, Glacier2, Glacier2_Router_ice 
 14      import uuid 
 15      sys = __import__("sys") 
 16   
 17      api = __import__('omero.api') 
 18      model = __import__('omero.model') 
 19      util = __import__('omero.util') 
 20      sys = __import__('omero.sys') 
 21   
 22      import omero_API_ice 
 23      import omero_Constants_ice 
 24      import omero_sys_ParametersI 
 25      import omero.rtypes 
 26      from omero.rtypes import rlong 
 27      from omero.rtypes import rint 
 28      from omero.rtypes import rstring 
 29      from omero.rtypes import rdouble 
 30      from omero.rtypes import rfloat 
 31   
 32  finally: 
 33      __name__ = __save__ 
 34      del __save__ 
 35   
 36  ClientError = omero.ClientError 
 37   
38 -class BaseClient(object):
39 """ 40 Central client-side blitz entry point, and should be in sync with OmeroJava's omero.client 41 and OmeroCpp's omero::client. 42 43 Typical usage includes:: 44 45 client = omero.client() # Uses --Ice.Config argument or ICE_CONFIG variable 46 client = omero.client(host = host) # Defines "omero.host" 47 client = omero.client(host = host, port = port) # Defines "omero.host" and "omero.port" 48 49 For more information, see: 50 51 - U{https://trac.openmicroscopy.org.uk/omero/wiki/ClientDesign} 52 53 """ 54
55 - def __init__(self, args = None, id = None, \ 56 host = None, port = None, pmap = None):
57 """ 58 Constructor which takes one sys.argv-style list, one initialization 59 data, one host string, one port integer, and one properties map, in 60 that order. *However*, to simplify use, we reassign values based on 61 their type with a warning printed. A cleaner approach is to use named 62 parameters. 63 :: 64 c1 = omero.client(None, None, "host", myPort) # Correct 65 c2 = omero.client(host = "host", port = myPort) # Correct 66 c3 = omero.client("host", myPort) # Works with warning 67 68 Both "Ice" and "omero" prefixed properties will be parsed. 69 70 Defines the state variables:: 71 __previous : InitializationData from any previous communicator, if any 72 Used to re-initialization the client post-closeSession() 73 74 __ic : communicator. Nullness => init() needed on createSession() 75 76 __sf : current session. Nullness => createSession() needed. 77 78 __resources: if non-null, hs access to this client instance and will 79 periodically call sf.keepAlive(None) in order to keep any 80 session alive. This can be enabled either via the omero.keep_alive 81 configuration property, or by calling the enableKeepAlive() method. 82 Once enabled, the period cannot be adjusted during a single 83 session. 84 85 Modifying these variables outside of the accessors can lead to 86 undefined behavior. 87 88 Equivalent to all OmeroJava and OmeroCpp constructors 89 """ 90 91 # Setting all protected values to prevent AttributeError 92 self.__previous = None 93 self.__ic = None 94 self.__oa = None 95 self.__sf = None 96 self.__uuid = None 97 self.__resources = None 98 self.__lock = threading.RLock() 99 100 # Logging 101 self.__logger = logging.getLogger("omero.client") 102 logging.basicConfig() # Does nothing if already configured 103 104 # Reassigning based on argument type 105 106 args, id, host, port, pmap = self._repair(args, id, host, port, pmap) 107 108 # Copying args since we don't really want them edited 109 if not args: 110 args = [] 111 else: 112 args = list(args) 113 114 # Equiv to multiple constructors. ####################### 115 if id == None: 116 id = Ice.InitializationData() 117 118 if id.properties == None: 119 id.properties = Ice.createProperties(args) 120 121 id.properties.parseCommandLineOptions("omero", args); 122 if host: 123 id.properties.setProperty("omero.host", str(host)) 124 if not port: 125 port = id.properties.getPropertyWithDefault("omero.port",\ 126 str(omero.constants.GLACIER2PORT)) 127 id.properties.setProperty("omero.port", str(port)) 128 if pmap: 129 for k,v in pmap.items(): 130 id.properties.setProperty(str(k), str(v)) 131 132 self._initData(id)
133
134 - def _repair(self, args, id, host, port, pmap):
135 """ 136 Takes the 5 arguments passed to the __init__ method 137 and attempts to re-order them based on their types. 138 This allows for simplified usage without parameter 139 names. 140 """ 141 types = [list, Ice.InitializationData, str, int, dict] 142 original = [args, id, host, port, pmap] 143 repaired = [None, None, None, None, None] 144 145 # Check all to see if valid 146 valid = True 147 for i in range(0, len(types)): 148 if None != original[i] and not isinstance(original[i], types[i]): 149 valid = False 150 break 151 if valid: 152 return original 153 154 # Now try to find corrections. 155 for i in range(0, len(types)): 156 found = None 157 for j in range(0, len(types)): 158 if isinstance(original[j], types[i]): 159 if not found: 160 found = original[j] 161 else: 162 raise ClientError("Found two arguments of same type: " + str(types[i])) 163 if found: 164 repaired[i] = found 165 return repaired
166
167 - def _initData(self, id):
168 """ 169 Initializes the current client via an Ice.InitializationData 170 instance. This is called by all of the constructors, but may 171 also be called on createSession(name, pass) if a previous 172 call to closeSession() has nulled the Ice.Communicator. 173 """ 174 175 if not id: 176 raise ClientError("No initialization data provided."); 177 178 # Strictly necessary for this class to work 179 id.properties.setProperty("Ice.ImplicitContext", "Shared") 180 id.properties.setProperty("Ice.ACM.Client", "0") 181 id.properties.setProperty("Ice.RetryIntervals", "-1") 182 183 # Setting MessageSizeMax 184 messageSize = id.properties.getProperty("Ice.MessageSizeMax") 185 if not messageSize or len(messageSize) == 0: 186 id.properties.setProperty("Ice.MessageSizeMax", str(omero.constants.MESSAGESIZEMAX)) 187 188 # Setting ConnectTimeout 189 self.parseAndSetInt(id, "Ice.Override.ConnectTimeout",\ 190 omero.constants.CONNECTTIMEOUT) 191 192 # Endpoints set to tcp if not present 193 endpoints = id.properties.getProperty("omero.ClientCallback.Endpoints") 194 if not endpoints or len(endpoints) == 0: 195 id.properties.setProperty("omero.ClientCallback.Endpoints", "tcp") 196 197 # Port, setting to default if not present 198 port = self.parseAndSetInt(id, "omero.port",\ 199 omero.constants.GLACIER2PORT) 200 201 # Default Router, set a default and then replace 202 router = id.properties.getProperty("Ice.Default.Router") 203 if not router or len(router) == 0: 204 router = str(omero.constants.DEFAULTROUTER) 205 host = id.properties.getPropertyWithDefault("omero.host", """<"omero.host" not set>""") 206 router = router.replace("@omero.port@", str(port)) 207 router = router.replace("@omero.host@", str(host)) 208 id.properties.setProperty("Ice.Default.Router", router) 209 210 # Dump properties 211 dump = id.properties.getProperty("omero.dump") 212 if len(dump) > 0: 213 for prefix in ["omero","Ice"]: 214 for k,v in id.properties.getPropertiesForPrefix(prefix).items(): 215 print "%s=%s" % (k,v) 216 217 self.__lock.acquire() 218 try: 219 if self.__ic: 220 raise ClientError("Client already initialized") 221 222 self.__ic = Ice.initialize(id) 223 224 if not self.__ic: 225 raise ClientError("Improper initialization") 226 227 # Register Object Factory 228 self.of = ObjectFactory() 229 self.of.registerObjectFactory(self.__ic) 230 for of in omero.rtypes.ObjectFactories.values(): 231 of.register(self.__ic) 232 233 # Define our unique identifier (used during close/detach) 234 self.__uuid = str(uuid.uuid4()) 235 ctx = self.__ic.getImplicitContext() 236 if not ctx: 237 raise ClientError("Ice.ImplicitContext not set to Shared") 238 ctx.put(omero.constants.CLIENTUUID, self.__uuid) 239 240 # Register the default client callback 241 self.__oa = self.__ic.createObjectAdapter("omero.ClientCallback") 242 cb = BaseClient.CallbackI(self.__ic, self.__oa) 243 self.__oa.add(cb, self.__ic.stringToIdentity("ClientCallback/%s" % self.__uuid)) 244 self.__oa.activate() 245 finally: 246 self.__lock.release()
247
248 - def __del__(self):
249 """ 250 Calls closeSession() and ignores any exceptions. 251 252 Equivalent to close() in OmeroJava or omero::client::~client() 253 """ 254 try: 255 self.closeSession() 256 except exceptions.Exception, e: 257 self.__logger.warning("Ignoring error in client.__del__:" + str(e.__class__))
258
259 - def getCommunicator(self):
260 """ 261 Returns the Ice.Communicator for this instance or throws 262 an exception if None. 263 """ 264 self.__lock.acquire() 265 try: 266 if not self.__ic: 267 raise ClientError("No Ice.Communicator active; call createSession() or create a new client instance") 268 return self.__ic 269 finally: 270 self.__lock.release()
271
272 - def getAdapter(self):
273 """ 274 Returns the Ice.ObjectAdapter for this instance or throws 275 an exception if None. 276 """ 277 self.__lock.acquire() 278 try: 279 if not self.__oa: 280 raise ClientError("No Ice.ObjectAdapter active; call createSession() or create a new client instance") 281 return self.__oa 282 finally: 283 self.__lock.release()
284
285 - def getSession(self):
286 """ 287 Returns the current active session or throws an exception if none has been 288 created since the last closeSession() 289 """ 290 self.__lock.acquire() 291 try: 292 return self.__sf 293 finally: 294 self.__lock.release()
295
296 - def getImplicitContext(self):
297 """ 298 Returns the Ice.ImplicitContext which defines what properties 299 will be sent on every method invocation. 300 """ 301 return self.getCommunicator().getImplicitContext()
302
303 - def getProperties(self):
304 """ 305 Returns the active properties for this instance 306 """ 307 self.__lock.acquire() 308 try: 309 return self.__ic.getProperties() 310 finally: 311 self.__lock.release()
312
313 - def getProperty(self, key):
314 """ 315 Returns the property for the given key or "" if none present 316 """ 317 return self.getProperties().getProperty(key)
318
319 - def joinSession(self, session):
320 """ 321 Uses the given session uuid as name 322 and password to rejoin a running session 323 """ 324 return self.createSession(session, session)
325
326 - def createSession(self, username=None, password=None):
327 """ 328 Performs the actual logic of logging in, which is done via the 329 getRouter(). Disallows an extant ServiceFactoryPrx, and 330 tries to re-create a null Ice.Communicator. A null or empty 331 username will throw an exception, but an empty password is allowed. 332 """ 333 import omero 334 335 self.__lock.acquire() 336 try: 337 338 # Checking state 339 340 if self.__sf: 341 raise ClientError("Session already active. Create a new omero.client or closeSession()") 342 343 if not self.__ic: 344 if not self.__previous: 345 raise ClientError("No previous data to recreate communicator.") 346 self._initData(self.__previous) 347 self.__previous = None 348 349 # Check the required properties 350 351 if not username: 352 username = self.getProperty("omero.user") 353 elif isinstance(username,omero.RString): 354 username = username.val 355 356 if not username or len(username) == 0: 357 raise ClientError("No username specified") 358 359 if not password: 360 password = self.getProperty("omero.pass") 361 elif isinstance(password,omero.RString): 362 password = password.val 363 364 if not password: 365 raise ClientError("No password specified") 366 367 # Acquire router and get the proxy 368 prx = None 369 retries = 0 370 while retries < 3: 371 reason = None 372 if retries > 0: 373 self.__logger.warning(\ 374 "%s - createSession retry: %s"% (reason, retries) ) 375 try: 376 prx = self.getRouter(self.__ic).createSession(username, password) 377 break 378 except omero.WrappedCreateSessionException, wrapped: 379 if not wrapped.concurrency: 380 raise wrapped # We only retry concurrency issues. 381 reason = "%s:%s" % (wrapped.type, wrapped.reason) 382 retries = retries + 1 383 except Ice.ConnectTimeoutException, cte: 384 reason = "Ice.ConnectTimeoutException:%s" % str(cte) 385 retries = retries + 1 386 387 if not prx: 388 raise ClientError("Obtained null object prox") 389 390 # Check type 391 self.__sf = omero.api.ServiceFactoryPrx.uncheckedCast(prx) 392 if not self.__sf: 393 raise ClientError("Obtained object proxy is not a ServiceFactory") 394 395 # Configure keep alive 396 keep_alive = self.__ic.getProperties().getPropertyWithDefault("omero.keep_alive", "-1") 397 try: 398 i = int(keep_alive) 399 self.enableKeepAlive(i) 400 except: 401 pass 402 403 # Set the client callback on the session 404 # and pass it to icestorm 405 id = self.__ic.stringToIdentity("ClientCallback/%s" % self.__uuid ) 406 raw = self.__oa.createProxy(id) 407 self.__sf.setCallback(omero.api.ClientCallbackPrx.uncheckedCast(raw)) 408 #self.__sf.subscribe("/public/HeartBeat", raw) 409 410 return self.__sf 411 finally: 412 self.__lock.release()
413
414 - def enableKeepAlive(self, seconds):
415 """ 416 Resets the "omero.keep_alive" property on the current 417 Ice.Communicator which is used on initialization to determine 418 the time-period between Resource checks. If no __resources 419 instance is available currently, one is also created. 420 """ 421 422 self.__lock.acquire() 423 try: 424 # A communicator must be configured! 425 ic = self.getCommunicator() 426 # Setting this here guarantees that after closeSession() 427 # the next createSession() will use the new value despite 428 # what was in the configuration file 429 ic.getProperties().setProperty("omero.keep_alive", str(seconds)) 430 431 # If it's not null, then there's already an entry for keeping 432 # any existing session alive 433 if self.__resources == None and seconds > 0: 434 self.__resources = omero.util.Resources(seconds) 435 class Entry: 436 def __init__(self, c): 437 self.c = c
438 def cleanup(self): pass 439 def check(self): 440 sf = self.c._BaseClient__sf 441 ic = self.c._BaseClient__ic 442 if sf != None: 443 try: 444 sf.keepAlive(None) 445 except exceptions.Exception, e: 446 self.c._BaseClient__logger.warning("Proxy keep alive failed.") 447 return False 448 return True
449 self.__resources.add(Entry(self)) 450 finally: 451 self.__lock.release() 452
453 - def getRouter(self, comm):
454 """ 455 Acquires the default router, and throws an exception 456 if it is not of type Glacier2.Router. Also sets the 457 Ice.ImplicitContext on the router proxy. 458 """ 459 prx = comm.getDefaultRouter() 460 if not prx: 461 raise ClientError("No default router found.") 462 router = Glacier2.RouterPrx.uncheckedCast(prx) 463 if not router: 464 raise ClientError("Error obtaining Glacier2 router") 465 466 # For whatever reason, we have to set the context 467 # on the router context here as well 468 router = router.ice_context(comm.getImplicitContext().getContext()) 469 return router
470
471 - def sha1(self, filename):
472 """ 473 Calculates the local sha1 for a file. 474 """ 475 import sha 476 digest = sha.new() 477 file = open(filename, 'rb') 478 try: 479 while True: 480 block = file.read(1024) 481 if not block: 482 break 483 digest.update(block) 484 finally: 485 file.close() 486 return digest.hexdigest()
487
488 - def upload(self, filename, name = None, path = None, 489 type = None, ofile = None, block_size = 1024, 490 permissions = None):
491 """ 492 Utility method to upload a file to the server. 493 """ 494 if not self.__sf: 495 raise ClientError("No session. Use createSession first.") 496 497 import os, types 498 if not filename or not isinstance(filename, types.StringType): 499 raise ClientError("Non-null filename must be provided") 500 501 if not os.path.exists(filename): 502 raise ClientError("File does not exist: " + filename) 503 504 file = open(filename, 'rb') 505 try: 506 507 size = os.path.getsize(file.name) 508 if block_size > size: 509 block_size = size 510 511 if not ofile: 512 ofile = omero.model.OriginalFileI() 513 514 ofile.size = rlong(size) 515 ofile.sha1 = rstring(self.sha1(file.name)) 516 517 if not ofile.name: 518 if name: 519 ofile.name = rstring(name) 520 else: 521 ofile.name = rstring(file.name) 522 523 if not ofile.path: 524 ofile.path = rstring(os.path.abspath(file.name)) 525 526 if not ofile.format: 527 if not type: 528 # ofile.format = FormatI("unknown") 529 # Or determine type from file ending 530 raise ClientError("no format given") 531 else: 532 ofile.format = omero.model.FormatI() 533 ofile.format.value = rstring(type) 534 535 if permissions: 536 ofile.details.permissions = permissions 537 538 up = self.__sf.getUpdateService() 539 ofile = up.saveAndReturnObject(ofile) 540 541 prx = self.__sf.createRawFileStore() 542 prx.setFileId(ofile.id.val) 543 offset = 0 544 while True: 545 block = file.read(block_size) 546 if not block: 547 break 548 prx.write(block, offset, len(block)) 549 offset += len(block) 550 prx.close() 551 finally: 552 file.close() 553 554 return ofile
555
556 - def download(self, ofile, filename, block_size = 1024*1024):
557 file = open(filename, 'wb') 558 try: 559 prx = self.__sf.createRawFileStore() 560 try: 561 if not ofile or not ofile.id: 562 raise ClientError("No file to download") 563 ofile = self.__sf.getQueryService().get("OriginalFile", ofile.id.val) 564 565 if block_size > ofile.size.val: 566 block_size = ofile.size.val 567 568 prx.setFileId(ofile.id.val) 569 offset = 0 570 while offset < ofile.size.val: 571 block = prx.read(offset, block_size) 572 if not block: 573 break 574 file.write(block) 575 offset += len(block) 576 file.flush() 577 finally: 578 prx.close() 579 finally: 580 file.close()
581
582 - def closeSession(self):
583 """ 584 Closes the Router connection created by createSession(). Due to a bug in Ice, 585 only one connection is allowed per communicator, so we also destroy the communicator. 586 """ 587 588 self.__lock.acquire() 589 try: 590 oldSf = self.__sf 591 self.__sf = None 592 593 oldOa = self.__oa 594 self.__oa = None 595 596 oldIc = self.__ic 597 self.__ic = None 598 599 # Only possible if improperly configured. 600 if not oldIc: 601 return 602 603 if oldOa: 604 try: 605 oldOa.deactivate() 606 except exceptions.Exception, e: 607 self.__logger.warning("While deactivating adapter: " + str(e.message)) 608 609 self.__previous = Ice.InitializationData() 610 self.__previous.properties = oldIc.getProperties().clone() 611 612 oldR = self.__resources 613 self.__resources = None 614 if oldR != None: 615 try: 616 oldR.cleanup() 617 except exceptions.Exception, e: 618 self.__logger.warning( 619 "While cleaning up resources: " + str(e)) 620 621 try: 622 try: 623 if oldSf: 624 oldSf = omero.api.ServiceFactoryPrx.uncheckedCast(oldSf.ice_oneway()) 625 oldSf.destroy() 626 except Glacier2.SessionNotExistException: 627 # ok. We don't want it to exist 628 pass 629 except Ice.ConnectionLostException: 630 # ok. Exception will always be thrown 631 pass 632 except Ice.ConnectionRefusedException: 633 # ok. Server probably went down 634 pass 635 except Ice.ConnectTimeoutException: 636 # ok. Server probably went down 637 pass 638 finally: 639 oldIc.destroy() 640 641 finally: 642 self.__lock.release()
643 644
645 - def killSession(self):
646 """ 647 Calls closeSession(omero.model.Session) until 648 the returned reference count is greater than zero. 649 """ 650 651 sf = self.sf 652 if not sf: 653 raise ClientError("No session avaliable") 654 655 s = omero.model.SessionI() 656 s.uuid = rstring(sf.ice_getIdentity().name) 657 try: 658 svc = sf.getSessionService() 659 except: 660 self.__logger.warning("Cannot get session service for killSession. Using closeSession") 661 self.closeSession() 662 return 663 count = 0 664 try: 665 r = 1 666 while r > 0: 667 count += 1 668 r = svc.closeSession(s) 669 except omero.RemovedSessionException: 670 pass 671 except: 672 self.__logger.warning("Unknown exception while closing all references", exc_info = True) 673 674 # Now the server-side session is dead, call closeSession() 675 self.closeSession() 676 return count
677 678 # Environment Methods 679 # =========================================================== 680
681 - def _env(self, method, *args):
682 """ Helper method to access session environment""" 683 session = self.getSession() 684 if not session: 685 raise ClientError("No session active") 686 a = session.getAdminService() 687 u = a.getEventContext().sessionUuid 688 s = session.getSessionService() 689 m = getattr(s, method) 690 return apply(m, (u,)+args)
691
692 - def getInput(self, key):
693 """ 694 Retrieves an item from the "input" shared (session) memory. 695 """ 696 return self._env("getInput", key)
697
698 - def getOutput(self, key):
699 """ 700 Retrieves an item from the "output" shared (session) memory. 701 """ 702 return self._env("getOutput", key)
703 704
705 - def setInput(self, key, value):
706 """ 707 Sets an item in the "input" shared (session) memory under the given name. 708 """ 709 self._env("setInput", key, value)
710
711 - def setOutput(self, key, value):
712 """ 713 Sets an item in the "output" shared (session) memory under the given name. 714 """ 715 self._env("setOutput", key, value)
716
717 - def getInputKeys(self):
718 """ 719 Returns a list of keys for all items in the "input" shared (session) memory 720 """ 721 return self._env("getInputKeys")
722
723 - def getOutputKeys(self):
724 """ 725 Returns a list of keys for all items in the "output" shared (session) memory 726 """ 727 return self._env("getOutputKeys")
728 729 # 730 # Misc. 731 # 732
733 - def parseAndSetInt(self, data, key, newValue):
734 currentValue = data.properties.getProperty(key) 735 if not currentValue or len(currentValue) == 0: 736 newStr = str(newValue) 737 data.properties.setProperty(key, newStr) 738 currentValue = newStr 739 return currentValue
740
741 - def __getattr__(self, name):
742 """ 743 Compatibility layer, which allows calls to getCommunicator() and getSession() 744 to be called via self.ic and self.sf 745 """ 746 if name == "ic": 747 return self.getCommunicator() 748 elif name == "sf": 749 return self.getSession() 750 else: 751 raise AttributeError("Unknown property: " + name)
752 753 # 754 # Callback 755 #
756 - def _getCb(self):
757 if not self.__oa: 758 raise ClientError("No session active; call createSession()") 759 obj = self.__oa.find(self.ic.stringToIdentity("ClientCallback/%s" % self.__uuid)) 760 if not isinstance(obj, BaseClient.CallbackI): 761 raise ClientError("Cannot find CallbackI in ObjectAdapter") 762 return obj
763
764 - def onHeartbeat(self, myCallable):
765 self._getCb().onHeartbeat = myCallable
766
767 - def onSessionClosed(self, myCallable):
768 self._getCb().onSessionClosed = myCallable
769
770 - def onShutdownIn(self, myCallable):
771 self._getCb().onShutdownIn = myCallable
772
773 - class CallbackI(omero.api.ClientCallback):
774 """ 775 Implemention of ClientCallback which will be added to 776 any Session which this instance creates. Note: this client 777 should avoid all interaction with the {@link client#lock} since it 778 can lead to deadlocks during shutdown. See: ticket:1210 779 """ 780 781 # 782 # Default callbacks 783 #
784 - def _noop(self):
785 pass
786 - def _closeSession(self):
787 try: 788 self.oa.deactivate(); 789 except exceptions.Exception, e: 790 sys.err.write("On session closed: " + str(e))
791
792 - def __init__(self, ic, oa):
793 self.ic = ic 794 self.oa = oa 795 self.onHeartbeat = self._noop 796 self.onShutdownIn = self._noop 797 self.onSessionClosed = self._noop
798 - def execute(self, myCallable, action):
799 try: 800 myCallable() 801 self.__logger.debug("ClientCallback %s run", action) 802 except: 803 try: 804 self.__logger.error("Error performing %s" % action) 805 except: 806 print "Error performing %s" % action
807
808 - def requestHeartbeat(self, current = None):
809 self.execute(self.onHeartbeat, "heartbeat")
810 - def shutdownIn(self, milliseconds, current = None):
811 self.execute(self.onShutdownIn, "shutdown")
812 - def sessionClosed(self, current = None):
813 self.execute(self.onSessionClosed, "sessionClosed")
814 815 # 816 # Other 817 # 818 819 import util.FactoryMap
820 -class ObjectFactory(Ice.ObjectFactory):
821 """ 822 Responsible for instantiating objects during deserialization. 823 """ 824
825 - def __init__(self, pmap = util.FactoryMap.map()):
826 self.__m = pmap
827
828 - def registerObjectFactory(self, ic):
829 for key in self.__m: 830 if not ic.findObjectFactory(key): 831 ic.addObjectFactory(self,key)
832
833 - def create(self, type):
834 generator = self.__m[type] 835 if generator == None: 836 raise ClientError("Unknown type:"+type) 837 return generator.next()
838
839 - def destroy(self):
840 # Nothing to do 841 pass
842