Преглед на файлове

Support configurable plugin framework storage area.

Sascha Zelzer преди 14 години
родител
ревизия
6e2a5ead22

+ 2 - 0
Libs/PluginFramework/ctkPluginConstants.cpp

@@ -25,6 +25,8 @@ const QString	ctkPluginConstants::SYSTEM_PLUGIN_LOCATION = "System Plugin";
 const QString	ctkPluginConstants::SYSTEM_PLUGIN_SYMBOLICNAME = "system.plugin";
 
 const QString ctkPluginConstants::FRAMEWORK_STORAGE = "org.commontk.pluginfw.storage";
+const QString ctkPluginConstants::FRAMEWORK_STORAGE_CLEAN = "org.commontk.pluginfw.storage.clean";
+const QString ctkPluginConstants::FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT = "onFirstInit";
 
 const QString	ctkPluginConstants::PLUGIN_SYMBOLICNAME = "Plugin-SymbolicName";
 const QString ctkPluginConstants::PLUGIN_COPYRIGHT = "Plugin-Copyright";

+ 16 - 0
Libs/PluginFramework/ctkPluginConstants.h

@@ -57,6 +57,22 @@ struct CTK_PLUGINFW_EXPORT ctkPluginConstants {
    */
   static const QString FRAMEWORK_STORAGE; // = "org.commontk.pluginfw.storage"
 
+  /**
+   * Specifies if and when the persistent storage area for the framework
+   * should be cleaned. If this property is not set, then the framework
+   * storage area must not be cleaned.
+   *
+   * @see #FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT
+   */
+  static const QString FRAMEWORK_STORAGE_CLEAN; // = "org.commontk.pluginfw.storage.clean";
+
+  /**
+   * Specifies that the framework storage area must be cleaned before the
+   * framework is initialized for the first time. Subsequent inits, starts or
+   * updates of the framework will not result in cleaning the framework
+   * storage area.
+   */
+  static const QString FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT; //	= "onFirstInit";
 
   /**
    * Manifest header identifying the plugin's symbolic name.

+ 10 - 33
Libs/PluginFramework/ctkPluginDatabase.cpp

@@ -26,6 +26,7 @@
 #include "ctkPluginException.h"
 #include "ctkPluginArchive_p.h"
 #include "ctkPluginStorage_p.h"
+#include "ctkPluginFrameworkUtil_p.h"
 #include "ctkServiceException.h"
 
 #include <QApplication>
@@ -524,40 +525,16 @@ void ctkPluginDatabase::setDatabasePath(const QString &databasePath)
 
 QString ctkPluginDatabase::getDatabasePath() const
 {
-    QString path;
-    if(m_databasePath.isEmpty())
-    {
-      QSettings settings;
-      path = settings.value("PluginDB/Path").toString();
-      if (path.isEmpty())
-      {
-        path = QApplication::applicationDirPath();
-        if (path.lastIndexOf("/") != path.length() -1)
-        {
-          path.append("/");
-        }
-        QString appName = QApplication::applicationName();
-        appName.replace(" ", "");
-        if (!appName.isEmpty())
-        {
-          path.append(appName + "_plugins.db");
-        }
-        else
-        {
-          path.append("pluginfw.db");
-          qWarning() << "Warning: Using generic plugin database name. You should "
-              "set an application name via QCoreApplication::setApplicationName()";
-        }
-      }
-      path = QDir::toNativeSeparators(path);
-    }
-    else
-    {
-      path = m_databasePath;
-    }
+  QString path = m_databasePath;
+  if(path.isEmpty())
+  {
+    path = QDir::homePath() + "/ctkpluginfw/plugins.db";
+    qWarning() << "No database path set. Using default:" << path;
+  }
 
-	qDebug() << "Using database:" << path;
-    return path;
+  path = QDir::toNativeSeparators(path);
+  qDebug() << "Using database:" << path;
+  return path;
 }
 
 

+ 27 - 9
Libs/PluginFramework/ctkPluginFrameworkContext.cpp

@@ -21,6 +21,7 @@
 
 #include "ctkPluginFrameworkContext_p.h"
 
+#include "ctkPluginFrameworkUtil_p.h"
 #include "ctkPluginFrameworkPrivate_p.h"
 #include "ctkPluginArchive_p.h"
 #include "ctkPluginConstants.h"
@@ -34,7 +35,7 @@
   ctkPluginFrameworkContext::ctkPluginFrameworkContext(
       const ctkProperties& initProps)
         : plugins(0), services(0), systemPlugin(this),
-        storage(0), props(initProps)
+        storage(0), firstInit(true), props(initProps)
   {
 
     {
@@ -49,14 +50,12 @@
   {
     log() << "initializing";
 
-//    if (Constants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT
-//        .equals(props.getProperty(Constants.FRAMEWORK_STORAGE_CLEAN))) {
-//      deleteFWDir();
-//      // Must remove the storage clean property since it should not be
-//      // used more than once!
-//      props.removeProperty(Constants.FRAMEWORK_STORAGE_CLEAN);
-//    }
-//    props.save();
+    if (firstInit && ctkPluginConstants::FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT
+        == props[ctkPluginConstants::FRAMEWORK_STORAGE_CLEAN])
+    {
+      deleteFWDir();
+      firstInit = false;
+    }
 
     ctkPluginFrameworkPrivate* const systemPluginPrivate = systemPlugin.d_func();
     systemPluginPrivate->initSystemPlugin();
@@ -187,3 +186,22 @@
 
 
 }
+
+void ctkPluginFrameworkContext::deleteFWDir()
+{
+  QString d = ctkPluginFrameworkUtil::getFrameworkDir(this);
+
+  QFileInfo fwDirInfo(d);
+  if (fwDirInfo.exists())
+  {
+    if(fwDirInfo.isDir())
+    {
+      log() << "deleting old framework directory.";
+      bool bOK = ctkPluginFrameworkUtil::removeDir(fwDirInfo.absoluteFilePath());
+      if(!bOK)
+      {
+        qDebug() << "Failed to remove existing fwdir" << fwDirInfo.absoluteFilePath();
+      }
+    }
+  }
+}

+ 11 - 0
Libs/PluginFramework/ctkPluginFrameworkContext_p.h

@@ -66,6 +66,11 @@
       ctkPluginStorage* storage;
 
       /**
+       * First framework init
+       */
+      bool firstInit;
+
+      /**
        * Framework id.
        */
       int id;
@@ -137,6 +142,12 @@
 
       QSet<ctkPluginPrivate*> tempResolved;
 
+      /**
+       * Delete framework directory if it exists.
+       *
+       */
+      void deleteFWDir();
+
       void checkRequirePlugin(ctkPluginPrivate* plugin);
   };
 

