| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448 | 
							- /*=============================================================================
 
-   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 "ctkLocationManager_p.h"
 
- #include "ctkPluginFrameworkProperties_p.h"
 
- #include "ctkBasicLocation_p.h"
 
- #include "ctkException.h"
 
- #include "ctkPluginFrameworkLauncher.h"
 
- #include "ctkPluginConstants.h"
 
- #include <QCoreApplication>
 
- #include <QSettings>
 
- #include <QFileInfo>
 
- #include <QDir>
 
- #include <QUrl>
 
- namespace {
 
- // Constants for configuration location discovery
 
- static const QString CTK = "commontk";
 
- static const QString PRODUCT_SITE_MARKER = ".commontkproduct";
 
- static const QString PRODUCT_SITE_ID = "id";
 
- static const QString PRODUCT_SITE_VERSION = "version";
 
- static const QString CONFIG_DIR = "configuration";
 
- // Data mode constants for user, configuration and data locations.
 
- static const QString NONE = "@none";
 
- static const QString NO_DEFAULT = "@noDefault";
 
- static const QString USER_HOME = "@user.home";
 
- static const QString USER_DIR = "@user.dir";
 
- // Placeholder for hashcode of installation directory
 
- static const QString INSTALL_HASH_PLACEHOLDER = "@install.hash";
 
- static const QString INSTANCE_DATA_AREA_PREFIX = ".metadata/.plugins/";
 
- static QScopedPointer<ctkBasicLocation> installLocation;
 
- static QScopedPointer<ctkBasicLocation> configurationLocation;
 
- static QScopedPointer<ctkBasicLocation> userLocation;
 
- static QScopedPointer<ctkBasicLocation> instanceLocation;
 
- static QScopedPointer<ctkBasicLocation> ctkHomeLocation;
 
- static bool CanWrite(const QUrl& location);
 
- static bool CanWrite(const QFileInfo& location);
 
- static QString SubstituteVar(const QString& source, const QString& var, const QString& prop);
 
- static QString GetInstallDirHash();
 
- static QString ComputeDefaultUserAreaLocation(const QString& pathAppendage);
 
- static bool isInitialized = false;
 
- //----------------------------------------------------------------------------
 
- static QUrl BuildUrl(const QString& location, bool trailingSlash)
 
- {
 
-   QUrl result(location,QUrl::StrictMode);
 
-   if (!result.isValid() || result.scheme().compare("file", Qt::CaseInsensitive) != 0)
 
-   {
 
-     result = QUrl::fromLocalFile(location);
 
-   }
 
-   bool isFile = result.isValid() && result.scheme().compare("file", Qt::CaseInsensitive) == 0;
 
-   if (isFile)
 
-   {
 
-     QString path = result.path();
 
-     if (trailingSlash == path.endsWith('/'))
 
-     {
 
-       return result;
 
-     }
 
-     path = trailingSlash ? path + '/' : path.left(path.size()-1);
 
-     result.setPath(path);
 
-   }
 
-   return result;
 
- }
 
- //----------------------------------------------------------------------------
 
- static QString ComputeCTKHomeLocation()
 
- {
 
-   // TODO MacOS do we need to walk out of the application bundle?
 
-   return QCoreApplication::applicationDirPath();
 
- }
 
- //----------------------------------------------------------------------------
 
- ctkBasicLocation* BuildLocation(const QString& property, const QUrl& defaultLocation,
 
-                            const QString& userDefaultAppendage, bool readOnlyDefault,
 
-                            bool computeReadOnly, const QString& dataAreaPrefix)
 
- {
 
-   QString location = ctkPluginFrameworkProperties::clearProperty(property).toString();
 
-   // the user/product may specify a non-default readOnly setting
 
-   QVariant userReadOnlySetting = ctkPluginFrameworkProperties::getProperty(property + ctkLocationManager::READ_ONLY_AREA_SUFFIX);
 
-   bool readOnly = (userReadOnlySetting.isNull() ? readOnlyDefault : userReadOnlySetting.toBool());
 
-   // if the instance location is not set, predict where the workspace will be and
 
-   // put the instance area inside the workspace meta area.
 
-   if (location.isNull())
 
-   {
 
-     return new ctkBasicLocation(property, defaultLocation,
 
-                                 !userReadOnlySetting.isNull() || !computeReadOnly ? readOnly : !CanWrite(defaultLocation),
 
-                                 dataAreaPrefix);
 
-   }
 
-   QString trimmedLocation = location.trimmed();
 
-   if (trimmedLocation.compare(NONE, Qt::CaseInsensitive) == 0)
 
-   {
 
-     return NULL;
 
-   }
 
-   if (trimmedLocation.compare(NO_DEFAULT, Qt::CaseInsensitive) == 0)
 
-   {
 
-     return new ctkBasicLocation(property, QUrl(), readOnly, dataAreaPrefix);
 
-   }
 
-   if (trimmedLocation.startsWith(USER_HOME))
 
-   {
 
-     QString base = SubstituteVar(location, USER_HOME, ctkPluginFrameworkLauncher::PROP_USER_HOME);
 
-     location = QFileInfo(QDir(base), userDefaultAppendage).absoluteFilePath();
 
-   }
 
-   else if (trimmedLocation.startsWith(USER_DIR))
 
-   {
 
-     QString base = SubstituteVar(location, USER_DIR, ctkPluginFrameworkLauncher::PROP_USER_DIR);
 
-     location = QFileInfo(QDir(base), userDefaultAppendage).absoluteFilePath();
 
-   }
 
-   int idx = location.indexOf(INSTALL_HASH_PLACEHOLDER);
 
-   if (idx == 0)
 
-   {
 
-     throw ctkRuntimeException("The location cannot start with '" + INSTALL_HASH_PLACEHOLDER + "': " + location);
 
-   }
 
-   else if (idx > 0)
 
-   {
 
-     location = location.left(idx) + GetInstallDirHash() + location.mid(idx + INSTALL_HASH_PLACEHOLDER.size());
 
-   }
 
-   QUrl url = BuildUrl(location, true);
 
-   ctkBasicLocation* result = NULL;
 
-   if (url.isValid())
 
-   {
 
-     result = new ctkBasicLocation(property, QUrl(), !userReadOnlySetting.isNull() || !computeReadOnly ? readOnly : !CanWrite(url), dataAreaPrefix);
 
-     result->set(url, false);
 
-   }
 
-   return result;
 
- }
 
- //----------------------------------------------------------------------------
 
- static QString SubstituteVar(const QString& source, const QString& var, const QString& prop)
 
- {
 
-   QString value = ctkPluginFrameworkProperties::getProperty(prop).toString();
 
-   return value + source.mid(var.size());
 
- }
 
- //----------------------------------------------------------------------------
 
- static QUrl ComputeInstallConfigurationLocation()
 
- {
 
-   QString property = ctkPluginFrameworkProperties::getProperty(ctkPluginFrameworkLauncher::PROP_INSTALL_AREA).toString();
 
-   if (!property.isEmpty())
 
-   {
 
-     return BuildUrl(property, true);
 
-   }
 
-   return QUrl();
 
- }
 
- //----------------------------------------------------------------------------
 
- static QUrl ComputeSharedConfigurationLocation()
 
- {
 
-   QVariant property = ctkPluginFrameworkProperties::getProperty(ctkPluginFrameworkLauncher::PROP_SHARED_CONFIG_AREA);
 
-   if (property.isNull())
 
-   {
 
-     return QUrl();
 
-   }
 
-   QUrl sharedConfigurationURL = BuildUrl(property.toString(), true);
 
-   if (!sharedConfigurationURL.isValid())
 
-   {
 
-     return QUrl();
 
-   }
 
-   if (sharedConfigurationURL.path().startsWith("/"))
 
-   {
 
-     // absolute
 
-     return sharedConfigurationURL;
 
-   }
 
-   QUrl installURL = installLocation->getUrl();
 
-   if (sharedConfigurationURL.scheme() != installURL.scheme())
 
-   {
 
-     // different protocol
 
-     return sharedConfigurationURL;
 
-   }
 
-   QString sharedConfigPath = QDir::cleanPath(installURL.path() + '/' + sharedConfigurationURL.path());
 
-   sharedConfigurationURL = installURL;
 
-   sharedConfigurationURL.setPath(sharedConfigPath);
 
-   ctkPluginFrameworkProperties::setProperty(ctkPluginFrameworkLauncher::PROP_SHARED_CONFIG_AREA, sharedConfigurationURL.toString());
 
-   return QUrl();
 
- }
 
- //----------------------------------------------------------------------------
 
- static QString ComputeDefaultConfigurationLocation()
 
- {
 
-   // 1) We store the config state relative to the 'ctk' directory if possible
 
-   // 2) If this directory is read-only
 
-   //    we store the state in <user.home>/.commontk/<application-id>_<version> where <user.home>
 
-   //    is unique for each local user, and <application-id> is the one
 
-   //    defined in .eclipseproduct marker file. If .eclipseproduct does not
 
-   //    exist, use "eclipse" as the application-id.
 
-   QUrl installURL = ComputeInstallConfigurationLocation();
 
-   if (installURL.isValid() && installURL.scheme() == "file")
 
-   {
 
-     QDir installDir(installURL.toLocalFile());
 
-     QFileInfo defaultConfigDir(installDir, CONFIG_DIR);
 
-     if (!defaultConfigDir.exists())
 
-     {
 
-       installDir.mkpath(defaultConfigDir.absoluteFilePath());
 
-     }
 
-     if (defaultConfigDir.exists() && CanWrite(defaultConfigDir))
 
-     {
 
-       return defaultConfigDir.absoluteFilePath();
 
-     }
 
-   }
 
-   // We can't write in the CTK install dir so try for some place in the user's home dir
 
-   return ComputeDefaultUserAreaLocation(CONFIG_DIR);
 
- }
 
- //----------------------------------------------------------------------------
 
- static bool CanWrite(const QFileInfo& location)
 
- {
 
-   if (location.isWritable() == false)
 
-   {
 
-     return false;
 
-   }
 
-   if (!location.isDir())
 
-   {
 
-     return false;
 
-   }
 
-   return true;
 
- }
 
- //----------------------------------------------------------------------------
 
- static bool CanWrite(const QUrl& location)
 
- {
 
-   if (location.isValid() && location.scheme() == "file")
 
-   {
 
-     QFileInfo locationDir(location.toLocalFile());
 
-     if (!locationDir.exists())
 
-     {
 
-       QDir().mkpath(locationDir.absoluteFilePath());
 
-     }
 
-     if (locationDir.exists() && CanWrite(locationDir))
 
-       return true;
 
-   }
 
-   return false;
 
- }
 
- //----------------------------------------------------------------------------
 
- static QString ComputeDefaultUserAreaLocation(const QString& pathAppendage)
 
- {
 
-   //    we store the state in <user.home>/.commontk/<application-id>_<version> where <user.home>
 
-   //    is unique for each local user, and <application-id> is the one
 
-   //    defined in .commontkproduct marker file. If .commontkproduct does not
 
-   //    exist, use "commontk" as the application-id.
 
-   QString installProperty = ctkPluginFrameworkProperties::getProperty(ctkPluginFrameworkLauncher::PROP_INSTALL_AREA).toString();
 
-   QUrl installURL = BuildUrl(installProperty, true);
 
-   if (!installURL.isValid())
 
-   {
 
-     return QString::null;
 
-   }
 
-   QFileInfo installDir(installURL.toLocalFile());
 
-   QString installDirHash = GetInstallDirHash();
 
-   QString appName = "." + CTK;
 
-   QFileInfo ctkProduct(QDir(installDir.absoluteFilePath()), PRODUCT_SITE_MARKER);
 
-   if (ctkProduct.exists())
 
-   {
 
-     QSettings props(ctkProduct.absoluteFilePath(), QSettings::IniFormat);
 
-     QString appId = props.value(PRODUCT_SITE_ID).toString();
 
-     if (appId.trimmed().isEmpty())
 
-     {
 
-       appId = CTK;
 
-     }
 
-     QString appVersion = props.value(PRODUCT_SITE_VERSION).toString();
 
-     if (appVersion.trimmed().isEmpty())
 
-     {
 
-       appVersion = "";
 
-     }
 
-     appName += "/" + appId + "_" + appVersion + "_" + installDirHash;
 
-   }
 
-   else
 
-   {
 
-     // add the hash to help prevent collisions
 
-     appName += "/" + installDirHash;
 
-   }
 
-   QString userHome = ctkPluginFrameworkProperties::getProperty(ctkPluginFrameworkLauncher::PROP_USER_HOME).toString();
 
-   return QFileInfo(QDir(userHome), appName + "/" + pathAppendage).absoluteFilePath();
 
- }
 
- /**
 
-  * Return hash code identifying an absolute installation path
 
-  * @return hash code as String
 
-  */
 
