source: TI12-security/trunk/NDGSecurity/python/ndg_security_common/ndg/security/common/utils/factory.py @ 7698

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg-security/TI12-security/trunk/NDGSecurity/python/ndg_security_common/ndg/security/common/utils/factory.py@7698
Revision 7698, 5.5 KB checked in by pjkersha, 10 years ago (diff)

Integrated SAML ESGF Group/Role? attribute value type into SAML Attribute Authority client unit tests.

  • Property svn:keywords set to Id
Line 
1"""
2Class Factory
3
4NERC 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$'
12import traceback
13import logging, os, sys
14log = logging.getLogger(__name__)
15
16
17def 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            try:
37                _moduleName, objectName = moduleName.rsplit('.', 1)
38            except ValueError:
39                raise ValueError('Invalid module name %r set for import: %s' %
40                                 (moduleName, traceback.format_exc()))       
41    else:
42        _moduleName = moduleName
43       
44    if isinstance(objectName, basestring):
45        objectName = [objectName]
46   
47    log.debug("Importing %r ..." % objectName) 
48     
49    module = __import__(_moduleName, globals(), locals(), [])
50    components = _moduleName.split('.')
51    try:
52        for component in components[1:]:
53            module = getattr(module, component)
54    except AttributeError:
55        raise AttributeError("Error importing %r: %s" %
56                             (objectName, traceback.format_exc()))
57
58    importedObject = module
59    for i in objectName:
60        importedObject = getattr(importedObject, i)
61
62    # Check class inherits from a base class
63    if objectType and not issubclass(importedObject, objectType):
64        raise TypeError("Specified class %r must be derived from %r; got %r" %
65                        (objectName, objectType, importedObject))
66   
67    log.info('Imported %r from module, %r', objectName, _moduleName)
68    return importedObject
69
70
71def callModuleObject(moduleName, objectName=None, moduleFilePath=None, 
72                     objectType=None, objectArgs=None, objectProperties=None):
73    '''
74    Create and return an instance of the specified class or invoke callable
75    @param moduleName: Name of module containing the class
76    @type moduleName: str
77    @param objectName: Name of the class to instantiate.  May be None in
78    which case, the class name is parsed from the moduleName last element
79    @type objectName: str
80    @param moduleFilePath: Path to the module - if unset, assume module on
81    system path already
82    @type moduleFilePath: str
83    @param objectProperties: dict of properties to use when instantiating the
84    class
85    @type objectProperties: dict
86    @param objectType: expected type for the object to instantiate - to
87    enforce use of specific interfaces
88    @type objectType: object
89    @return: object - instance of the class specified
90    '''
91   
92    # ensure that properties is a dict - NB, it may be passed in as a null
93    # value which can override the default val
94    if not objectProperties:
95        objectProperties = {}
96
97    if not objectArgs:
98        objectArgs = ()
99       
100    # variable to store original state of the system path
101    sysPathBak = None
102    try:
103        try:
104            # Module file path may be None if the new module to be loaded
105            # can be found in the existing system path           
106            if moduleFilePath:
107                if not os.path.exists(moduleFilePath):
108                    raise IOError("Module file path '%s' doesn't exist" % 
109                                  moduleFilePath)
110                         
111                # Temporarily extend system path ready for import
112                sysPathBak = sys.path
113                         
114                sys.path.append(moduleFilePath)
115
116           
117            # Import module name specified in properties file
118            importedObject = importModuleObject(moduleName, 
119                                                objectName=objectName,
120                                                objectType=objectType)
121        finally:
122            # revert back to original sys path, if necessary
123            # NB, python requires the use of a try/finally OR a try/except
124            # block - not both combined
125            if sysPathBak:
126                sys.path = sysPathBak
127                           
128    except Exception, e:
129        log.error('%r module import raised %r type exception: %r' % 
130                  (moduleName, e.__class__, traceback.format_exc()))
131        raise 
132
133    # Instantiate class
134    log.debug('Instantiating object "%s"', importedObject.__name__)
135    try:
136        if objectArgs:
137            object = importedObject(*objectArgs, **objectProperties)
138        else:
139            object = importedObject(**objectProperties)
140           
141        return object
142
143    except Exception, e:
144        log.error("Instantiating module object, %r: %r" % 
145                                                    (importedObject.__name__, 
146                                                     traceback.format_exc()))
147        raise
Note: See TracBrowser for help on using the repository browser.