diff --git a/Modules/AppUtil/src/mitkBaseApplication.cpp b/Modules/AppUtil/src/mitkBaseApplication.cpp index 89571e0811..b24cb017ec 100644 --- a/Modules/AppUtil/src/mitkBaseApplication.cpp +++ b/Modules/AppUtil/src/mitkBaseApplication.cpp @@ -1,706 +1,733 @@ /*=================================================================== 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 "mitkBaseApplication.h" #include "mitkLogMacros.h" #include "mitkProvisioningInfo.h" #include "QmitkSafeApplication.h" #include "QmitkSingleApplication.h" #include #include #include #include #include #include #include #include #include #include #include #include #include namespace mitk { QString BaseApplication::ARG_NEWINSTANCE = "BlueBerry.newInstance"; QString BaseApplication::ARG_CLEAN = "BlueBerry.clean"; QString BaseApplication::ARG_APPLICATION = "BlueBerry.application"; QString BaseApplication::ARG_HOME = "BlueBerry.home"; QString BaseApplication::ARG_STORAGE_DIR = "BlueBerry.storageDir"; QString BaseApplication::ARG_PLUGIN_CACHE = "BlueBerry.plugin_cache_dir"; QString BaseApplication::ARG_PLUGIN_DIRS = "BlueBerry.plugin_dirs"; QString BaseApplication::ARG_FORCE_PLUGIN_INSTALL = "BlueBerry.forcePlugins"; QString BaseApplication::ARG_PRELOAD_LIBRARY = "BlueBerry.preloadLibrary"; QString BaseApplication::ARG_PROVISIONING = "BlueBerry.provisioning"; QString BaseApplication::ARG_DEBUG = "BlueBerry.debug"; QString BaseApplication::ARG_CONSOLELOG = "BlueBerry.consoleLog"; QString BaseApplication::ARG_TESTPLUGIN = "BlueBerry.testplugin"; QString BaseApplication::ARG_TESTAPPLICATION = "BlueBerry.testapplication"; QString BaseApplication::ARG_NO_REGISTRY_CACHE = "BlueBerry.noRegistryCache"; QString BaseApplication::ARG_NO_LAZY_REGISTRY_CACHE_LOADING = "BlueBerry.noLazyRegistryCacheLoading"; QString BaseApplication::ARG_REGISTRY_MULTI_LANGUAGE = "BlueBerry.registryMultiLanguage"; QString BaseApplication::ARG_XARGS = "xargs"; QString BaseApplication::PROP_NEWINSTANCE = BaseApplication::ARG_NEWINSTANCE; QString BaseApplication::PROP_FORCE_PLUGIN_INSTALL = BaseApplication::ARG_FORCE_PLUGIN_INSTALL; QString BaseApplication::PROP_NO_REGISTRY_CACHE = BaseApplication::ARG_NO_REGISTRY_CACHE; QString BaseApplication::PROP_NO_LAZY_REGISTRY_CACHE_LOADING = BaseApplication::ARG_NO_LAZY_REGISTRY_CACHE_LOADING; QString BaseApplication::PROP_REGISTRY_MULTI_LANGUAGE = BaseApplication::ARG_REGISTRY_MULTI_LANGUAGE; QString BaseApplication::PROP_APPLICATION = "blueberry.application"; QString BaseApplication::PROP_TESTPLUGIN = "BlueBerry.testplugin"; QString BaseApplication::PROP_TESTAPPLICATION = "BlueBerry.testapplication"; struct BaseApplication::Impl { ctkProperties m_FWProps; QScopedPointer m_QApp; int m_Argc; char** m_Argv; QString m_AppName; QString m_OrgaName; QString m_OrgaDomain; bool m_SingleMode; bool m_SafeMode; QStringList m_PreloadLibs; QString m_ProvFile; Impl(int argc, char** argv) : m_Argc(argc) , m_Argv(argv) , m_SingleMode(false) , m_SafeMode(true) {} QVariant getProperty(const QString& property) const { auto iter = m_FWProps.find(property); return iter == m_FWProps.end() ? QVariant() : iter.value(); } void handleBooleanOption(const std::string& name, const std::string& /*value*/) { QString fwKey = QString::fromStdString(name); // translate some keys to proper framework properties if (fwKey == ARG_CONSOLELOG) { fwKey = ctkPluginFrameworkLauncher::PROP_CONSOLE_LOG; } // For all other options we use the command line option name as the // framework property key. m_FWProps[fwKey] = true; } void handlePreloadLibraryOption(const std::string& /*name*/, const std::string& value) { m_PreloadLibs.push_back(QString::fromStdString(value)); } void handleClean(const std::string& /*name*/, const std::string& /*value*/) { m_FWProps[ctkPluginConstants::FRAMEWORK_STORAGE_CLEAN] = ctkPluginConstants::FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT; } void initializeCTKPluginFrameworkProperties(Poco::Util::LayeredConfiguration& configuration) { // add all configuration key / value pairs as framework properties Poco::Util::LayeredConfiguration::Keys keys; Poco::Util::LayeredConfiguration::Keys keyStack; configuration.keys(keyStack); std::vector keyChain; while(!keyStack.empty()) { std::string currSubKey = keyStack.back(); if (!keyChain.empty() && keyChain.back() == currSubKey) { keyChain.pop_back(); keyStack.pop_back(); continue; } Poco::Util::LayeredConfiguration::Keys subKeys; configuration.keys(currSubKey, subKeys); if (subKeys.empty()) { keyStack.pop_back(); std::string finalKey; for (auto k = keyChain.begin(); k != keyChain.end(); ++k) { finalKey += *k + "."; } finalKey += currSubKey; keys.push_back(finalKey); } else { keyChain.push_back(currSubKey); for (auto s : subKeys) { keyStack.push_back(s); } } } for (auto key : keys) { QString qKey = QString::fromStdString(key); if (!m_FWProps.contains(qKey) && configuration.hasProperty(key)) { m_FWProps[qKey] = QString::fromStdString(configuration.getString(key)); } } } void parseProvisioningFile(const QString& filePath) { // Skip parsing if the file path is empty if (filePath.isEmpty()) return; bool consoleLog = this->getProperty(ctkPluginFrameworkLauncher::PROP_CONSOLE_LOG).toBool(); // read initial plugins from a provisioning file QStringList pluginsToStart; QFileInfo provFile(filePath); if (provFile.exists()) { MITK_INFO(consoleLog) << "Using provisioning file: " << qPrintable(provFile.absoluteFilePath()); ProvisioningInfo provInfo(provFile.absoluteFilePath()); // it can still happen, that the encoding is not compatible with the fromUtf8 function ( i.e. when manipulating the LANG variable // in such case, the QStringList in provInfo is empty which we can easily check for if( provInfo.getPluginDirs().empty() ) { MITK_ERROR << "Cannot search for provisioning file, the retrieved directory list is empty.\n" << "This can occur if there are some special (non-ascii) characters in the install path."; } else { foreach(QString pluginPath, provInfo.getPluginDirs()) { ctkPluginFrameworkLauncher::addSearchPath(pluginPath); } //bool forcePluginOverwrite = this->getProperty(ARG_FORCE_PLUGIN_INSTALL).toBool(); QList pluginUrlsToStart = provInfo.getPluginsToStart(); for(auto url : pluginUrlsToStart) { pluginsToStart.push_back(url.toString()); } //foreach(QUrl pluginUrl, provInfo.getPluginsToInstall()) //{ // TODO for "uninstall", we need a proper configuration agent, e.g. a dedicated // plug-in for provisioning of the platform /* if (forcePluginOverwrite) { uninstallPugin(pluginUrl, context); } */ //try //{ //MITK_INFO(consoleLog) << "Installing CTK plug-in from: " << pluginUrl.toString().toStdString(); /* QSharedPointer plugin = context->installPlugin(pluginUrl); if (pluginsToStart.contains(pluginUrl)) { m_CTKPluginsToStart << plugin->getPluginId(); } */ /* } catch (const ctkPluginException& e) { QString errorMsg; QDebug dbg(&errorMsg); dbg << e.printStackTrace(); BERRY_ERROR << qPrintable(errorMsg); } */ //} } } else { MITK_INFO(consoleLog) << "No provisioning file set."; } if(!pluginsToStart.isEmpty()) { m_FWProps[ctkPluginFrameworkLauncher::PROP_PLUGINS] = pluginsToStart; // Use transient start with declared activation policy (this helps when // the provisioning file changes and some plug-ins should not be installed // in the application any more). ctkPlugin::StartOptions startOptions(ctkPlugin::START_TRANSIENT | ctkPlugin::START_ACTIVATION_POLICY); m_FWProps[ctkPluginFrameworkLauncher::PROP_PLUGINS_START_OPTIONS] = static_cast(startOptions); } } }; BaseApplication::BaseApplication(int argc, char** argv) : Application() , d(new Impl(argc, argv)) { } BaseApplication::~BaseApplication() { } void BaseApplication::printHelp(const std::string& /*name*/, const std::string& /*value*/) { Poco::Util::HelpFormatter help(this->options()); help.setAutoIndent(); help.setCommand(this->commandName()); help.format(std::cout); exit(EXIT_OK); } void BaseApplication::setApplicationName(const QString& name) { - if (qApp) qApp->setApplicationName(name); + if (qApp) + { + qApp->setApplicationName(name); + } d->m_AppName = name; } QString BaseApplication::getApplicationName() const { if (qApp) { return qApp->applicationName(); } return d->m_AppName; } void BaseApplication::setOrganizationName(const QString& name) { - if (qApp) qApp->setOrganizationName(name); + if (qApp) + { + qApp->setOrganizationName(name); + } d->m_OrgaName = name; } QString BaseApplication::getOrganizationName() const { if (qApp) return qApp->organizationName(); return d->m_OrgaName; } void BaseApplication::setOrganizationDomain(const QString& domain) { - if (qApp) qApp->setOrganizationDomain(domain); + if (qApp) + { + qApp->setOrganizationDomain(domain); + } d->m_OrgaDomain = domain; } QString BaseApplication::getOrganizationDomain() const { if (qApp) return qApp->organizationDomain(); return d->m_OrgaDomain; } void BaseApplication::setSingleMode(bool singleMode) { if (qApp) return; d->m_SingleMode = singleMode; } bool BaseApplication::getSingleMode() const { return d->m_SingleMode; } void BaseApplication::setSafeMode(bool safeMode) { if (qApp && !d->m_QApp) return; d->m_SafeMode = safeMode; if (d->m_QApp) { if (getSingleMode()) { static_cast(d->m_QApp.data())->setSafeMode(safeMode); } else { static_cast(d->m_QApp.data())->setSafeMode(safeMode); } } } bool BaseApplication::getSafeMode() const { return d->m_SafeMode; } void BaseApplication::setPreloadLibraries(const QStringList& libraryBaseNames) { d->m_PreloadLibs = libraryBaseNames; } QStringList BaseApplication::getPreloadLibraries() const { return d->m_PreloadLibs; } void BaseApplication::setProvisioningFilePath(const QString& filePath) { d->m_ProvFile = filePath; } QString BaseApplication::getProvisioningFilePath() const { QString provFilePath = d->m_ProvFile; // A null QString means look up a default provisioning file if (provFilePath.isNull() && qApp) { QFileInfo appFilePath(QCoreApplication::applicationFilePath()); QDir basePath(QCoreApplication::applicationDirPath()); + #ifdef Q_OS_MAC + // for MAC applicationDirPath() points to the actual executable within + // the bundle instead of the bundle, we need it to point to the bundle + basePath.cdUp(); + basePath.cdUp(); + basePath.cdUp(); + #endif QString provFileName = appFilePath.baseName() + ".provisioning"; QFileInfo provFile(basePath.absoluteFilePath(provFileName)); if (provFile.exists()) { provFilePath = provFile.absoluteFilePath(); } #ifdef CMAKE_INTDIR else { basePath.cdUp(); provFile.setFile(basePath.absoluteFilePath(provFileName)); if (provFile.exists()) { provFilePath = provFile.absoluteFilePath(); } } #endif } return provFilePath; } void BaseApplication::initializeQt() { if (qApp) return; + // If previously parameters have been set we have to store them + // to hand them through to the application + QString appName = this->getApplicationName(); + QString orgName = this->getOrganizationName(); + QString orgDomain = this->getOrganizationDomain(); + // Create a QCoreApplication instance this->getQApplication(); + + // provide parameters to QCoreApplication + this->setApplicationName(appName); + this->setOrganizationName(orgName); + this->setOrganizationDomain(orgDomain); } void BaseApplication::initialize(Poco::Util::Application& self) { // 1. Call the super-class method Poco::Util::Application::initialize(self); // 2. Initialize the Qt framework (by creating a QCoreApplication) this->initializeQt(); // 3. Seed the random number generator, once at startup. QTime time = QTime::currentTime(); qsrand((uint)time.msec()); // 4. Load the "default" configuration, which involves parsing // an optional .ini file and parsing any // command line arguments this->loadConfiguration(); // 5. Add configuration data from the command line and the // optional .ini file as CTK plugin // framework properties. d->initializeCTKPluginFrameworkProperties(this->config()); // 6. Set the custom CTK Plugin Framework storage directory QString storageDir = this->getCTKFrameworkStorageDir(); if (!storageDir.isEmpty()) { d->m_FWProps[ctkPluginConstants::FRAMEWORK_STORAGE] = storageDir; } // 7. Set the library search paths and the pre-load library property this->initializeLibraryPaths(); QStringList preloadLibs = this->getPreloadLibraries(); if (!preloadLibs.isEmpty()) { d->m_FWProps[ctkPluginConstants::FRAMEWORK_PRELOAD_LIBRARIES] = preloadLibs.join(QString(',')); } // 8. Initialize the CppMicroServices library. // The initializeCppMicroServices() method reuses the // FRAMEWORK_STORAGE property, so we call it after the // getCTKFrameworkStorageDir method. this->initializeCppMicroServices(); // 9. Parse the (optional) provisioning file and set the // correct framework properties. d->parseProvisioningFile(this->getProvisioningFilePath()); // Finally, set the CTK Plugin Framework properties ctkPluginFrameworkLauncher::setFrameworkProperties(d->m_FWProps); } void BaseApplication::uninitialize() { QSharedPointer pfw = this->getFramework(); if (pfw) { pfw->stop(); // wait 10 seconds for the CTK plugin framework to stop pfw->waitForStop(10000); } Poco::Util::Application::uninitialize(); } int BaseApplication::getArgc() const { return d->m_Argc; } char**BaseApplication::getArgv() const { return d->m_Argv; } QString BaseApplication::getCTKFrameworkStorageDir() const { QString storageDir; if (this->getSingleMode()) { // This function checks if an instance is already running // and either sends a message to it (containing the command // line arguments) or checks if a new instance was forced by // providing the BlueBerry.newInstance command line argument. // In the latter case, a path to a temporary directory for // the new application's storage directory is returned. storageDir = handleNewAppInstance(static_cast(d->m_QApp.data()), d->m_Argc, d->m_Argv, ARG_NEWINSTANCE); } if (storageDir.isEmpty()) { // This is a new instance and no other instance is already running. We specify // the storage directory here (this is the same code as in berryInternalPlatform.cpp // so that we can re-use the location for the persistent data location of the // the CppMicroServices library. // Append a hash value of the absolute path of the executable to the data location. // This allows to start the same application from different build or install trees. #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) - storageDir = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + '_'; + storageDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/" + this->getOrganizationName() + "/" + this->getApplicationName() + '_'; #else storageDir = QDesktopServices::storageLocation(QDesktopServices::DataLocation) + '_'; #endif storageDir += QString::number(qHash(QCoreApplication::applicationDirPath())) + "/"; } return storageDir; } void BaseApplication::initializeCppMicroServices() { QString storageDir = this->getProperty(ctkPluginConstants::FRAMEWORK_STORAGE).toString(); if (!storageDir.isEmpty()) { us::ModuleSettings::SetStoragePath((storageDir + QString("us") + QDir::separator()).toStdString()); } } QCoreApplication* BaseApplication::getQApplication() const { QCoreApplication* qCoreApp = qApp; if (!qCoreApp) { if (getSingleMode()) { qCoreApp = new QmitkSingleApplication(d->m_Argc, d->m_Argv, getSafeMode()); } else { QmitkSafeApplication* safeApp = new QmitkSafeApplication(d->m_Argc, d->m_Argv); safeApp->setSafeMode(d->m_SafeMode); qCoreApp = safeApp; } d->m_QApp.reset(qCoreApp); } return qCoreApp; } void BaseApplication::initializeLibraryPaths() { QStringList suffixes; suffixes << "plugins"; #ifdef Q_OS_WINDOWS suffixes << "bin/plugins"; #ifdef CMAKE_INTDIR suffixes << "bin/" CMAKE_INTDIR "/plugins"; #endif #else suffixes << "lib/plugins"; #ifdef CMAKE_INTDIR suffixes << "lib/" CMAKE_INTDIR "/plugins"; #endif #endif #ifdef Q_OS_MAC suffixes << "../../plugins"; #endif // we add a couple of standard library search paths for plug-ins QDir appDir(QCoreApplication::applicationDirPath()); // walk one directory up and add bin and lib sub-dirs; this // might be redundant appDir.cdUp(); foreach(QString suffix, suffixes) { ctkPluginFrameworkLauncher::addSearchPath(appDir.absoluteFilePath(suffix)); } } int BaseApplication::main(const std::vector& /*args*/) { // Start the plugin framework and all installed plug-ins according with // their auto-start setting. return ctkPluginFrameworkLauncher::run().toInt(); } void BaseApplication::defineOptions(Poco::Util::OptionSet& options) { Poco::Util::Option helpOption("help", "h", "print this help text"); helpOption.callback(Poco::Util::OptionCallback(this, &BaseApplication::printHelp)); options.addOption(helpOption); Poco::Util::Option newInstanceOption(ARG_NEWINSTANCE.toStdString(), "", "forces a new instance of this application"); newInstanceOption.callback(Poco::Util::OptionCallback(d.data(), &Impl::handleBooleanOption)); options.addOption(newInstanceOption); Poco::Util::Option cleanOption(ARG_CLEAN.toStdString(), "", "cleans the plugin cache"); cleanOption.callback(Poco::Util::OptionCallback(d.data(), &Impl::handleClean)); options.addOption(cleanOption); Poco::Util::Option appOption(ARG_APPLICATION.toStdString(), "", "the id of the application extension to be executed"); appOption.argument("").binding(PROP_APPLICATION.toStdString()); options.addOption(appOption); Poco::Util::Option provOption(ARG_PROVISIONING.toStdString(), "", "the location of a provisioning file"); provOption.argument("").binding(ARG_PROVISIONING.toStdString()); options.addOption(provOption); Poco::Util::Option storageDirOption(ARG_STORAGE_DIR.toStdString(), "", "the location for storing persistent application data"); storageDirOption.argument("").binding(ctkPluginConstants::FRAMEWORK_STORAGE.toStdString()); options.addOption(storageDirOption); Poco::Util::Option consoleLogOption(ARG_CONSOLELOG.toStdString(), "", "log messages to the console"); consoleLogOption.callback(Poco::Util::OptionCallback(d.data(), &Impl::handleBooleanOption)); options.addOption(consoleLogOption); Poco::Util::Option debugOption(ARG_DEBUG.toStdString(), "", "enable debug mode"); debugOption.argument("", false).binding(ctkPluginFrameworkLauncher::PROP_DEBUG.toStdString()); options.addOption(debugOption); Poco::Util::Option forcePluginOption(ARG_FORCE_PLUGIN_INSTALL.toStdString(), "", "force installing plug-ins with same symbolic name"); forcePluginOption.callback(Poco::Util::OptionCallback(d.data(), &Impl::handleBooleanOption)); options.addOption(forcePluginOption); Poco::Util::Option preloadLibsOption(ARG_PRELOAD_LIBRARY.toStdString(), "", "preload a library"); preloadLibsOption.argument("").repeatable(true).callback(Poco::Util::OptionCallback(d.data(), &Impl::handlePreloadLibraryOption)); options.addOption(preloadLibsOption); Poco::Util::Option testPluginOption(ARG_TESTPLUGIN.toStdString(), "", "the plug-in to be tested"); testPluginOption.argument("").binding(PROP_TESTPLUGIN.toStdString()); options.addOption(testPluginOption); Poco::Util::Option testAppOption(ARG_TESTAPPLICATION.toStdString(), "", "the application to be tested"); testAppOption.argument("").binding(PROP_TESTAPPLICATION.toStdString()); options.addOption(testAppOption); Poco::Util::Option noRegistryCacheOption(ARG_NO_REGISTRY_CACHE.toStdString(), "", "do not use a cache for the registry"); noRegistryCacheOption.callback(Poco::Util::OptionCallback(d.data(), &Impl::handleBooleanOption)); options.addOption(noRegistryCacheOption); Poco::Util::Option noLazyRegistryCacheLoadingOption(ARG_NO_LAZY_REGISTRY_CACHE_LOADING.toStdString(), "", "do not use lazy cache loading for the registry"); noLazyRegistryCacheLoadingOption.callback(Poco::Util::OptionCallback(d.data(), &Impl::handleBooleanOption)); options.addOption(noLazyRegistryCacheLoadingOption); Poco::Util::Option registryMultiLanguageOption(ARG_REGISTRY_MULTI_LANGUAGE.toStdString(), "", "enable multi-language support for the registry"); registryMultiLanguageOption.callback(Poco::Util::OptionCallback(d.data(), &Impl::handleBooleanOption)); options.addOption(registryMultiLanguageOption); Poco::Util::Option xargsOption(ARG_XARGS.toStdString(), "", "Extended argument list"); xargsOption.argument("").binding(ARG_XARGS.toStdString()); options.addOption(xargsOption); Poco::Util::Application::defineOptions(options); } QSharedPointer BaseApplication::getFramework() const { return ctkPluginFrameworkLauncher::getPluginFramework(); } ctkPluginContext* BaseApplication::getFrameworkContext() const { QSharedPointer framework = getFramework(); if (framework) return framework->getPluginContext(); return nullptr; } QHash BaseApplication::getFrameworkProperties() const { return d->m_FWProps; } int BaseApplication::run() { this->init(d->m_Argc, d->m_Argv); return Application::run(); } void BaseApplication::setProperty(const QString& property, const QVariant& value) { d->m_FWProps[property] = value; } QVariant BaseApplication::getProperty(const QString& property) const { return d->getProperty(property); } } diff --git a/Plugins/org.blueberry.core.runtime/src/internal/berryInternalPlatform.cpp b/Plugins/org.blueberry.core.runtime/src/internal/berryInternalPlatform.cpp index 8ff981d6a8..18a94196b6 100644 --- a/Plugins/org.blueberry.core.runtime/src/internal/berryInternalPlatform.cpp +++ b/Plugins/org.blueberry.core.runtime/src/internal/berryInternalPlatform.cpp @@ -1,477 +1,477 @@ /*=================================================================== BlueBerry Platform 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 NOMINMAX #define NOMINMAX #endif #include "berryInternalPlatform.h" #include "berryLog.h" #include "berryLogImpl.h" #include "berryPlatform.h" #include "berryPlatformException.h" #include "berryDebugUtil.h" #include "berryPlatformException.h" #include "berryCTKPluginActivator.h" #include "berryPlatformException.h" #include "berryApplicationContainer.h" #include "berryIBranding.h" //#include "event/berryPlatformEvents.h" //#include "berryPlatformLogChannel.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace berry { QMutex InternalPlatform::m_Mutex; bool InternalPlatform::DEBUG = false; bool InternalPlatform::DEBUG_PLUGIN_PREFERENCES = false; InternalPlatform::InternalPlatform() : m_Initialized(false) , m_ConsoleLog(false) , m_Context(nullptr) { } InternalPlatform::~InternalPlatform() { } InternalPlatform* InternalPlatform::GetInstance() { QMutexLocker lock(&m_Mutex); static InternalPlatform instance; return &instance; } bool InternalPlatform::ConsoleLog() const { return m_ConsoleLog; } QVariant InternalPlatform::GetOption(const QString& option, const QVariant& defaultValue) const { ctkDebugOptions* options = GetDebugOptions(); if (options != nullptr) { return options->getOption(option, defaultValue); } return QVariant(); } IAdapterManager* InternalPlatform::GetAdapterManager() const { AssertInitialized(); return NULL; } SmartPointer InternalPlatform::GetProduct() const { if (product.IsNotNull()) return product; ApplicationContainer* container = org_blueberry_core_runtime_Activator::GetContainer(); IBranding* branding = container == nullptr ? nullptr : container->GetBranding(); if (branding == nullptr) return IProduct::Pointer(); return branding->GetProduct(); } void InternalPlatform::InitializePluginPaths() { QMutexLocker lock(&m_Mutex); // Add search paths for Qt plugins foreach(QString qtPluginPath, m_Context->getProperty(Platform::PROP_QTPLUGIN_PATH).toStringList()) { if (QFile::exists(qtPluginPath)) { QCoreApplication::addLibraryPath(qtPluginPath); } else if (m_ConsoleLog) { BERRY_WARN << "Qt plugin path does not exist: " << qtPluginPath.toStdString(); } } // Add a default search path. It is assumed that installed applications // provide their Qt plugins in that path. static const QString defaultQtPluginPath = QCoreApplication::applicationDirPath() + "/plugins"; if (QFile::exists(defaultQtPluginPath)) { QCoreApplication::addLibraryPath(defaultQtPluginPath); } if (m_ConsoleLog) { std::string pathList; foreach(QString libPath, QCoreApplication::libraryPaths()) { pathList += (pathList.empty() ? "" : ", ") + libPath.toStdString(); } BERRY_INFO << "Qt library search paths: " << pathList; } /* m_ConfigPath.setPath(m_Context->getProperty("application.configDir").toString()); m_InstancePath.setPath(m_Context->getProperty("application.dir").toString()); QString installPath = m_Context->getProperty(Platform::PROP_HOME).toString(); if (installPath.isEmpty()) { m_InstallPath = m_InstancePath; } else { m_InstallPath.setPath(installPath); } QString dataLocation = m_Context->getProperty(Platform::PROP_STORAGE_DIR).toString(); if (!storageDir.isEmpty()) { if (dataLocation.at(dataLocation.size()-1) != '/') { dataLocation += '/'; } m_UserPath.setPath(dataLocation); } else { // Append a hash value of the absolute path of the executable to the data location. // This allows to start the same application from different build or install trees. #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) - dataLocation = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + '_'; + dataLocation = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + this->getOrganizationName() + "/" + this->getApplicationName() + '_'; #else dataLocation = QDesktopServices::storageLocation(QDesktopServices::DataLocation) + '_'; #endif dataLocation += QString::number(qHash(QCoreApplication::applicationDirPath())) + "/"; m_UserPath.setPath(dataLocation); } BERRY_INFO(m_ConsoleLog) << "Framework storage dir: " << m_UserPath.absolutePath(); QFileInfo userFile(m_UserPath.absolutePath()); if (!QDir().mkpath(userFile.absoluteFilePath()) || !userFile.isWritable()) { QString tmpPath = QDir::temp().absoluteFilePath(QString::fromStdString(this->commandName())); BERRY_WARN << "Storage dir " << userFile.absoluteFilePath() << " is not writable. Falling back to temporary path " << tmpPath; QDir().mkpath(tmpPath); userFile.setFile(tmpPath); } m_BaseStatePath.setPath(m_UserPath.absolutePath() + "/bb-metadata/bb-plugins"); QString logPath(m_UserPath.absoluteFilePath(QString::fromStdString(this->commandName()) + ".log")); m_PlatformLogChannel = new Poco::SimpleFileChannel(logPath.toStdString()); */ } ctkDebugOptions* InternalPlatform::GetDebugOptions() const { return m_DebugTracker.isNull() ? nullptr : m_DebugTracker->getService(); } IApplicationContext* InternalPlatform::GetApplicationContext() const { QList refs; try { refs = m_Context->getServiceReferences("(blueberry.application.type=main.thread)"); } catch (const std::invalid_argument&) { return nullptr; } if (refs.isEmpty()) return nullptr; // assumes the application context is available as a service IApplicationContext* result = m_Context->getService(refs.front()); if (result != nullptr) { m_Context->ungetService(refs.front()); return result; } return nullptr; } void InternalPlatform::Start(ctkPluginContext* context) { this->m_Context = context; m_ConsoleLog = m_Context->getProperty(ctkPluginFrameworkLauncher::PROP_CONSOLE_LOG).toBool(); OpenServiceTrackers(); this->InitializePluginPaths(); #ifdef BLUEBERRY_DEBUG_SMARTPOINTER DebugUtil::RestoreState(m_UserPath); #endif InitializeDebugFlags(); this->m_Initialized = true; } void InternalPlatform::Stop(ctkPluginContext* /*context*/) { AssertInitialized(); this->m_Initialized = false; CloseServiceTrackers(); #ifdef BLUEBERRY_DEBUG_SMARTPOINTER DebugUtil::SaveState(m_UserPath); #endif this->m_Context = nullptr; } void InternalPlatform::AssertInitialized() const { if (!m_Initialized) { throw PlatformException("The Platform has not been initialized yet!"); } } void InternalPlatform::OpenServiceTrackers() { ctkPluginContext* context = this->m_Context; instanceLocation.reset(new ctkServiceTracker(context, ctkLDAPSearchFilter(ctkLocation::INSTANCE_FILTER))); instanceLocation->open(); userLocation.reset(new ctkServiceTracker(context, ctkLDAPSearchFilter(ctkLocation::USER_FILTER))); userLocation->open(); configurationLocation.reset(new ctkServiceTracker(context, ctkLDAPSearchFilter(ctkLocation::CONFIGURATION_FILTER))); configurationLocation->open(); installLocation.reset(new ctkServiceTracker(context, ctkLDAPSearchFilter(ctkLocation::INSTALL_FILTER))); installLocation->open(); m_PreferencesTracker.reset(new ctkServiceTracker(context)); m_PreferencesTracker->open(); m_RegistryTracker.reset(new ctkServiceTracker(context)); m_RegistryTracker->open(); m_DebugTracker.reset(new ctkServiceTracker(context)); m_DebugTracker->open(); } void InternalPlatform::CloseServiceTrackers() { if (!m_PreferencesTracker.isNull()) { m_PreferencesTracker->close(); m_PreferencesTracker.reset(); } if (!m_RegistryTracker.isNull()) { m_RegistryTracker->close(); m_RegistryTracker.reset(); } if (!m_DebugTracker.isNull()) { m_DebugTracker->close(); m_DebugTracker.reset(); } } void InternalPlatform::InitializeDebugFlags() { DEBUG = this->GetOption(Platform::PI_RUNTIME + "/debug", false).toBool(); if (DEBUG) { DEBUG_PLUGIN_PREFERENCES = GetOption(Platform::PI_RUNTIME + "/preferences/plugin", false).toBool(); } } IExtensionRegistry* InternalPlatform::GetExtensionRegistry() { return m_RegistryTracker.isNull() ? nullptr : m_RegistryTracker->getService(); } IPreferencesService *InternalPlatform::GetPreferencesService() { return m_PreferencesTracker.isNull() ? nullptr : m_PreferencesTracker->getService(); } ctkLocation* InternalPlatform::GetConfigurationLocation() { this->AssertInitialized(); return configurationLocation->getService(); } ctkLocation* InternalPlatform::GetInstallLocation() { this->AssertInitialized(); return configurationLocation->getService(); } ctkLocation* InternalPlatform::GetInstanceLocation() { this->AssertInitialized(); return installLocation->getService(); } QDir InternalPlatform::GetStateLocation(const QSharedPointer& plugin) { ctkLocation* service = GetInstanceLocation(); if (service == nullptr) { throw ctkIllegalStateException("No instance data can be specified."); } QUrl url = GetInstanceLocation()->getDataArea(plugin->getSymbolicName()); if (!url.isValid()) { throw ctkIllegalStateException("The instance data location has not been specified yet."); } QDir location(url.toLocalFile()); if (!location.exists()) { if (!location.mkpath(location.absolutePath())) { throw PlatformException(QString("Could not create plugin state location \"%1\"").arg(location.absolutePath())); } } return location; } //PlatformEvents& InternalPlatform::GetEvents() //{ // return m_Events; //} ctkLocation* InternalPlatform::GetUserLocation() { this->AssertInitialized(); return userLocation->getService(); } ILog *InternalPlatform::GetLog(const QSharedPointer &plugin) const { LogImpl* result = m_Logs.value(plugin->getPluginId()); if (result != NULL) return result; // ExtendedLogService logService = (ExtendedLogService) extendedLogTracker.getService(); // Logger logger = logService == null ? null : logService.getLogger(bundle, PlatformLogWriter.EQUINOX_LOGGER_NAME); // result = new Log(bundle, logger); // ExtendedLogReaderService logReader = (ExtendedLogReaderService) logReaderTracker.getService(); // logReader.addLogListener(result, result); // logs.put(bundle, result); // return result; result = new LogImpl(plugin); m_Logs.insert(plugin->getPluginId(), result); return result; } bool InternalPlatform::IsRunning() const { QMutexLocker lock(&m_Mutex); try { return m_Initialized && m_Context && m_Context->getPlugin()->getState() == ctkPlugin::ACTIVE; } catch (const ctkIllegalStateException&) { return false; } } QSharedPointer InternalPlatform::GetPlugin(const QString &symbolicName) { QList > plugins = m_Context->getPlugins(); QSharedPointer res(0); foreach(QSharedPointer plugin, plugins) { if ((plugin->getState() & (ctkPlugin::INSTALLED | ctkPlugin::UNINSTALLED)) == 0 && plugin->getSymbolicName() == symbolicName) { if (res.isNull()) { res = plugin; } else if (res->getVersion().compare(plugin->getVersion()) < 0) { res = plugin; } } } return res; } QList > InternalPlatform::GetPlugins(const QString &symbolicName, const QString &version) { QList > plugins = m_Context->getPlugins(); QMap > selected; ctkVersion versionObj(version); foreach(QSharedPointer plugin, plugins) { if ((plugin->getState() & (ctkPlugin::INSTALLED | ctkPlugin::UNINSTALLED)) == 0 && plugin->getSymbolicName() == symbolicName) { if (plugin->getVersion().compare(versionObj) > -1) { selected.insert(plugin->getVersion(), plugin); } } } QList > sortedPlugins = selected.values(); QList > reversePlugins; qCopyBackward(sortedPlugins.begin(), sortedPlugins.end(), reversePlugins.end()); return reversePlugins; } QStringList InternalPlatform::GetApplicationArgs() const { QStringList result; IApplicationContext* appContext = this->GetApplicationContext(); if (appContext) { QHash args = appContext->GetArguments(); result = args[IApplicationContext::APPLICATION_ARGS].toStringList(); } return result; } }