diff --git a/Plugins/org.mitk.core.services/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.core.services/src/internal/mitkPluginActivator.cpp index 30d39d3ded..7eb7ac19be 100644 --- a/Plugins/org.mitk.core.services/src/internal/mitkPluginActivator.cpp +++ b/Plugins/org.mitk.core.services/src/internal/mitkPluginActivator.cpp @@ -1,40 +1,255 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkPluginActivator.h" #include "internal/mitkDataStorageService.h" +#include +#include +#include + + namespace mitk { +class ITKLightObjectToQObjectAdapter : public QObject +{ + +public: + + ITKLightObjectToQObjectAdapter(const QStringList& clazzes, itk::LightObject* service) + : interfaceNames(clazzes), mitkService(service) + {} + + // This method is called by the Qt meta object system. It is usually + // generated by the moc, but we create it manually to be able to return + // a MITK micro service object (derived from itk::LightObject). It basically + // works as if the micro service class had used the Q_INTERFACES macro in + // its declaration. Now we can successfully do a + // qobject_cast(lightObjectToQObjectAdapter) + void* qt_metacast(const char *_clname) + { + if (!_clname) return 0; + if (!strcmp(_clname, "ITKLightObjectToQObjectAdapter")) + return static_cast(const_cast(this)); + if (interfaceNames.contains(QString(_clname))) + return static_cast(mitkService); + return QObject::qt_metacast(_clname); + } + +private: + + QStringList interfaceNames; + itk::LightObject* mitkService; +}; + const std::string org_mitk_core_services_Activator::PLUGIN_ID = "org.mitk.core.services"; void org_mitk_core_services_Activator::start(ctkPluginContext* context) { + pluginContext = context; + DataStorageService* service = new DataStorageService(); dataStorageService = IDataStorageService::Pointer(service); context->registerService(service); + + // Get the MitkCore Module Context + mitkContext = mitk::ModuleRegistry::GetModule(1)->GetModuleContext(); + + // Process all already registered services + std::list refs = mitkContext->GetServiceReferences(""); + for (std::list::const_iterator i = refs.begin(); + i != refs.end(); ++i) + { + this->AddMitkService(*i); + } + + mitkContext->AddServiceListener(this, &org_mitk_core_services_Activator::MitkServiceChanged); } void org_mitk_core_services_Activator::stop(ctkPluginContext* /*context*/) { + mitkContext->RemoveServiceListener(this, &org_mitk_core_services_Activator::MitkServiceChanged); + + foreach(ctkServiceRegistration reg, mapMitkIdToRegistration.values()) + { + reg.unregister(); + } + mapMitkIdToRegistration.clear(); + + qDeleteAll(mapMitkIdToAdapter); + mapMitkIdToAdapter.clear(); + dataStorageService = 0; + mitkContext = 0; + pluginContext = 0; +} + +void org_mitk_core_services_Activator::MitkServiceChanged(const mitk::ServiceEvent event) +{ + switch (event.GetType()) + { + case mitk::ServiceEvent::REGISTERED: + { + this->AddMitkService(event.GetServiceReference()); + } + case mitk::ServiceEvent::UNREGISTERING: + { + long mitkServiceId = mitk::any_cast(event.GetServiceReference().GetProperty(mitk::ServiceConstants::SERVICE_ID())); + ctkServiceRegistration reg = mapMitkIdToRegistration.take(mitkServiceId); + if (reg) + { + reg.unregister(); + } + delete mapMitkIdToAdapter.take(mitkServiceId); + } + case mitk::ServiceEvent::MODIFIED: + { + long mitkServiceId = mitk::any_cast(event.GetServiceReference().GetProperty(mitk::ServiceConstants::SERVICE_ID())); + ctkDictionary newProps = CreateServiceProperties(event.GetServiceReference()); + mapMitkIdToRegistration[mitkServiceId].setProperties(newProps); + } + default: + ;// do nothing + } +} + +void org_mitk_core_services_Activator::AddMitkService(const mitk::ServiceReference& ref) +{ + // Get the MITK micro service object + itk::LightObject* mitkService = mitkContext->GetService(ref); + if (mitkService == 0) return; + + // Get the interface names against which the service was registered + std::list clazzes = + mitk::any_cast >(ref.GetProperty(mitk::ServiceConstants::OBJECTCLASS())); + + QStringList qclazzes; + for(std::list::const_iterator clazz = clazzes.begin(); + clazz != clazzes.end(); ++clazz) + { + qclazzes << QString::fromStdString(*clazz); + } + + long mitkServiceId = mitk::any_cast(ref.GetProperty(mitk::ServiceConstants::SERVICE_ID())); + + QObject* adapter = new ITKLightObjectToQObjectAdapter(qclazzes, mitkService); + mapMitkIdToAdapter[mitkServiceId] = adapter; + + ctkDictionary props = CreateServiceProperties(ref); + mapMitkIdToRegistration[mitkServiceId] = pluginContext->registerService(qclazzes, adapter, props); +} + +ctkDictionary org_mitk_core_services_Activator::CreateServiceProperties(const ServiceReference &ref) +{ + ctkDictionary props; + + long mitkServiceId = mitk::any_cast(ref.GetProperty(mitk::ServiceConstants::SERVICE_ID())); + props.insert("mitk.serviceid", QVariant::fromValue(mitkServiceId)); + + // Add all other properties from the MITK micro service + std::vector keys; + ref.GetPropertyKeys(keys); + for (std::vector::const_iterator it = keys.begin(); it != keys.end(); ++it) + { + QString key = QString::fromStdString(*it); + mitk::Any value = ref.GetProperty(*it); + // We cannot add any mitk::Any object, we need to query the type + const std::type_info& objType = value.Type(); + if (objType == typeid(std::string)) + { + props.insert(key, QString::fromStdString(ref_any_cast(value))); + } + else if (objType == typeid(std::vector)) + { + const std::vector& list = ref_any_cast >(value); + QStringList qlist; + for (std::vector::const_iterator str = list.begin(); + str != list.end(); ++str) + { + qlist << QString::fromStdString(*str); + } + props.insert(key, qlist); + } + else if (objType == typeid(std::list)) + { + const std::list& list = ref_any_cast >(value); + QStringList qlist; + for (std::list::const_iterator str = list.begin(); + str != list.end(); ++str) + { + qlist << QString::fromStdString(*str); + } + props.insert(key, qlist); + } + else if (objType == typeid(char)) + { + props.insert(key, QChar(ref_any_cast(value))); + } + else if (objType == typeid(unsigned char)) + { + props.insert(key, QChar(ref_any_cast(value))); + } + else if (objType == typeid(bool)) + { + props.insert(key, any_cast(value)); + } + else if (objType == typeid(short)) + { + props.insert(key, any_cast(value)); + } + else if (objType == typeid(unsigned short)) + { + props.insert(key, any_cast(value)); + } + else if (objType == typeid(int)) + { + props.insert(key, any_cast(value)); + } + else if (objType == typeid(unsigned int)) + { + props.insert(key, any_cast(value)); + } + else if (objType == typeid(float)) + { + props.insert(key, any_cast(value)); + } + else if (objType == typeid(double)) + { + props.insert(key, any_cast(value)); + } + else if (objType == typeid(long long int)) + { + props.insert(key, any_cast(value)); + } + else if (objType == typeid(unsigned long long int)) + { + props.insert(key, any_cast(value)); + } + } + + return props; +} + +org_mitk_core_services_Activator::org_mitk_core_services_Activator() + : mitkContext(0), pluginContext(0) +{ } } Q_EXPORT_PLUGIN2(org_mitk_core_services, mitk::org_mitk_core_services_Activator) diff --git a/Plugins/org.mitk.core.services/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.core.services/src/internal/mitkPluginActivator.h index 2f80ac4e5e..3d558524ce 100644 --- a/Plugins/org.mitk.core.services/src/internal/mitkPluginActivator.h +++ b/Plugins/org.mitk.core.services/src/internal/mitkPluginActivator.h @@ -1,50 +1,65 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef MITKCORESERVICESPLUGIN_H_ #define MITKCORESERVICESPLUGIN_H_ #include #include #include "mitkIDataStorageService.h" +#include namespace mitk { +class ModuleContext; + class org_mitk_core_services_Activator : public QObject, public ctkPluginActivator { Q_OBJECT Q_INTERFACES(ctkPluginActivator) public: static const std::string PLUGIN_ID; + + org_mitk_core_services_Activator(); void start(ctkPluginContext* context); void stop(ctkPluginContext* context); + void MitkServiceChanged(const mitk::ServiceEvent event); + private: mitk::IDataStorageService::Pointer dataStorageService; + QMap mapMitkIdToAdapter; + QMap mapMitkIdToRegistration; + + mitk::ModuleContext* mitkContext; + ctkPluginContext* pluginContext; + void AddMitkService(const mitk::ServiceReference &ref); + + ctkDictionary CreateServiceProperties(const mitk::ServiceReference& ref); }; typedef org_mitk_core_services_Activator PluginActivator; } #endif /*MITKCORESERVICESPLUGIN_H_*/