- //----------------------------------------------------------------------------
 
- static QString GetInstallDirHash()
 
- {
 
-   // compute an install dir hash to prevent configuration area collisions with other eclipse installs
 
-   QString installProperty = ctkPluginFrameworkProperties::getProperty(ctkPluginFrameworkLauncher::PROP_INSTALL_AREA).toString();
 
-   QUrl installURL = BuildUrl(installProperty, true);
 
-   if (!installURL.isValid())
 
-   {
 
-     return "";
 
-   }
 
-   QFileInfo installDir(installURL.toLocalFile());
 
-   QString stringToHash = installDir.canonicalFilePath();
 
-   if (stringToHash.isEmpty())
 
-   {
 
-     // fall back to absolute path
 
-     stringToHash = installDir.absoluteFilePath();
 
-   }
 
-   uint hashCode = qHash(stringToHash);
 
-   return QString::number(hashCode);
 
- }
 
- }
 
- const QString ctkLocationManager::READ_ONLY_AREA_SUFFIX = ".readOnly";
 
- // configuration area file/dir names
 
- const QString ctkLocationManager::CONFIG_FILE = "config.ini";
 
- const QString ctkLocationManager::CTK_PROPERTIES = "ctk.properties";
 
- //----------------------------------------------------------------------------
 
