1 """
2 Class Factory for NDG SAML package
3
4 NERC DataGrid project
5 """
6 __author__ = "Philip Kershaw"
7 __date__ = "15/02/10"
8 __copyright__ = "(C) 2010 Science and Technology Facilities Council"
9 __license__ = "http://www.apache.org/licenses/LICENSE-2.0"
10 __contact__ = "Philip.Kershaw@stfc.ac.uk"
11 __revision__ = '$Id:$'
12 import traceback
13 import logging, os, sys
14 log = logging.getLogger(__name__)
15
16
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
31
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
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
71 -def 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
93
94 if not objectProperties:
95 objectProperties = {}
96
97 if not objectArgs:
98 objectArgs = ()
99
100
101 sysPathBak = None
102 try:
103 try:
104
105
106 if moduleFilePath:
107 if not os.path.exists(moduleFilePath):
108 raise IOError("Module file path '%s' doesn't exist" %
109 moduleFilePath)
110
111
112 sysPathBak = sys.path
113
114 sys.path.append(moduleFilePath)
115
116
117
118 importedObject = importModuleObject(moduleName,
119 objectName=objectName,
120 objectType=objectType)
121 finally:
122
123
124
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
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
148