/*============================================================================= 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 "ctkMTProviderTracker_p.h" #include "ctkMTMsg_p.h" #include #include #include #include class ctkMTProviderTracker::MetaTypeProviderWrapper { public: ctkMetaTypeProvider* provider; QString pid; bool factory; MetaTypeProviderWrapper(ctkMetaTypeProvider* provider, const QString& pid, bool factory) : provider(provider), pid(pid), factory(factory) { } bool operator==(const MetaTypeProviderWrapper& o) const { if (this == &o) return true; return provider == o.provider && pid == o.pid && factory == o.factory; } }; uint qHash(const ctkMTProviderTracker::MetaTypeProviderWrapper wrapper) { uint result = 17; result = 31 * result + qHash(wrapper.provider); result = 31 * result + qHash(wrapper.pid); result = 31 * result + (wrapper.factory ? 1 : 0); return result; } ctkMTProviderTracker::ctkMTProviderTracker(const QSharedPointer& plugin, ctkLogService* log, ctkServiceTracker<>* tracker) : _plugin(plugin), log(log), _tracker(tracker) { } QStringList ctkMTProviderTracker::getPids() const { return getPids(false); } QStringList ctkMTProviderTracker::getFactoryPids() const { return getPids(true); } QSharedPointer ctkMTProviderTracker::getPlugin() const { return _plugin; } ctkObjectClassDefinitionPtr ctkMTProviderTracker::getObjectClassDefinition(const QString& id, const QLocale& locale) { if (_plugin->getState() != ctkPlugin::ACTIVE) { return ctkObjectClassDefinitionPtr(); // return none if not active } QSet wrappers = getMetaTypeProviders(); QSet::ConstIterator end = wrappers.end(); for (QSet::ConstIterator it = wrappers.begin(); it != end; ++it) { if (id == (*it).pid) { // found a matching pid now call the actual provider return (*it).provider->getObjectClassDefinition(id, locale); } } return ctkObjectClassDefinitionPtr(); } QList ctkMTProviderTracker::getLocales() const { if (_plugin->getState() != ctkPlugin::ACTIVE) { return QList(); // return none if not active } QSet wrappers = getMetaTypeProviders(); QList locales; // collect all the unique locales from all providers we found QSet::ConstIterator end = wrappers.end(); for (QSet::ConstIterator it = wrappers.begin(); it != end; ++it) { QList wrappedLocales = (*it).provider->getLocales(); if (wrappedLocales.isEmpty()) continue; for (int j = 0; j < wrappedLocales.size(); j++) if (!locales.contains(wrappedLocales[j])) locales.push_back(wrappedLocales[j]); } return locales; } QStringList ctkMTProviderTracker::getPids(bool factory) const { if (_plugin->getState() != ctkPlugin::ACTIVE) { return QStringList(); // return none if not active } QSet wrappers = getMetaTypeProviders(); QStringList results; QSet::ConstIterator end = wrappers.end(); for (QSet::ConstIterator it = wrappers.begin(); it != end; ++it) { // return only the correct type of pids (regular or factory) if (factory == (*it).factory) results.push_back((*it).pid); } return results; } QSet ctkMTProviderTracker::getMetaTypeProviders() const { QMap services = _tracker->getTracked(); if (services.isEmpty()) { return QSet(); } QList serviceReferences = services.keys(); QSet result; foreach (ctkServiceReference serviceReference, serviceReferences) { if (serviceReference.getPlugin() == _plugin) { QObject* service = services.value(serviceReference); // If the service is not a ctkMetaTypeProvider, we're not interested in it. if (ctkMetaTypeProvider* metatypeService = qobject_cast(service)) { // Include the METATYPE_PID, if present, to return as part of getPids(). Also, include the // METATYPE_FACTORY_PID, if present, to return as part of getFactoryPids(). // The filter ensures at least one of these properties was set for a standalone ctkMetaTypeProvider. addMetaTypeProviderWrappers(ctkMetaTypeProvider::METATYPE_PID, serviceReference, metatypeService, false, result); addMetaTypeProviderWrappers(ctkMetaTypeProvider::METATYPE_FACTORY_PID, serviceReference, metatypeService, true, result); // If the service is a ctkManagedService, include the SERVICE_PID to return as part of getPids(). // The filter ensures the SERVICE_PID property was set. if (qobject_cast(service)) { addMetaTypeProviderWrappers(ctkPluginConstants::SERVICE_PID, serviceReference, metatypeService, false, result); } // If the service is a ctkManagedServiceFactory, include the SERVICE_PID to return as part of getFactoryPids(). // The filter ensures the SERVICE_PID property was set. else if (qobject_cast(service)) { addMetaTypeProviderWrappers(ctkPluginConstants::SERVICE_PID, serviceReference, metatypeService, true, result); } } } } return result; } void ctkMTProviderTracker::addMetaTypeProviderWrappers(const QString& servicePropertyName, const ctkServiceReference& serviceReference, ctkMetaTypeProvider* service, bool factory, QSet& wrappers) const { QStringList pids = getStringProperty(servicePropertyName, serviceReference.getProperty(servicePropertyName)); foreach (QString pid, pids) { wrappers.insert(MetaTypeProviderWrapper(service, pid, factory)); } } QStringList ctkMTProviderTracker::getStringProperty(const QString& name, const QVariant& value) const { // Don't log a warning if the value is null. The filter guarantees at least one of the necessary properties // is there. If others are not, this method will get called with value equal to null. if (value.isNull()) return QStringList(); if (value.canConvert()) { return value.toStringList(); } CTK_WARN(log) << QCoreApplication::translate(ctkMTMsg::CONTEXT, ctkMTMsg::INVALID_PID_METATYPE_PROVIDER_IGNORED) .arg(_plugin->getSymbolicName()).arg(_plugin->getPluginId()).arg(name). arg(value.toString()); return QStringList(); }