26 #include "usServiceRegistry_p.h"
29 #include "usServiceRegistry_p.h"
30 #include "usServiceRegistrationBasePrivate.h"
31 #include "usModulePrivate.h"
32 #include "usCoreModuleContext_p.h"
38 const std::vector<std::string>& classes,
39 bool isFactory,
bool isPrototypeFactory,
42 static long nextServiceID = 1;
52 if (isPrototypeFactory)
65 return ServicePropertiesImpl(props);
68 ServiceRegistry::ServiceRegistry(CoreModuleContext* coreCtx)
74 ServiceRegistry::~ServiceRegistry()
79 void ServiceRegistry::Clear()
82 serviceRegistrations.clear();
83 classServices.clear();
87 ServiceRegistrationBase ServiceRegistry::RegisterService(ModulePrivate* module,
93 throw std::invalid_argument(
"Can't register empty InterfaceMap as a service");
97 bool isFactory = service.count(
"org.cppmicroservices.factory") > 0;
98 bool isPrototypeFactory = (isFactory ?
dynamic_cast<PrototypeServiceFactory*
>(
reinterpret_cast<ServiceFactory*
>(service.find(
"org.cppmicroservices.factory")->second)) != NULL :
false);
100 std::vector<std::string> classes;
102 for (InterfaceMap::const_iterator i = service.begin();
103 i != service.end(); ++i)
105 if (i->first.empty() || (!isFactory && i->second == NULL))
107 throw std::invalid_argument(
"Can't register as null class");
109 classes.push_back(i->first);
112 ServiceRegistrationBase res(module, service,
113 CreateServiceProperties(properties, classes, isFactory, isPrototypeFactory));
115 MutexLock lock(mutex);
116 services.insert(std::make_pair(res, classes));
117 serviceRegistrations.push_back(res);
118 for (std::vector<std::string>::const_iterator i = classes.begin();
119 i != classes.end(); ++i)
121 std::vector<ServiceRegistrationBase>& s = classServices[*i];
122 std::vector<ServiceRegistrationBase>::iterator ip =
123 std::lower_bound(s.begin(), s.end(), res);
128 ServiceReferenceBase r = res.GetReference(std::string());
129 ServiceListeners::ServiceListenerEntries listeners;
130 ServiceEvent registeredEvent(ServiceEvent::REGISTERED, r);
131 module->coreCtx->listeners.GetMatchingServiceListeners(registeredEvent, listeners);
132 module->coreCtx->listeners.ServiceChanged(listeners,
137 void ServiceRegistry::UpdateServiceRegistrationOrder(
const ServiceRegistrationBase& sr,
138 const std::vector<std::string>& classes)
140 MutexLock lock(mutex);
141 for (std::vector<std::string>::const_iterator i = classes.begin();
142 i != classes.end(); ++i)
144 std::vector<ServiceRegistrationBase>& s = classServices[*i];
145 s.erase(std::remove(s.begin(), s.end(), sr), s.end());
146 s.insert(std::lower_bound(s.begin(), s.end(), sr), sr);
150 void ServiceRegistry::Get(
const std::string& clazz,
151 std::vector<ServiceRegistrationBase>& serviceRegs)
const
153 MutexLock lock(mutex);
154 Get_unlocked(clazz, serviceRegs);
157 void ServiceRegistry::Get_unlocked(
const std::string& clazz,
158 std::vector<ServiceRegistrationBase>& serviceRegs)
const
160 MapClassServices::const_iterator i = classServices.find(clazz);
161 if (i != classServices.end())
163 serviceRegs = i->second;
167 ServiceReferenceBase ServiceRegistry::Get(ModulePrivate* module,
const std::string& clazz)
const
169 MutexLock lock(mutex);
172 std::vector<ServiceReferenceBase> srs;
173 Get_unlocked(clazz,
"", module, srs);
174 US_DEBUG <<
"get service ref " << clazz <<
" for module "
175 << module->info.name <<
" = " << srs.size() <<
" refs";
182 catch (
const std::invalid_argument& )
185 return ServiceReferenceBase();
188 void ServiceRegistry::Get(
const std::string& clazz,
const std::string& filter,
189 ModulePrivate* module, std::vector<ServiceReferenceBase>& res)
const
191 MutexLock lock(mutex);
192 Get_unlocked(clazz, filter, module, res);
195 void ServiceRegistry::Get_unlocked(
const std::string& clazz,
const std::string& filter,
196 ModulePrivate* module, std::vector<ServiceReferenceBase>& res)
const
198 std::vector<ServiceRegistrationBase>::const_iterator s;
199 std::vector<ServiceRegistrationBase>::const_iterator send;
200 std::vector<ServiceRegistrationBase> v;
206 ldap = LDAPExpr(filter);
207 LDAPExpr::ObjectClassSet matched;
208 if (ldap.GetMatchedObjectClasses(matched))
211 for(LDAPExpr::ObjectClassSet::const_iterator className = matched.begin();
212 className != matched.end(); ++className)
214 MapClassServices::const_iterator i = classServices.find(*className);
215 if (i != classServices.end())
217 std::copy(i->second.begin(), i->second.end(), std::back_inserter(v));
232 s = serviceRegistrations.begin();
233 send = serviceRegistrations.end();
238 s = serviceRegistrations.begin();
239 send = serviceRegistrations.end();
244 MapClassServices::const_iterator it = classServices.find(clazz);
245 if (it != classServices.end())
247 s = it->second.begin();
248 send = it->second.end();
256 ldap = LDAPExpr(filter);
260 for (; s != send; ++s)
262 ServiceReferenceBase sri = s->GetReference(clazz);
264 if (filter.empty() || ldap.Evaluate(s->d->properties,
false))
274 core->serviceHooks.FilterServiceReferences(module->moduleContext, clazz, filter, res);
278 core->serviceHooks.FilterServiceReferences(NULL, clazz, filter, res);
283 void ServiceRegistry::RemoveServiceRegistration(
const ServiceRegistrationBase& sr)
285 MutexLock lock(mutex);
288 const std::vector<std::string>& classes =
ref_any_cast<std::vector<std::string> >(
291 serviceRegistrations.erase(std::remove(serviceRegistrations.begin(), serviceRegistrations.end(), sr),
292 serviceRegistrations.end());
293 for (std::vector<std::string>::const_iterator i = classes.begin();
294 i != classes.end(); ++i)
296 std::vector<ServiceRegistrationBase>& s = classServices[*i];
299 s.erase(std::remove(s.begin(), s.end(), sr), s.end());
303 classServices.erase(*i);
308 void ServiceRegistry::GetRegisteredByModule(ModulePrivate* p,
309 std::vector<ServiceRegistrationBase>& res)
const
311 MutexLock lock(mutex);
313 for (std::vector<ServiceRegistrationBase>::const_iterator i = serviceRegistrations.begin();
314 i != serviceRegistrations.end(); ++i)
316 if (i->d->module == p)
323 void ServiceRegistry::GetUsedByModule(Module* p,
324 std::vector<ServiceRegistrationBase>& res)
const
326 MutexLock lock(mutex);
328 for (std::vector<ServiceRegistrationBase>::const_iterator i = serviceRegistrations.begin();
329 i != serviceRegistrations.end(); ++i)
331 if (i->d->IsUsedByModule(p))
US_Core_EXPORT const std::string & SCOPE_MODULE()
US_Core_EXPORT const std::string & SCOPE_PROTOTYPE()
std::map< std::string, void * > InterfaceMap
US_Core_EXPORT const std::string & SERVICE_SCOPE()
US_Core_EXPORT const std::string & SCOPE_SINGLETON()
US_Core_EXPORT const std::string & OBJECTCLASS()
US_UNORDERED_MAP_TYPE< std::string, Any > ServiceProperties
const ValueType & ref_any_cast(const Any &operand)
static bool in(Reader::Char c, Reader::Char c1, Reader::Char c2, Reader::Char c3, Reader::Char c4)
US_Core_EXPORT const std::string & SERVICE_ID()