ctkMTProviderTracker.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /*=============================================================================
  2. Library: CTK
  3. Copyright (c) German Cancer Research Center,
  4. Division of Medical and Biological Informatics
  5. Licensed under the Apache License, Version 2.0 (the "License");
  6. you may not use this file except in compliance with the License.
  7. You may obtain a copy of the License at
  8. http://www.apache.org/licenses/LICENSE-2.0
  9. Unless required by applicable law or agreed to in writing, software
  10. distributed under the License is distributed on an "AS IS" BASIS,
  11. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. See the License for the specific language governing permissions and
  13. limitations under the License.
  14. =============================================================================*/
  15. #include "ctkMTProviderTracker_p.h"
  16. #include "ctkMTMsg_p.h"
  17. #include <service/cm/ctkManagedService.h>
  18. #include <service/cm/ctkManagedServiceFactory.h>
  19. #include <service/log/ctkLogService.h>
  20. #include <QCoreApplication>
  21. class ctkMTProviderTracker::MetaTypeProviderWrapper
  22. {
  23. public:
  24. ctkMetaTypeProvider* provider;
  25. QString pid;
  26. bool factory;
  27. MetaTypeProviderWrapper(ctkMetaTypeProvider* provider, const QString& pid, bool factory)
  28. : provider(provider), pid(pid), factory(factory)
  29. {
  30. }
  31. bool operator==(const MetaTypeProviderWrapper& o) const
  32. {
  33. if (this == &o)
  34. return true;
  35. return provider == o.provider && pid == o.pid && factory == o.factory;
  36. }
  37. };
  38. uint qHash(const ctkMTProviderTracker::MetaTypeProviderWrapper wrapper)
  39. {
  40. uint result = 17;
  41. result = 31 * result + qHash(wrapper.provider);
  42. result = 31 * result + qHash(wrapper.pid);
  43. result = 31 * result + (wrapper.factory ? 1 : 0);
  44. return result;
  45. }
  46. ctkMTProviderTracker::ctkMTProviderTracker(const QSharedPointer<ctkPlugin>& plugin, ctkLogService* log, ctkServiceTracker<>* tracker)
  47. : _plugin(plugin), log(log), _tracker(tracker)
  48. {
  49. }
  50. QStringList ctkMTProviderTracker::getPids() const
  51. {
  52. return getPids(false);
  53. }
  54. QStringList ctkMTProviderTracker::getFactoryPids() const
  55. {
  56. return getPids(true);
  57. }
  58. QSharedPointer<ctkPlugin> ctkMTProviderTracker::getPlugin() const
  59. {
  60. return _plugin;
  61. }
  62. ctkObjectClassDefinitionPtr ctkMTProviderTracker::getObjectClassDefinition(const QString& id, const QLocale& locale)
  63. {
  64. if (_plugin->getState() != ctkPlugin::ACTIVE)
  65. {
  66. return ctkObjectClassDefinitionPtr(); // return none if not active
  67. }
  68. QSet<MetaTypeProviderWrapper> wrappers = getMetaTypeProviders();
  69. QSet<MetaTypeProviderWrapper>::ConstIterator end = wrappers.end();
  70. for (QSet<MetaTypeProviderWrapper>::ConstIterator it = wrappers.begin();
  71. it != end; ++it)
  72. {
  73. if (id == (*it).pid)
  74. {
  75. // found a matching pid now call the actual provider
  76. return (*it).provider->getObjectClassDefinition(id, locale);
  77. }
  78. }
  79. return ctkObjectClassDefinitionPtr();
  80. }
  81. QList<QLocale> ctkMTProviderTracker::getLocales() const
  82. {
  83. if (_plugin->getState() != ctkPlugin::ACTIVE)
  84. {
  85. return QList<QLocale>(); // return none if not active
  86. }
  87. QSet<MetaTypeProviderWrapper> wrappers = getMetaTypeProviders();
  88. QList<QLocale> locales;
  89. // collect all the unique locales from all providers we found
  90. QSet<MetaTypeProviderWrapper>::ConstIterator end = wrappers.end();
  91. for (QSet<MetaTypeProviderWrapper>::ConstIterator it = wrappers.begin();
  92. it != end; ++it)
  93. {
  94. QList<QLocale> wrappedLocales = (*it).provider->getLocales();
  95. if (wrappedLocales.isEmpty())
  96. continue;
  97. for (int j = 0; j < wrappedLocales.size(); j++)
  98. if (!locales.contains(wrappedLocales[j]))
  99. locales.push_back(wrappedLocales[j]);
  100. }
  101. return locales;
  102. }
  103. QStringList ctkMTProviderTracker::getPids(bool factory) const
  104. {
  105. if (_plugin->getState() != ctkPlugin::ACTIVE)
  106. {
  107. return QStringList(); // return none if not active
  108. }
  109. QSet<MetaTypeProviderWrapper> wrappers = getMetaTypeProviders();
  110. QStringList results;
  111. QSet<MetaTypeProviderWrapper>::ConstIterator end = wrappers.end();
  112. for (QSet<MetaTypeProviderWrapper>::ConstIterator it = wrappers.begin();
  113. it != end; ++it)
  114. {
  115. // return only the correct type of pids (regular or factory)
  116. if (factory == (*it).factory)
  117. results.push_back((*it).pid);
  118. }
  119. return results;
  120. }
  121. QSet<ctkMTProviderTracker::MetaTypeProviderWrapper> ctkMTProviderTracker::getMetaTypeProviders() const
  122. {
  123. QMap<ctkServiceReference, QObject*> services = _tracker->getTracked();
  124. if (services.isEmpty())
  125. {
  126. return QSet<MetaTypeProviderWrapper>();
  127. }
  128. QList<ctkServiceReference> serviceReferences = services.keys();
  129. QSet<MetaTypeProviderWrapper> result;
  130. foreach (ctkServiceReference serviceReference, serviceReferences)
  131. {
  132. if (serviceReference.getPlugin() == _plugin)
  133. {
  134. QObject* service = services.value(serviceReference);
  135. // If the service is not a ctkMetaTypeProvider, we're not interested in it.
  136. if (ctkMetaTypeProvider* metatypeService = qobject_cast<ctkMetaTypeProvider*>(service))
  137. {
  138. // Include the METATYPE_PID, if present, to return as part of getPids(). Also, include the
  139. // METATYPE_FACTORY_PID, if present, to return as part of getFactoryPids().
  140. // The filter ensures at least one of these properties was set for a standalone ctkMetaTypeProvider.
  141. addMetaTypeProviderWrappers(ctkMetaTypeProvider::METATYPE_PID, serviceReference, metatypeService, false, result);
  142. addMetaTypeProviderWrappers(ctkMetaTypeProvider::METATYPE_FACTORY_PID, serviceReference, metatypeService, true, result);
  143. // If the service is a ctkManagedService, include the SERVICE_PID to return as part of getPids().
  144. // The filter ensures the SERVICE_PID property was set.
  145. if (qobject_cast<ctkManagedService*>(service))
  146. {
  147. addMetaTypeProviderWrappers(ctkPluginConstants::SERVICE_PID, serviceReference, metatypeService, false, result);
  148. }
  149. // If the service is a ctkManagedServiceFactory, include the SERVICE_PID to return as part of getFactoryPids().
  150. // The filter ensures the SERVICE_PID property was set.
  151. else if (qobject_cast<ctkManagedServiceFactory*>(service))
  152. {
  153. addMetaTypeProviderWrappers(ctkPluginConstants::SERVICE_PID, serviceReference, metatypeService, true, result);
  154. }
  155. }
  156. }
  157. }
  158. return result;
  159. }
  160. void ctkMTProviderTracker::addMetaTypeProviderWrappers(const QString& servicePropertyName,
  161. const ctkServiceReference& serviceReference,
  162. ctkMetaTypeProvider* service, bool factory,
  163. QSet<MetaTypeProviderWrapper>& wrappers) const
  164. {
  165. QStringList pids = getStringProperty(servicePropertyName, serviceReference.getProperty(servicePropertyName));
  166. foreach (QString pid, pids)
  167. {
  168. wrappers.insert(MetaTypeProviderWrapper(service, pid, factory));
  169. }
  170. }
  171. QStringList ctkMTProviderTracker::getStringProperty(const QString& name, const QVariant& value) const
  172. {
  173. // Don't log a warning if the value is null. The filter guarantees at least one of the necessary properties
  174. // is there. If others are not, this method will get called with value equal to null.
  175. if (value.isNull())
  176. return QStringList();
  177. if (value.canConvert<QStringList>())
  178. {
  179. return value.toStringList();
  180. }
  181. CTK_WARN(log) << QCoreApplication::translate(ctkMTMsg::CONTEXT, ctkMTMsg::INVALID_PID_METATYPE_PROVIDER_IGNORED)
  182. .arg(_plugin->getSymbolicName()).arg(_plugin->getPluginId()).arg(name). arg(value.toString());
  183. return QStringList();
  184. }