- void ctkLocationManager::initializeLocations()
 
- {
 
-   if (isInitialized) return;
 
-   // set the ctk storage area if it exists
 
-   QVariant osgiStorage = ctkPluginFrameworkProperties::getProperty(ctkPluginConstants::FRAMEWORK_STORAGE);
 
-   if (!osgiStorage.isNull())
 
-   {
 
-     ctkPluginFrameworkProperties::setProperty(ctkPluginFrameworkLauncher::PROP_CONFIG_AREA, osgiStorage);
 
-   }
 
-   // do install location initialization first since others may depend on it
 
-   // assumes that the property is already set
 
-   installLocation.reset(BuildLocation(ctkPluginFrameworkLauncher::PROP_INSTALL_AREA, QUrl(), "", true, false, QString::null));
 
-   // TODO not sure what the data area prefix should be here for the user area
 
-   QScopedPointer<ctkBasicLocation> temp(BuildLocation(ctkPluginFrameworkLauncher::PROP_USER_AREA_DEFAULT,
 
-                                                       QUrl(), "", false, false, QString::null));
 
-   QUrl defaultLocation = temp ? temp->getUrl() : QUrl();
 
-   if (!defaultLocation.isValid())
 
-   {
 
-     defaultLocation = BuildUrl(QFileInfo(QDir(ctkPluginFrameworkProperties::getProperty(ctkPluginFrameworkLauncher::PROP_USER_HOME).toString()), "user").absoluteFilePath(), true);
 
-   }
 
-   userLocation.reset(BuildLocation(ctkPluginFrameworkLauncher::PROP_USER_AREA, defaultLocation, "", false, false, QString::null));
 
-   temp.reset(BuildLocation(ctkPluginFrameworkLauncher::PROP_INSTANCE_AREA_DEFAULT, QUrl(), "", false, false, INSTANCE_DATA_AREA_PREFIX));
 
-   defaultLocation = temp ? temp->getUrl() : QUrl();
 
-   if (!defaultLocation.isValid())
 
-   {
 
-     defaultLocation = BuildUrl(QFileInfo(QDir(ctkPluginFrameworkProperties::getProperty(ctkPluginFrameworkLauncher::PROP_USER_DIR).toString()), "workspace").absoluteFilePath(), true);
 
-   }
 
-   instanceLocation.reset(BuildLocation(ctkPluginFrameworkLauncher::PROP_INSTANCE_AREA, defaultLocation, "", false, false, INSTANCE_DATA_AREA_PREFIX));
 
-   //mungeConfigurationLocation();
 
-   // compute a default but it is very unlikely to be used since main will have computed everything
 
-   temp.reset(BuildLocation(ctkPluginFrameworkLauncher::PROP_CONFIG_AREA_DEFAULT, QUrl(), "", false, false, QString::null));
 
-   defaultLocation = temp ? temp->getUrl() : QUrl();
 
-   if (!defaultLocation.isValid() && ctkPluginFrameworkProperties::getProperty(ctkPluginFrameworkLauncher::PROP_CONFIG_AREA).isNull())
 
-   {
 
-     // only compute the default if the configuration area property is not set
 
-     defaultLocation = BuildUrl(ComputeDefaultConfigurationLocation(), true);
 
-   }
 
-   configurationLocation.reset(BuildLocation(ctkPluginFrameworkLauncher::PROP_CONFIG_AREA, defaultLocation, "", false, false, QString::null));
 
-   // get the parent location based on the system property. This will have been set on the
 
-   // way in either by the caller/user or by main.  There will be no parent location if we are not
 
-   // cascaded.
 
-   QUrl parentLocation = ComputeSharedConfigurationLocation();
 
-   if (parentLocation.isValid() && parentLocation != configurationLocation->getUrl())
 
-   {
 
-     ctkBasicLocation* parent = new ctkBasicLocation(QString::null, parentLocation, true, QString::null);
 
-     configurationLocation->setParent(parent);
 
-   }
 
-   //initializeDerivedConfigurationLocations();
 
-   if (ctkPluginFrameworkProperties::getProperty(ctkPluginFrameworkLauncher::PROP_HOME_LOCATION_AREA).isNull())
 
-   {
 
-     QString blueberryHomeLocationPath = ComputeCTKHomeLocation();
 
-     if (!blueberryHomeLocationPath.isEmpty())
 
-     {
 
-       ctkPluginFrameworkProperties::setProperty(ctkPluginFrameworkLauncher::PROP_HOME_LOCATION_AREA, blueberryHomeLocationPath);
 
-     }
 
-   }
 
-   // if ctk.home.location is not set then default to ctk.install.area
 
-   if (ctkPluginFrameworkProperties::getProperty(ctkPluginFrameworkLauncher::PROP_HOME_LOCATION_AREA).isNull() &&
 
-       !ctkPluginFrameworkProperties::getProperty(ctkPluginFrameworkLauncher::PROP_INSTALL_AREA).isNull())
 
-   {
 
-     ctkPluginFrameworkProperties::setProperty(ctkPluginFrameworkLauncher::PROP_HOME_LOCATION_AREA,
 
-                                               ctkPluginFrameworkProperties::getProperty(ctkPluginFrameworkLauncher::PROP_INSTALL_AREA));
 
-   }
 
-   ctkHomeLocation.reset(BuildLocation(ctkPluginFrameworkLauncher::PROP_HOME_LOCATION_AREA, QUrl(), "", true, true, QString::null));
 
-   isInitialized = true;
 
- }
 
- //----------------------------------------------------------------------------
 
- ctkBasicLocation* ctkLocationManager::getUserLocation()
 
- {
 
-   return userLocation.data();
 
- }
 
- //----------------------------------------------------------------------------
 
- ctkBasicLocation* ctkLocationManager::getConfigurationLocation()
 
- {
 
-   return configurationLocation.data();
 
- }
 
- //----------------------------------------------------------------------------
 
- ctkBasicLocation* ctkLocationManager::getInstallLocation()
 
- {
 
-   return installLocation.data();
 
- }
 
- //----------------------------------------------------------------------------
 
- ctkBasicLocation* ctkLocationManager::getInstanceLocation()
 
- {
 
-   return instanceLocation.data();
 
- }
 
- //----------------------------------------------------------------------------
 
- ctkBasicLocation* ctkLocationManager::getCTKHomeLocation()
 
- {
 
-   return ctkHomeLocation.data();
 
- }
 
 
  |