source: TI12-security/trunk/python/ndg_security_common/ndg/security/common/utils/classfactory.py @ 5779

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/python/ndg_security_common/ndg/security/common/utils/classfactory.py@5779
Revision 5779, 4.9 KB checked in by pjkersha, 11 years ago (diff)

Integrated automated start-up and shutdown of Paste http servers for unit tests.

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"
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
15class ClassFactoryError(Exception):
16    """Exception handling for NDG classfactory module."""
17    def __init__(self, msg):
18        log.error(msg)
19        Exception.__init__(self, msg)
20
21def importClass(moduleName, className=None, objectType=None):
22    '''Import a class from a string module name and class name.
23   
24    @param moduleName: Name of module containing the class
25    @type moduleName: str
26    @param className: Name of the class to import.  If none is given, the
27    class name will be assumed to be the last component of modulePath
28    @type className: str
29    @rtype: class object
30    @return: imported class'''
31   
32    if className is None:
33        _moduleName, className = moduleName.rsplit('.', 1)
34    else:
35        _moduleName = moduleName
36   
37    log.debug("Importing class %s ..." % className) 
38     
39    module = __import__(_moduleName, globals(), locals(), [])
40    components = _moduleName.split('.')
41    try:
42        for component in components[1:]:
43            module = getattr(module, component)
44    except AttributeError, e:
45        raise AttributeError("Error importing class %s: %s" %
46                             (className, traceback.format_exc()))
47
48    importedClass = getattr(module, className)
49
50    # Check class inherits from a base class
51    if objectType and not issubclass(importedClass, objectType):
52        raise TypeError("Specified class %s must be derived from %s; got %s" %
53                        (className, objectType, importedClass))
54   
55    log.info('Imported "%s" class from module, "%s"', className, _moduleName)
56    return importedClass
57   
58
59def instantiateClass(moduleName, className, moduleFilePath=None, 
60                     objectType=None, classArgs=(), classProperties={}):
61    '''
62    Create and return an instance of the specified class
63    @param moduleName: Name of module containing the class
64    @type moduleName: str
65    @param className: Name of the class to instantiate.  May be None in
66    which case, the class name is parsed from the moduleName last element
67    @type className: str
68    @param moduleFilePath: Path to the module - if unset, assume module on
69    system path already
70    @type moduleFilePath: str
71    @param classProperties: dict of properties to use when instantiating the
72    class
73    @type classProperties: dict
74    @param objectType: expected type for the object to instantiate - to
75    enforce use of specific interfaces
76    @type objectType: object
77    @return: object - instance of the class specified
78    '''
79
80   
81    # ensure that classproperties is a dict - NB, it may be passed in as a null
82    # value which can override the default val
83    if not classProperties:
84        classProperties = {}
85
86    # variable to store original state of the system path
87    sysPathBak = None
88    try:
89        try:
90            # Module file path may be None if the new module to be loaded
91            # can be found in the existing system path           
92            if moduleFilePath:
93                if not os.path.exists(moduleFilePath):
94                    raise IOError("Module file path '%s' doesn't exist" % 
95                                  moduleFilePath)
96                         
97                # Temporarily extend system path ready for import
98                sysPathBak = sys.path
99                         
100                sys.path.append(moduleFilePath)
101
102           
103            # Import module name specified in properties file
104            importedClass = importClass(moduleName, 
105                                        className=className,
106                                        objectType=objectType)
107        finally:
108            # revert back to original sys path, if necessary
109            # NB, python requires the use of a try/finally OR a try/except
110            # block - not both combined
111            if sysPathBak:
112                sys.path = sysPathBak
113                           
114    except Exception, e:
115        log.error('%s module import raised %s type exception: %s' % 
116                  (moduleName, e.__class__, e))
117        raise 
118
119    # Instantiate class
120    log.debug('Instantiating class "%s"' % importedClass.__name__)
121    try:
122        if classArgs:
123            object = importedClass(*classArgs, **classProperties)
124        else:
125            object = importedClass(**classProperties)
126           
127        return object
128
129    except Exception, e:
130        log.error("Instantiating class, %s: %s" % (importedClass.__name__, e))
131        raise
132           
133                 
Note: See TracBrowser for help on using the repository browser.