Gaudi Framework, version v23r4

Home   Generated: Mon Sep 17 2012

ConfigurableDb.py

Go to the documentation of this file.
00001 # File: AthenaCommon/python/ConfigurableDb.py
00002 # Author: Sebastien Binet (binet@cern.ch)
00003 
00004 """A singleton holding informations on the whereabouts of all the automatically
00005 generated Configurables.
00006 This repository of (informations on) Configurables is used by the PropertyProxy
00007 class to locate Configurables and feed the JobOptionsSvc. It could also be used
00008 to feed the AthenaEmacs module..."""
00009 
00010 __all__ = [ 'CfgDb', 'cfgDb', 'loadConfigurableDb', 'getConfigurable' ]
00011 
00012 import string
00013 _transtable = string.maketrans('<>&*,: ().', '__rp__s___')
00014 
00015 import logging
00016 log = logging.getLogger( 'ConfigurableDb' )
00017 
00018 class _CfgDb( dict ):
00019     """
00020     A singleton class holding informations about automatically generated
00021     Configurables.
00022      --> package holding that Configurable
00023      --> library holding the components related to that Configurable
00024      --> python module holding the Configurable
00025      --> a dictionary of duplicates
00026     """
00027 
00028     __slots__ = {
00029         '_duplicates' : { },
00030         }
00031 
00032     def __init__(self):
00033         object.__init__(self)
00034         self._duplicates = {}
00035         return
00036 
00037     def add( self, configurable, package, module, lib ):
00038         """Method to populate the Db.
00039         It is called from the auto-generated Xyz_confDb.py files (genconf.cpp)
00040         @param configurable: the name of the configurable being added
00041         @param package: the name of the package which holds this Configurable
00042         @param module: the name of the python module holding the Configurable
00043         @param lib: the name of the library holding the component(s) (ie: the
00044                     C++ Gaudi component which is mapped by the Configurable)
00045         """
00046         cfg = { 'package' : package,
00047                 'module'  : module,
00048                 'lib'     : lib }
00049         if self.has_key( configurable ):
00050             ## check if it comes from the same library...
00051             if cfg['lib'] != self[configurable]['lib']:
00052                 log.debug( "dup!! [%s] p=%s m=%s lib=%s",
00053                            configurable, package, module, lib )
00054                 if self._duplicates.has_key(configurable):
00055                     self._duplicates[configurable] += [ cfg ]
00056                 else:
00057                     self._duplicates[configurable]  = [ cfg ]
00058                     pass
00059         else:
00060             log.debug( "added [%s] p=%s m=%s lib=%s",
00061                        configurable, package, module, lib )
00062             self[configurable] = cfg
00063             pass
00064         return
00065 
00066     def duplicates(self):
00067         return self._duplicates
00068 
00069     pass # class _CfgDb
00070 
00071 class _Singleton( object ):
00072 
00073     ## the object this singleton is holding
00074     ## No other object will be created...
00075     __obj = _CfgDb()
00076 
00077     def __call__( self ):
00078         return self.__obj
00079 
00080     pass # class _Singleton
00081 
00082 CfgDb = _Singleton()
00083 
00084 # clean-up
00085 del _Singleton
00086 del _CfgDb
00087 
00088 ## default name for CfgDb instance
00089 cfgDb = CfgDb()
00090 
00091 ## Helper function to load all ConfigurableDb files holding informations
00092 def loadConfigurableDb():
00093     """Helper function to load all ConfigurableDb files (modules) holding
00094     informations about Configurables
00095     """
00096     import os
00097     import sys
00098     from zipfile import is_zipfile, ZipFile
00099     from glob import glob
00100     from os.path import join as path_join
00101     log.debug( "importing confDb packages..." )
00102     nFiles = 0 # counter of imported files
00103     for path in sys.path:
00104         log.debug( "walking in [%s]..." % path )
00105         if not os.path.exists(path):
00106             continue
00107         if is_zipfile(path):
00108             # turn filename syntax into module syntax: remove path+extension and replace / with . (dot)
00109             confDbModules = [ os.path.splitext(f)[0].replace('/','.')
00110                               for f in ZipFile(path).namelist()
00111                               if f.endswith("_merged_confDb.py") or f.endswith("_merged_confDb.pyc") ]
00112         else:
00113             # turn filename syntax into module syntax: remove path+extension and replace / with . (dot)
00114             confDbModules = [ os.path.splitext( f[len(path)+1:] )[0].replace(os.sep,'.')
00115                               for f in glob(path_join(path, "*_merged_confDb.py"))
00116                               if os.path.isfile(f) ]
00117         for confDbModule in confDbModules:
00118             nFiles += 1
00119             log.debug( "\t-importing [%s]..." % confDbModule )
00120             try:
00121                 mod = __import__( confDbModule )
00122             except ImportError, err:
00123                 log.warning( "Could not import module [%s] !", confDbModule )
00124                 log.warning( "Reason: %s", err )
00125                 pass
00126             else:
00127                 # don't need to keep the module
00128                 del mod
00129             pass
00130         pass # loop over sys.path
00131     log.debug( "importing confDb packages... [DONE]" )
00132     nPkgs = len( set([k['package'] for k in cfgDb.values()]) )
00133     log.debug( "imported %i confDb packages" % nPkgs )
00134     return nFiles
00135 
00136 
00137 def getConfigurable( className, requester='', assumeCxxClass=True ):
00138     confClass=className
00139     if assumeCxxClass:
00140         # assume className is C++: --> translate to python
00141         confClass = string.translate( confClass, _transtable )
00142     # see if I have it in my dictionary
00143     confClassInfo = cfgDb.get(confClass)
00144     if not confClassInfo:
00145         confClassInfo = cfgDb.get(confClass)
00146     # get the python module
00147     confMod = confClassInfo and confClassInfo.get('module')
00148     if not confMod:
00149         log.warning( "%s: Class %s not in database", requester, className )
00150         return None
00151     # load the module
00152     try:
00153         mod = __import__(confMod,globals(),locals(),confClass)
00154     except ImportError:
00155         log.warning( "%s: Module %s not found (needed for configurable %s)",
00156                      requester, confMod, className )
00157         return None
00158     # get the class
00159     try:
00160         confClass = getattr(mod,confClass)
00161     except AttributeError:
00162         log.warning( "%s: Configurable %s not found in module %s",
00163                      requester, confClass, confMod )
00164         return None
00165     # Got it!
00166     log.debug( "%s: Found configurable %s in module %s",
00167                requester, confClass, confMod )
00168 
00169     return confClass
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines

Generated at Mon Sep 17 2012 13:49:33 for Gaudi Framework, version v23r4 by Doxygen version 1.7.2 written by Dimitri van Heesch, © 1997-2004