27 #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
28 #define REG_SCOPE_LOCK \
29 std::lock_guard<std::recursive_mutex> _guard(m_mutex);
32 std::mutex registrySingletonMutex;
34 #define SINGLETON_LOCK \
35 std::lock_guard<std::mutex> _guard(::registrySingletonMutex);
37 #define REG_SCOPE_LOCK
38 #define SINGLETON_LOCK
45 static inline std::string <rim(std::string &
s) {
47 std::find_if(s.begin(), s.end(),
48 std::not1(std::ptr_fun<int, int>(std::isspace))));
53 static inline std::string &rtrim(std::string &
s) {
54 s.erase(std::find_if(s.rbegin(), s.rend(),
55 std::not1(std::ptr_fun<int, int>(std::isspace)))
61 static inline std::string &trim(std::string &s) {
62 return ltrim(rtrim(s));
69 inline void factoryInfoSetHelper(std::string&
dest,
const std::string
value,
70 const std::string& desc,
71 const std::string&
id) {
74 }
else if (dest != value) {
76 o <<
"new factory loaded for '" <<
id <<
"' with different "
77 << desc <<
": " << dest <<
" != " <<
value;
84 void operator() (
const char c) {
93 name.push_back(
'_');
break;
95 name.push_back(
'r');
break;
97 name.push_back(
'p');
break;
100 name.push_back(c);
break;
105 std::string old_style_name(
const std::string& name) {
106 return std::for_each(name.begin(), name.end(), OldStyleCnv()).name;
110 namespace Gaudi {
namespace PluginService {
115 return m_msg.c_str();
126 realname = abi::__cxa_demangle(
id.c_str(), 0, 0, &status);
127 if (realname == 0)
return id;
128 std::string result(realname);
149 const char* envVar =
"PATH";
150 const char sep =
';';
152 const char* envVar =
"LD_LIBRARY_PATH";
153 const char sep =
':';
155 char *search_path = ::getenv(envVar);
157 logger().
debug(std::string(
"searching factories in ") + envVar);
158 std::string
path(search_path);
159 std::string::size_type pos = 0;
160 std::string::size_type newpos = 0;
161 while (pos != std::string::npos) {
164 newpos = path.find(sep, pos);
165 if (newpos != std::string::npos) {
166 dirName = path.substr(pos, newpos - pos);
169 dirName = path.substr(pos);
172 logger().
debug(std::string(
" looking into ") + dirName);
174 DIR *dir = opendir(dirName.c_str());
176 struct dirent * entry;
177 while ((entry = readdir(dir))) {
178 std::string name(entry->d_name);
180 std::string::size_type extpos = name.find(
".components");
181 if ((extpos != std::string::npos) &&
182 ((extpos+11) == name.size())) {
183 std::string fullPath = (dirName +
'/' + name);
186 stat(fullPath.c_str(), &buf);
187 if (!S_ISREG(buf.st_mode))
continue;
191 std::ifstream
factories(fullPath.c_str());
193 int factoriesCount = 0;
200 if (line.empty() || line[0] ==
'#')
continue;
202 std::string::size_type pos = line.find(
':');
203 if (pos == std::string::npos) {
204 std::ostringstream o;
205 o <<
"failed to parse line " << fullPath
210 const std::string lib(line, 0, pos);
211 const std::string fact(line, pos+1);
213 #ifdef GAUDI_REFLEX_COMPONENT_ALIASES
215 std::string old_name = old_style_name(fact);
216 if (fact != old_name) {
219 m_factories.insert(std::make_pair(old_name, old_info));
225 std::ostringstream o;
226 o <<
" found " << factoriesCount <<
" factories";
239 const std::string&
type,
const std::string& rtype,
240 const std::string& className,
244 FactoryMap::iterator entry = facts.find(
id);
245 if (entry == facts.end())
248 entry = facts.insert(std::make_pair(
id,
250 type, rtype, className, props))).first;
253 if (!entry->second.ptr) {
254 entry->second.ptr = factory;
256 factoryInfoSetHelper(entry->second.type, type,
"type",
id);
257 factoryInfoSetHelper(entry->second.rtype, rtype,
"return type",
id);
258 factoryInfoSetHelper(entry->second.className, className,
"class",
id);
260 #ifdef GAUDI_REFLEX_COMPONENT_ALIASES
262 std::string old_name = old_style_name(
id);
264 add(old_name, factory, type, rtype, className, props)
267 return entry->second;
273 FactoryMap::const_iterator f = facts.find(
id);
274 if (f != facts.end())
276 #ifdef GAUDI_REFLEX_COMPONENT_ALIASES
277 const Properties& props = f->second.properties;
278 if (props.find(
"ReflexName") != props.end())
279 logger().
warning(
"requesting factory via old name '" +
id +
"'"
280 "use '" + f->second.className +
"' instead");
282 if (!f->second.ptr) {
283 if (!dlopen(f->second.library.c_str(), RTLD_LAZY | RTLD_GLOBAL)) {
285 " for factory " +
id);
286 char *dlmsg = dlerror();
293 if (f->second.type == type) {
294 return f->second.ptr;
296 logger().
warning(
"found factory " +
id +
", but of wrong type: " +
307 FactoryMap::const_iterator f = facts.find(
id);
308 if (f != facts.end())
317 const std::string& k,
318 const std::string& v) {
321 FactoryMap::iterator f = facts.find(
id);
322 if (f != facts.end())
324 f->second.properties[k] = v;
333 for (FactoryMap::const_iterator f = facts.begin();
334 f != facts.end(); ++f)
343 static const char* levels[] = {
"DEBUG : ",
347 if (lvl >=
level()) {
348 std::cerr << levels[lvl] << msg << std::endl;
352 static std::auto_ptr<Logger> s_logger(
new Logger);
357 s_logger.reset(logger);
363 using namespace Details;
367 else if (debugLevel > 0)
373 using namespace Details;
const FactoryInfo & getInfo(const std::string &id) const
Retrieve the FactoryInfo object for an id.
Registry & addProperty(const std::string &id, const std::string &k, const std::string &v)
Add a property to an already existing FactoryInfo object (via its id.)
Registry()
Private constructor for the singleton pattern.
void initialize()
Initialize the registry loading the list of factories from the .component files in the library search...
std::set< KeyType > loadedFactories() const
Return a list of all the known and loaded factories.
GAUDIPS_API Logger & logger()
Return the current logger instance.
std::map< KeyType, std::string > Properties
Type used for the properties implementation.
Simple logging class, just to provide a default implementation.
GAUDIPS_API void SetDebug(int debugLevel)
Backward compatibility with Reflex.
void * get(const std::string &id, const std::string &type) const
Retrieve the factory for the given id.
GAUDIPS_API std::string demangle(const std::type_info &id)
Return a canonical name for type_info object (implementation borrowed from GaudiKernel/System).
const FactoryMap & factories() const
Return the known factories (loading the list if not yet done).
virtual void report(Level lvl, const std::string &msg)
void warning(const std::string &msg)
GAUDI_API std::string path(const AIDA::IBaseHistogram *aida)
get the path in THS for AIDA histogram
GAUDIPS_API void * getCreator(const std::string &id, const std::string &type)
Function used to load a specific factory function.
static Registry & instance()
Retrieve the singleton instance of Registry.
In-memory database of the loaded factories.
virtual const char * what() const
FactoryInfo & add(const I &id, typename F::FuncType ptr)
Add a factory to the database.
GAUDIPS_API int Debug()
Backward compatibility with Reflex.
GAUDIPS_API void setLogger(Logger *logger)
Set the logger instance to use.
This is a number of static methods for bootstrapping the Gaudi framework.
Exception(const std::string &msg)
std::map< KeyType, FactoryInfo > FactoryMap
Type used for the database implementation.
FactoryMap m_factories
Internal storage for factories.
bool m_initialized
Flag recording if the registry has been initialized or not.
void debug(const std::string &msg)