source: TI12-security/trunk/NDG_XACML/ndg/xacml/utils/factory.py @ 7072

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/NDG_XACML/ndg/xacml/utils/factory.py@7072
Revision 7072, 4.9 KB checked in by pjkersha, 9 years ago (diff)

Incomplete - task 2: XACML-Security Integration

  • Major cleanup of function factories for efficiency. Only the required factories and function classes are loaded and any loaded classes are cached for future calls. All unit tests pass.
  • 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            _moduleName, objectName = moduleName.rsplit('.', 1)
37            objectName = [objectName]
38    else:
39        _moduleName = moduleName
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, e:
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
65def callModuleObject(moduleName, objectName=None, moduleFilePath=None, 
66                     objectType=None, objectArgs=(), objectProperties={}):
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   
87    # ensure that properties is a dict - NB, it may be passed in as a null
88    # value which can override the default val
89    if not objectProperties:
90        objectProperties = {}
91
92    # variable to store original state of the system path
93    sysPathBak = None
94    try:
95        try:
96            # Module file path may be None if the new module to be loaded
97            # can be found in the existing system path           
98            if moduleFilePath:
99                if not os.path.exists(moduleFilePath):
100                    raise IOError("Module file path '%s' doesn't exist" % 
101                                  moduleFilePath)
102                         
103                # Temporarily extend system path ready for import
104                sysPathBak = sys.path
105                         
106                sys.path.append(moduleFilePath)
107
108           
109            # Import module name specified in properties file
110            importedObject = importModuleObject(moduleName, 
111                                                objectName=objectName,
112                                                objectType=objectType)
113        finally:
114            # revert back to original sys path, if necessary
115            # NB, python requires the use of a try/finally OR a try/except
116            # block - not both combined
117            if sysPathBak:
118                sys.path = sysPathBak
119                           
120    except Exception, e:
121        log.debug('%r module import raised %r type exception: %s', 
122                  moduleName, e.__class__, traceback.format_exc())
123        raise 
124
125    # Instantiate class
126    if objectArgs:
127        object = importedObject(*objectArgs, **objectProperties)
128    else:
129        object = importedObject(**objectProperties)
130       
131    return object
Note: See TracBrowser for help on using the repository browser.