瀏覽代碼

Added findResources method and fixed resource API bugs.

Sascha Zelzer 14 年之前
父節點
當前提交
ddcae6da4d

+ 8 - 0
Libs/PluginFramework/ctkPlugin.cpp

@@ -335,6 +335,14 @@ QStringList ctkPlugin::getResourceList(const QString& path) const
 }
 
 //----------------------------------------------------------------------------
+QStringList ctkPlugin::findResources(const QString& path,
+                                     const QString& pattern, bool recurse) const
+{
+  Q_D(const ctkPlugin);
+  return d->findResourceEntries(path, pattern, recurse);
+}
+
+//----------------------------------------------------------------------------
 QByteArray ctkPlugin::getResource(const QString& path) const
 {
   Q_D(const ctkPlugin);

+ 41 - 0
Libs/PluginFramework/ctkPlugin.h

@@ -622,6 +622,47 @@ public:
   virtual QStringList getResourceList(const QString& path) const;
 
   /**
+   * Returns a list of resources in this plugin.
+   *
+   * <p>
+   * This method is intended to be used to obtain configuration, setup,
+   * localization and other information from this plugin. This method can
+   * either return only entries in the specified path or recurse into
+   * subdirectories returning entries in the directory tree beginning at the
+   * specified path.
+   *
+   * <p>
+   * Examples:
+   *
+   * \code
+   * // List all XML files in the OSGI-INF directory and below
+   * QStringList r = b->findResources(&quot;OSGI-INF&quot;, &quot;*.xml&quot;, true);
+   *
+   * // Find a specific localization file
+   * QStringList r = b->findResources(&quot;OSGI-INF/l10n&quot;, &quot;plugin_nl_DU.tm&quot;, false);
+   * \endcode
+   *
+   * @param path The path name in which to look. The path is always relative
+   *        to the root of this plugin and may begin with &quot;/&quot;. A
+   *        path value of &quot;/&quot; indicates the root of this plugin.
+   * @param filePattern The file name pattern for selecting entries in the
+   *        specified path. The pattern is only matched against the last
+   *        element of the entry path. Substring matching is supported, as
+   *        specified in the Filter specification, using the wildcard
+   *        character (&quot;*&quot;). If a null QString is specified, this
+   *        is equivalent to &quot;*&quot; and matches all files.
+   * @param recurse If <code>true</code>, recurse into subdirectories.
+   *        Otherwise only return entries from the specified path.
+   * @return A list of QString objects for each matching entry, or
+   *         an empty list if an entry could not be found or if the caller
+   *         does not have the appropriate
+   *         <code>AdminPermission[this,RESOURCE]</code>, and the Plugin
+   *         Framework supports permissions.
+   * @throws std::logic_error If this plugin has been uninstalled.
+   */
+  virtual QStringList findResources(const QString& path, const QString& filePattern, bool recurse) const;
+
+  /**
    * Returns a QByteArray containing a Qt resource located at the
    * specified path in this plugin.
    * <p>

+ 10 - 8
Libs/PluginFramework/ctkPluginDatabase.cpp

@@ -360,7 +360,7 @@ ctkPluginArchive* ctkPluginDatabase::insertPlugin(const QUrl& location, const QS
   try
   {
     ctkPluginArchive* archive = new ctkPluginArchive(m_PluginStorage, location, localPath,
-                                               pluginId);;
+                                                     pluginId);
 
     statement = "UPDATE Plugins SET SymbolicName=?,Version=? WHERE ID=?";
     QString versionString = archive->getAttribute(ctkPluginConstants::PLUGIN_VERSION);
@@ -453,20 +453,22 @@ QStringList ctkPluginDatabase::findResourcesPath(long pluginId, const QString& p
 
   executeQuery(&query, statement, bindValues);
 
-  QStringList paths;
+  QSet<QString> paths;
   while (query.next())
   {
     QString currPath = query.value(EBindIndex).toString();
-    int slashIndex = currPath.indexOf('/');
-    if (slashIndex > 0)
+    QStringList components = currPath.split('/', QString::SkipEmptyParts);
+    if (components.size() == 1)
     {
-      currPath = currPath.left(slashIndex+1);
+      paths << components.front();
+    }
+    else if (components.size() == 2)
+    {
+      paths << components.front() + "/";
     }
-
-    paths << currPath;
   }
 
-  return paths;
+  return paths.toList();
 }
 
 //----------------------------------------------------------------------------

+ 38 - 0
Libs/PluginFramework/ctkPluginFrameworkUtil.cpp

@@ -397,3 +397,41 @@ bool ctkPluginFrameworkUtil::removeDir(const QString& dirName)
 
   return result;
 }
+
+//----------------------------------------------------------------------------
+bool ctkPluginFrameworkUtil::filterMatch(const QString& filter, const QString& s)
+{
+  return patSubstr(s, 0, filter, 0);
+}
+
+bool ctkPluginFrameworkUtil::patSubstr(const QString& s, int si, const QString& pat, int pi)
+{
+  if (pat.length() - pi == 0)
+  {
+    return s.length() - si == 0;
+  }
+  if (pat[pi] == '*')
+  {
+    pi++;
+    for (;;)
+    {
+      if (patSubstr(s, si, pat, pi))
+        return true;
+      if (s.length() - si == 0)
+        return false;
+      si++;
+    }
+  }
+  else
+  {
+    if (s.length() - si==0)
+    {
+      return false;
+    }
+    if(s[si] != pat[pi])
+    {
+      return false;
+    }
+    return patSubstr(s, ++si, pat, ++pi);
+  }
+}

+ 12 - 0
Libs/PluginFramework/ctkPluginFrameworkUtil_p.h

@@ -74,6 +74,18 @@ public:
    * @returns <code>true</code> on success, <code>false</code> otherwise.
    */
   static bool removeDir(const QString& dirName);
+
+  /**
+   * Check wildcard filter matches the string
+   */
+  static bool filterMatch(const QString& filter, const QString& s);
+
+private:
+
+  /**
+   *
+   */
+  static bool patSubstr(const QString& s, int si, const QString& pat, int pi);
 };
 
 #endif // CTKPLUGINFRAMEWORKUTIL_P_H