+ 84 - 0
Libs/PluginFramework/ctkPluginFrameworkUtil.cpp

@@ -20,6 +20,7 @@
 =============================================================================*/
 
 #include "ctkPluginFrameworkUtil_p.h"
+#include "ctkPluginFrameworkContext_p.h"
 
 #include <QString>
 
@@ -300,3 +301,86 @@ QList<QMap<QString, QStringList> > ctkPluginFrameworkUtil::parseEntries(const QS
   }
   return result;
 }
+
+QString ctkPluginFrameworkUtil::getFrameworkDir(ctkPluginFrameworkContext* ctx)
+{
+  QString s = ctx->props[ctkPluginConstants::FRAMEWORK_STORAGE].toString();
+  if (s.isEmpty())
+  {
+    s = QCoreApplication::applicationDirPath();
+    if (s.lastIndexOf("/") != s.length() -1)
+    {
+      s.append("/");
+    }
+    QString appName = QCoreApplication::applicationName();
+    appName.replace(" ", "");
+    if (!appName.isEmpty())
+    {
+      s.append(appName + "_ctkpluginfw");
+    }
+    else
+    {
+      s.append("ctkpluginfw");
+      qWarning() << "Warning: Using generic plugin framework storage directory:" << s;
+      qWarning() << "You should set an application name via QCoreApplication::setApplicationName()";
+    }
+  }
+  return s;
+}
+
+QDir ctkPluginFrameworkUtil::getFileStorage(ctkPluginFrameworkContext* ctx,
+                                            const QString& name)
+{
+  // See if we have a storage directory
+  QString fwdir = getFrameworkDir(ctx);
+  if (fwdir.isEmpty())
+  {
+    throw std::runtime_error("The framework storge directory is empty");
+  }
+  QDir dir(fwdir + "/" + name);
+  if (dir.exists())
+  {
+    if (!QFileInfo(dir.absolutePath()).isDir())
+    {
+      QString msg("Not a directory: ");
+      msg.append(dir.absolutePath());
+      throw std::runtime_error(msg.toStdString());
+    }
+  }
+  else
+  {
+    if (!dir.mkpath(dir.absolutePath()))
+    {
+      QString msg("Cannot create directory: ");
+      msg.append(dir.absolutePath());
+      throw std::runtime_error(msg.toStdString());
+    }
+  }
+  return dir;
+}
+
+bool ctkPluginFrameworkUtil::removeDir(const QString& dirName)
+{
+  bool result = true;
+  QDir dir(dirName);
+
+  if (dir.exists(dirName))
+  {
+    foreach (QFileInfo info, dir.entryInfoList(QDir::NoDotAndDotDot | QDir::System | QDir::Hidden  | QDir::AllDirs | QDir::Files, QDir::DirsFirst))
+    {
+      if (info.isDir()) {
+        result = removeDir(info.absoluteFilePath());
+      }
+      else {
+        result = QFile::remove(info.absoluteFilePath());
+      }
+
+      if (!result) {
+        return result;
+      }
+    }
+    result = dir.rmdir(dirName);
+  }
+
+  return result;
+}

