Package ndg :: Package xacml :: Package utils :: Module factory
[hide private]

Source Code for Module ndg.xacml.utils.factory

  1  """ 
  2  Class Factory 
  3   
  4  NERC DataGrid project 
  5  """ 
  6  __author__ = "Philip Kershaw" 
  7  __date__ = "15/02/10" 
  8  __copyright__ = "(C) 2010 Science and Technology Facilities Council" 
  9  __license__ = "BSD - see LICENSE file in top-level directory" 
 10  __contact__ = "Philip.Kershaw@stfc.ac.uk" 
 11  __revision__ = '$Id: factory.py 7696 2010-11-03 08:57:41Z pjkersha $' 
 12  import traceback 
 13  import logging, os, sys 
 14  log = logging.getLogger(__name__) 
 15   
 16   
17 -def importModuleObject(moduleName, objectName=None, objectType=None):
18 '''Import from a string module name and object name. Object can be 19 any entity contained in a module 20 21 @param moduleName: Name of module containing the class 22 @type moduleName: str 23 @param objectName: Name of the class to import. If none is given, the 24 class name will be assumed to be the last component of modulePath 25 @type objectName: str 26 @rtype: class object 27 @return: imported class''' 28 if objectName is None: 29 if ':' in moduleName: 30 # Support Paste style import syntax with rhs of colon denoting 31 # module content to import 32 _moduleName, objectName = moduleName.rsplit(':', 1) 33 if '.' in objectName: 34 objectName = objectName.split('.') 35 else: 36 _moduleName, objectName = moduleName.rsplit('.', 1) 37 else: 38 _moduleName = moduleName 39 40 if isinstance(objectName, basestring): 41 objectName = [objectName] 42 43 module = __import__(_moduleName, globals(), locals(), []) 44 components = _moduleName.split('.') 45 try: 46 for component in components[1:]: 47 module = getattr(module, component) 48 except AttributeError: 49 raise AttributeError("Error importing %r: %s" % 50 (objectName[0], traceback.format_exc())) 51 52 importedObject = module 53 for i in objectName: 54 importedObject = getattr(importedObject, i) 55 56 # Check class inherits from a base class 57 if objectType and not issubclass(importedObject, objectType): 58 raise TypeError("Specified class %r must be derived from %r; got %r" % 59 (objectName, objectType, importedObject)) 60 61 log.info('Imported %r from module %r', objectName[0], _moduleName) 62 return importedObject
63 64
65 -def callModuleObject(moduleName, objectName=None, moduleFilePath=None, 66 objectType=None, objectArgs=None, objectProperties=None):
67 ''' 68 Create and return an instance of the specified class or invoke callable 69 @param moduleName: Name of module containing the class 70 @type moduleName: str 71 @param objectName: Name of the class to instantiate. May be None in 72 which case, the class name is parsed from the moduleName last element 73 @type objectName: str 74 @param moduleFilePath: Path to the module - if unset, assume module on 75 system path already 76 @type moduleFilePath: str 77 @param objectProperties: dict of properties to use when instantiating the 78 class 79 @type objectProperties: dict 80 @param objectType: expected type for the object to instantiate - to 81 enforce use of specific interfaces 82 @type objectType: object 83 @return: object - instance of the class specified 84 ''' 85 86 # ensure that properties is a dict - NB, it may be passed in as a null 87 # value which can override the default val 88 if not objectProperties: 89 objectProperties = {} 90 91 if not objectArgs: 92 objectArgs = () 93 94 # variable to store original state of the system path 95 sysPathBak = None 96 try: 97 try: 98 # Module file path may be None if the new module to be loaded 99 # can be found in the existing system path 100 if moduleFilePath: 101 if not os.path.exists(moduleFilePath): 102 raise IOError("Module file path '%s' doesn't exist" % 103 moduleFilePath) 104 105 # Temporarily extend system path ready for import 106 sysPathBak = sys.path 107 108 sys.path.append(moduleFilePath) 109 110 111 # Import module name specified in properties file 112 importedObject = importModuleObject(moduleName, 113 objectName=objectName, 114 objectType=objectType) 115 finally: 116 # revert back to original sys path, if necessary 117 # NB, python requires the use of a try/finally OR a try/except 118 # block - not both combined 119 if sysPathBak: 120 sys.path = sysPathBak 121 122 except Exception, e: 123 log.debug('%r module import raised %r type exception: %s', 124 moduleName, e.__class__, traceback.format_exc()) 125 raise 126 127 # Instantiate class 128 if objectArgs: 129 object = importedObject(*objectArgs, **objectProperties) 130 else: 131 object = importedObject(**objectProperties) 132 133 return object
134