| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325 | 
							- /*=============================================================================
 
-   Library: CTK
 
-   Copyright (c) German Cancer Research Center,
 
-     Division of Medical and Biological Informatics
 
-   Licensed under the Apache License, Version 2.0 (the "License");
 
-   you may not use this file except in compliance with the License.
 
-   You may obtain a copy of the License at
 
-     http://www.apache.org/licenses/LICENSE-2.0
 
-   Unless required by applicable law or agreed to in writing, software
 
-   distributed under the License is distributed on an "AS IS" BASIS,
 
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
-   See the License for the specific language governing permissions and
 
-   limitations under the License.
 
- =============================================================================*/
 
- #include "ctkServices_p.h"
 
- #include <QStringListIterator>
 
- #include <QMutexLocker>
 
- #include <QBuffer>
 
- #include <algorithm>
 
- #include "ctkServiceFactory.h"
 
- #include "ctkPluginConstants.h"
 
- #include "ctkPluginFrameworkContext_p.h"
 
- #include "ctkServiceException.h"
 
- #include "ctkServiceRegistration_p.h"
 
- #include "ctkLDAPExpr_p.h"
 
- //----------------------------------------------------------------------------
 
- struct ServiceRegistrationComparator
 
- {
 
-   bool operator()(const ctkServiceRegistration& a, const ctkServiceRegistration& b) const
 
-   {
 
-     return a < b;
 
-   }
 
- };
 
- //----------------------------------------------------------------------------
 
- ctkDictionary ctkServices::createServiceProperties(const ctkDictionary& in,
 
-                                                        const QStringList& classes,
 
-                                                        long sid)
 
- {
 
-   static qlonglong nextServiceID = 1;
 
-   ctkDictionary props = in;
 
-   if (!classes.isEmpty())
 
-   {
 
-     props.insert(ctkPluginConstants::OBJECTCLASS, classes);
 
-   }
 
-   props.insert(ctkPluginConstants::SERVICE_ID, sid != -1 ? sid : nextServiceID++);
 
-   return props;
 
- }
 
- //----------------------------------------------------------------------------
 
- ctkServices::ctkServices(ctkPluginFrameworkContext* fwCtx)
 
-   : mutex(), framework(fwCtx)
 
- {
 
- }
 
- //----------------------------------------------------------------------------
 
- ctkServices::~ctkServices()
 
- {
 
-   clear();
 
- }
 
- //----------------------------------------------------------------------------
 
- void ctkServices::clear()
 
- {
 
-   services.clear();
 
-   classServices.clear();
 
-   framework = 0;
 
- }
 
- //----------------------------------------------------------------------------
 
- ctkServiceRegistration ctkServices::registerService(ctkPluginPrivate* plugin,
 
-                              const QStringList& classes,
 
-                              QObject* service,
 
-                              const ctkDictionary& properties)
 
- {
 
-   if (service == 0)
 
-   {
 
-     throw ctkInvalidArgumentException("Can't register 0 as a service");
 
-   }
 
-   // Check if service implements claimed classes and that they exist.
 
-   for (QStringListIterator i(classes); i.hasNext();)
 
-   {
 
-     QString cls = i.next();
 
-     if (cls.isEmpty())
 
-     {
 
-       throw ctkInvalidArgumentException("Can't register as null class");
 
-     }
 
-     if (!(qobject_cast<ctkServiceFactory*>(service)))
 
-     {
 
-       if (!checkServiceClass(service, cls))
 
-       {
 
-         QString msg = QString("Service class %1 is not an instance of %2. Maybe you forgot the Q_INTERFACES macro in the service class.")
 
-             .arg(service->metaObject()->className()).arg(cls);
 
-         throw ctkInvalidArgumentException(msg);
 
-       }
 
-     }
 
-   }
 
-   ctkServiceRegistration res(plugin, service,
 
-                              createServiceProperties(properties, classes));
 
-   {
 
-     QMutexLocker lock(&mutex);
 
-     services.insert(res, classes);
 
-     for (QStringListIterator i(classes); i.hasNext(); )
 
-     {
 
-       QString currClass = i.next();
 
-       QList<ctkServiceRegistration>& s = classServices[currClass];
 
-       QList<ctkServiceRegistration>::iterator ip =
 
-           std::lower_bound(s.begin(), s.end(), res, ServiceRegistrationComparator());
 
-       s.insert(ip, res);
 
-     }
 
-   }
 
-   ctkServiceReference r = res.getReference();
 
-   plugin->fwCtx->listeners.serviceChanged(
 
-       plugin->fwCtx->listeners.getMatchingServiceSlots(r),
 
-       ctkServiceEvent(ctkServiceEvent::REGISTERED, r));
 
-   return res;
 
- }
 
- //----------------------------------------------------------------------------
 
- void ctkServices::updateServiceRegistrationOrder(const ctkServiceRegistration& sr,
 
-                                               const QStringList& classes)
 
- {
 
-   QMutexLocker lock(&mutex);
 
-   for (QStringListIterator i(classes); i.hasNext(); )
 
-   {
 
-     QList<ctkServiceRegistration>& s = classServices[i.next()];
 
-     s.removeAll(sr);
 
-     s.insert(std::lower_bound(s.begin(), s.end(), sr, ServiceRegistrationComparator()), sr);
 
-   }
 
- }
 
- //----------------------------------------------------------------------------
 
- bool ctkServices::checkServiceClass(QObject* service, const QString& cls) const
 
- {
 
-   return service->inherits(cls.toLatin1());
 
- }
 
- //----------------------------------------------------------------------------
 
- QList<ctkServiceRegistration> ctkServices::get(const QString& clazz) const
 
