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();
136 const char* envVar =
"PATH";
137 const char sep =
';';
139 const char* envVar =
"LD_LIBRARY_PATH";
140 const char sep =
':';
142 char *search_path = ::getenv(envVar);
144 logger().
debug(std::string(
"searching factories in ") + envVar);
145 std::string
path(search_path);
146 std::string::size_type pos = 0;
147 std::string::size_type newpos = 0;
148 while (pos != std::string::npos) {
151 newpos = path.find(sep, pos);
152 if (newpos != std::string::npos) {
153 dirName = path.substr(pos, newpos - pos);
156 dirName = path.substr(pos);
159 logger().
debug(std::string(
" looking into ") + dirName);
161 DIR *dir = opendir(dirName.c_str());
163 struct dirent * entry;
164 while ((entry = readdir(dir))) {
165 std::string name(entry->d_name);
167 std::string::size_type extpos = name.find(
".components");
168 if ((extpos != std::string::npos) &&
169 ((extpos+11) == name.size())) {
170 std::string fullPath = (dirName +
'/' + name);
173 stat(fullPath.c_str(), &buf);
174 if (!S_ISREG(buf.st_mode))
continue;
178 std::ifstream
factories(fullPath.c_str());
180 int factoriesCount = 0;
187 if (line.empty() || line[0] ==
'#')
continue;
189 std::string::size_type pos = line.find(
':');
190 if (pos == std::string::npos) {
191 std::ostringstream o;
192 o <<
"failed to parse line " << fullPath
197 const std::string lib(line, 0, pos);
198 const std::string fact(line, pos+1);
200 #ifdef GAUDI_REFLEX_COMPONENT_ALIASES
202 std::string old_name = old_style_name(fact);
203 if (fact != old_name) {
206 m_factories.insert(std::make_pair(old_name, old_info));
212 std::ostringstream o;
213 o <<
" found " << factoriesCount <<
" factories";
226 const std::string&
type,
const std::string& rtype,
227 const std::string& className,
231 FactoryMap::iterator entry = facts.find(
id);
232 if (entry == facts.end())
235 entry = facts.insert(std::make_pair(
id,
237 type, rtype, className, props))).first;
240 if (!entry->second.ptr) {
241 entry->second.ptr = factory;
243 factoryInfoSetHelper(entry->second.type, type,
"type",
id);
244 factoryInfoSetHelper(entry->second.rtype, rtype,
"return type",
id);
245 factoryInfoSetHelper(entry->second.className, className,
"class",
id);
247 #ifdef GAUDI_REFLEX_COMPONENT_ALIASES
249 std::string old_name = old_style_name(
id);
251 add(old_name, factory, type, rtype, className, props)
254 return entry->second;
260 FactoryMap::const_iterator f = facts.find(
id);
261 if (f != facts.end())
263 #ifdef GAUDI_REFLEX_COMPONENT_ALIASES
264 const Properties& props = f->second.properties;
265 if (props.find(
"ReflexName") != props.end())
266 logger().
warning(
"requesting factory via old name '" +
id +
"'"
267 "use '" + f->second.className +
"' instead");
269 if (!f->second.ptr) {
270 if (!dlopen(f->second.library.c_str(), RTLD_LAZY | RTLD_GLOBAL)) {
272 " for factory " +
id);
273 char *dlmsg = dlerror();
280 if (f->second.type == type) {
281 return f->second.ptr;
283 logger().
warning(
"found factory " +
id +
", but of wrong type: " +
284 f->second.type +
" instead of " + type);
294 FactoryMap::const_iterator f = facts.find(
id);
295 if (f != facts.end())
304 const std::string& k,
305 const std::string& v) {
308 FactoryMap::iterator f = facts.find(
id);
309 if (f != facts.end())
311 f->second.properties[k] = v;
320 for (FactoryMap::const_iterator f = facts.begin();
321 f != facts.end(); ++f)
332 realname = abi::__cxa_demangle(
id.name(), 0, 0, &status);
333 if (realname == 0)
return id.name();
334 std::string result(realname);
340 static const char* levels[] = {
"DEBUG : ",
344 if (lvl >=
level()) {
345 std::cerr << levels[lvl] << msg << std::endl;
349 static std::auto_ptr<Logger> s_logger(
new Logger);
354 s_logger.reset(logger);
360 using namespace Details;
364 else if (debugLevel > 0)
370 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)