source: TI12-security/trunk/WSSecurity/ndg/wssecurity/common/utils/classfactory.py @ 6396

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/WSSecurity/ndg/wssecurity/common/utils/classfactory.py@6396
Revision 6396, 5.1 KB checked in by pjkersha, 11 years ago (diff)
Line 
1"""
2Generic parsers to use when reading in configuration data
3- methods available to deal with both XML and INI (flat text key/val) formats
4"""
5__author__ = "C Byrom (Tessella), P J Kershaw (STFC)"
6__date__ = "28/08/08"
7__copyright__ = "(C) 2009 Science and Technology Facilities Council"
8__license__ = "BSD - see LICENSE file in top-level directory"
9__contact__ = "Philip.Kershaw@stfc.ac.uk"
10__revision__ = '$Id: $'
11import traceback
12import logging, os, sys
13log = logging.getLogger(__name__)
14
15
16class ClassFactoryError(Exception):
17    """Exception handling for NDG classfactory module."""
18    def __init__(self, msg):
19        log.error(msg)
20        Exception.__init__(self, msg)
21
22
23def importClass(moduleName, className=None, objectType=None):
24    '''Import a class from a string module name and class name.
25   
26    @param moduleName: Name of module containing the class
27    @type moduleName: str
28    @param className: Name of the class to import.  If none is given, the
29    class name will be assumed to be the last component of modulePath
30    @type className: str
31    @rtype: class object
32    @return: imported class'''
33   
34    if className is None:
35        _moduleName, className = moduleName.rsplit('.', 1)
36    else:
37        _moduleName = moduleName
38   
39    log.debug("Importing class %s ..." % className) 
40     
41    module = __import__(_moduleName, globals(), locals(), [])
42    components = _moduleName.split('.')
43    try:
44        for component in components[1:]:
45            module = getattr(module, component)
46    except AttributeError:
47        raise AttributeError("Error importing class %s: %s" %
48                             (className, traceback.format_exc()))
49
50    importedClass = getattr(module, className)
51
52    # Check class inherits from a base class
53    if objectType and not issubclass(importedClass, objectType):
54        raise TypeError("Specified class %s must be derived from %s; got %s" %
55                        (className, objectType, importedClass))
56   
57    log.info('Imported "%s" class from module, "%s"', className, _moduleName)
58    return importedClass
59   
60
61def instantiateClass(moduleName, className=None, moduleFilePath=None, 
62                     objectType=None, classArgs=(), classProperties={}):
63    '''
64    Create and return an instance of the specified class
65    @param moduleName: Name of module containing the class
66    @type moduleName: str
67    @param className: Name of the class to instantiate.  May be None in
68    which case, the class name is parsed from the moduleName last element
69    @type className: str
70    @param moduleFilePath: Path to the module - if unset, assume module on
71    system path already
72    @type moduleFilePath: str
73    @param classProperties: dict of properties to use when instantiating the
74    class
75    @type classProperties: dict
76    @param objectType: expected type for the object to instantiate - to
77    enforce use of specific interfaces
78    @type objectType: object
79    @return: object - instance of the class specified
80    '''
81
82   
83    # ensure that classproperties is a dict - NB, it may be passed in as a null
84    # value which can override the default val
85    if not isinstance(classProperties, dict):
86        raise TypeError("Expecting dict type for 'classProperties' attribute; "
87                        "got %r" % type(classProperties))
88
89    # variable to store original state of the system path
90    sysPathBak = None
91    try:
92        try:
93            # Module file path may be None if the new module to be loaded
94            # can be found in the existing system path           
95            if moduleFilePath:
96                if not os.path.exists(moduleFilePath):
97                    raise IOError("Module file path '%s' doesn't exist" % 
98                                  moduleFilePath)
99                         
100                # Temporarily extend system path ready for import
101                sysPathBak = sys.path
102                         
103                sys.path.append(moduleFilePath)
104
105           
106            # Import module name specified in properties file
107            importedClass = importClass(moduleName, 
108                                        className=className,
109                                        objectType=objectType)
110        finally:
111            # revert back to original sys path, if necessary
112            # NB, python requires the use of a try/finally OR a try/except
113            # block - not both combined
114            if sysPathBak:
115                sys.path = sysPathBak
116                           
117    except Exception, e:
118        log.error('%s module import raised %s type exception: %s' % 
119                  (moduleName, e.__class__, e))
120        raise 
121
122    # Instantiate class
123    log.debug('Instantiating class "%s"' % importedClass.__name__)
124    try:
125        if classArgs:
126            object = importedClass(*classArgs, **classProperties)
127        else:
128            object = importedClass(**classProperties)
129           
130        return object
131
132    except Exception, e:
133        log.error("Instantiating class, %s: %s" % (importedClass.__name__, 
134                                                   traceback.format_exc()))
135        raise
Note: See TracBrowser for help on using the repository browser.