+ 39 - 17
Libs/PluginFramework/ctkPluginFrameworkUtil_p.h

@@ -24,31 +24,53 @@
 
 #include <QMap>
 #include <QStringList>
+#include <QDir>
 
+class ctkPluginFrameworkContext;
 
 class ctkPluginFrameworkUtil
 {
 public:
 
   /**
-     * Parse strings of format:
-     *
-     *   ENTRY (, ENTRY)*
-     *   ENTRY = key (; key)* (; PARAM)*
-     *   PARAM = attribute '=' value
-     *   PARAM = directive ':=' value
-     *
-     * @param a Attribute being parsed
-     * @param s String to parse
-     * @param single If true, only allow one key per ENTRY
-     * @param unique Only allow unique parameters for each ENTRY.
-     * @param single_entry If true, only allow one ENTRY is allowed.
-     * @return QMap<QString, QString> mapping attributes to values.
-     * @exception std::invalid_argument If syntax error in input string.
-     */
-    static QList<QMap<QString, QStringList> > parseEntries(const QString& a, const QString& s,
-                                               bool single, bool unique, bool single_entry);
+   * Parse strings of format:
+   *
+   *   ENTRY (, ENTRY)*
+   *   ENTRY = key (; key)* (; PARAM)*
+   *   PARAM = attribute '=' value
+   *   PARAM = directive ':=' value
+   *
+   * @param a Attribute being parsed
+   * @param s String to parse
+   * @param single If true, only allow one key per ENTRY
+   * @param unique Only allow unique parameters for each ENTRY.
+   * @param single_entry If true, only allow one ENTRY is allowed.
+   * @return QMap<QString, QString> mapping attributes to values.
+   * @exception std::invalid_argument If syntax error in input string.
+   */
+  static QList<QMap<QString, QStringList> > parseEntries(const QString& a, const QString& s,
+                                                         bool single, bool unique, bool single_entry);
 
+  static QString getFrameworkDir(ctkPluginFrameworkContext* ctx);
+
+  /**
+   * Check for local file storage directory.
+   *
+   * @param name local directory name.
+   * @return A QDir object pointing to the directory. The directory is
+   *         guaranteed to exist.
+   * @throws std::runtime_error if there is no global framework storage
+   *         directory or if the directory could not be created.
+   */
+  static QDir getFileStorage(ctkPluginFrameworkContext* ctx, const QString& name);
+
+  /**
+   * Remove a non-empty directory.
+   *
+   * @param dirName The directory to remove
+   * @returns <code>true</code> on success, <code>false</code> otherwise.
+   */
+  static bool removeDir(const QString& dirName);
 };
 
 #endif // CTKPLUGINFRAMEWORKUTIL_P_H

+ 4 - 5
Libs/PluginFramework/ctkPluginStorage.cpp

@@ -29,18 +29,17 @@
 // CTK includes
 #include "ctkPluginArchive_p.h"
 #include "ctkPluginFrameworkContext_p.h"
+#include "ctkPluginFrameworkUtil_p.h"
 #include "ctkPluginDatabaseException.h"
 
 
   ctkPluginStorage::ctkPluginStorage(ctkPluginFrameworkContext* framework)
     : framework(framework), pluginDatabase(this)
   {
-//    // See if we have a storage database
-//    bundlesDir = Util.getFileStorage(framework, "bs");
-//    if (bundlesDir == null) {
-//      throw RuntimeException("No plugin storage area available!");
-//    }
+    // See if we have a storage database
+    QString path = ctkPluginFrameworkUtil::getFileStorage(framework, "").absoluteFilePath("plugins.db");
 
+    pluginDatabase.setDatabasePath(path);
     pluginDatabase.open();
     archives << pluginDatabase.getPluginArchives();
   }