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

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

Added capability to customise unauthorized responses for the authorisation middleware. pepResultHandler config parameter to ndg.security.server.wsgi.authz.AuthorizationMiddleware? enables a custom WSGI middleware class to be added.

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