- {
 
-   QMutexLocker lock(&mutex);
 
-   return classServices.value(clazz);
 
- }
 
- //----------------------------------------------------------------------------
 
- ctkServiceReference ctkServices::get(ctkPluginPrivate* plugin, const QString& clazz) const
 
- {
 
-   QMutexLocker lock(&mutex);
 
-   try {
 
-     QList<ctkServiceReference> srs = get_unlocked(clazz, QString(), plugin);
 
-     if (framework->debug.service_reference)
 
-     {
 
-       qDebug() << "get service ref" << clazz << "for plugin"
 
-                << plugin->location << " = " << srs.size() << "refs";
 
-     }
 
-     if (!srs.isEmpty()) {
 
-       return srs.front();
 
-     }
 
-   }
 
-   catch (const ctkInvalidArgumentException& )
 
-   { }
 
-   return ctkServiceReference();
 
- }
 
- //----------------------------------------------------------------------------
 
- QList<ctkServiceReference> ctkServices::get(const QString& clazz, const QString& filter,
 
-                                             ctkPluginPrivate* plugin) const
 
- {
 
-   QMutexLocker lock(&mutex);
 
-   return get_unlocked(clazz, filter, plugin);
 
- }
 
- //----------------------------------------------------------------------------
 
- QList<ctkServiceReference> ctkServices::get_unlocked(const QString& clazz, const QString& filter,
 
-                                                      ctkPluginPrivate* plugin) const
 
- {
 
-   Q_UNUSED(plugin)
 
-   QListIterator<ctkServiceRegistration>* s = 0;
 
-   QList<ctkServiceRegistration> v;
 
-   ctkLDAPExpr ldap;
 
-   if (clazz.isEmpty())
 
-   {
 
-     if (!filter.isEmpty())
 
-     {
 
-       ldap = ctkLDAPExpr(filter);
 
-       QSet<QString> matched;
 
-       if (ldap.getMatchedObjectClasses(matched))
 
-       {
 
-         v.clear();
 
-         foreach (QString className, matched)
 
-         {
 
-           const QList<ctkServiceRegistration>& cl = classServices[className];
 
-           v += cl;
 
-         }
 
-         if (!v.isEmpty())
 
-         {
 
-           s = new QListIterator<ctkServiceRegistration>(v);
 
-         }
 
-         else
 
-         {
 
-           return QList<ctkServiceReference>();
 
-         }
 
-       }
 
-       else
 
-       {
 
-         s = new QListIterator<ctkServiceRegistration>(services.keys());
 
-       }
 
-     }
 
-     else
 
-     {
 
-       s = new QListIterator<ctkServiceRegistration>(services.keys());
 
-     }
 
-   }
 
-   else
 
-   {
 
-     QList<ctkServiceRegistration> v = classServices.value(clazz);
 
-     if (!v.isEmpty())
 
-     {
 
-       s = new QListIterator<ctkServiceRegistration>(v);
 
-     }
 
-     else
 
-     {
 
-       return QList<ctkServiceReference>();
 
-     }
 
-     if (!filter.isEmpty())
 
-     {
 
-       ldap = ctkLDAPExpr(filter);
 
-     }
 
-   }
 
-   QList<ctkServiceReference> res;
 
-   while (s->hasNext())
 
-   {
 
-     ctkServiceRegistration sr = s->next();
 
-     ctkServiceReference sri = sr.getReference();
 
-     if (filter.isEmpty() || ldap.evaluate(sr.d_func()->properties, false))
 
-     {
 
-       res.push_back(sri);
 
-     }
 
-   }
 
-   delete s;
 
-   return res;
 
- }
 
- //----------------------------------------------------------------------------
 
- void ctkServices::removeServiceRegistration(const ctkServiceRegistration& sr)
 
- {
 
-   QMutexLocker lock(&mutex);
 
-   QStringList classes = sr.d_func()->properties.value(ctkPluginConstants::OBJECTCLASS).toStringList();
 
-   services.remove(sr);
 
-   for (QStringListIterator i(classes); i.hasNext(); )
 
-   {
 
-     QString currClass = i.next();
 
-     QList<ctkServiceRegistration>& s = classServices[currClass];
 
-     if (s.size() > 1)
 
-     {
 
-       s.removeAll(sr);
 
-     }
 
-     else
 
-     {
 
-       classServices.remove(currClass);
 
-     }
 
-   }
 
- }
 
- //----------------------------------------------------------------------------
 
- QList<ctkServiceRegistration> ctkServices::getRegisteredByPlugin(ctkPluginPrivate* p) const
 
- {
 
-   QMutexLocker lock(&mutex);
 
-   QList<ctkServiceRegistration> res;
 
-   for (QHashIterator<ctkServiceRegistration, QStringList> i(services); i.hasNext(); )
 
-   {
 
-     ctkServiceRegistration sr = i.next().key();
 
-     if (sr.d_func()->plugin == p)
 
-     {
 
-       res.push_back(sr);
 
-     }
 
-   }
 
-   return res;
 
- }
 
- //----------------------------------------------------------------------------
 
- QList<ctkServiceRegistration> ctkServices::getUsedByPlugin(QSharedPointer<ctkPlugin> p) const
 
- {
 
-   QMutexLocker lock(&mutex);
 
-   QList<ctkServiceRegistration> res;
 
-   for (QHashIterator<ctkServiceRegistration, QStringList> i(services); i.hasNext(); )
 
-   {
 
-     ctkServiceRegistration sr = i.next().key();
 
-     if (sr.d_func()->isUsedByPlugin(p))
 
-     {
 
-       res.push_back(sr);
 
-     }
 
-   }
 
-   return res;
 
- }
 
 
  |