+ 28 - 0
Libs/PluginFramework/ctkPluginPrivate.cpp

@@ -345,6 +345,34 @@ void ctkPluginPrivate::stop0(bool wasStarted)
 }
 
 //----------------------------------------------------------------------------
+QStringList ctkPluginPrivate::findResourceEntries(const QString& path,
+                                                  const QString& pattern, bool recurse) const
+{
+  QStringList result;
+  QStringList resources = archive->findResourcesPath(path);
+  foreach(QString fp, resources)
+  {
+    QString lastComponentOfPath = fp.section('/', -1);
+    bool isDirectory = fp.endsWith("/");
+
+    if (!isDirectory &&
+        (pattern.isNull() || ctkPluginFrameworkUtil::filterMatch(pattern, lastComponentOfPath)))
+    {
+      result << (path + fp);
+    }
+    if (isDirectory && recurse)
+    {
+      QStringList subResources = findResourceEntries(fp, pattern, recurse);
+      foreach (QString subResource, subResources)
+      {
+        result << (path + subResource);
+      }
+    }
+  }
+  return result;
+}
+
+//----------------------------------------------------------------------------
 void ctkPluginPrivate::startDependencies()
 {
   QListIterator<ctkRequirePlugin*> i(this->require);

+ 6 - 0
Libs/PluginFramework/ctkPluginPrivate_p.h

@@ -115,6 +115,12 @@ public:
   void stop0(bool wasStarted);
 
   /**
+   *
+   */
+  QStringList findResourceEntries(const QString& path,
+                                  const QString& pattern, bool recurse) const;
+
+  /**
    * Union of flags allowing plugin class access
    */
   static const ctkPlugin::States RESOLVED_FLAGS;