浏览代码

Refactored Plugin Framework exception classes.

Sascha Zelzer 14 年之前
父节点
当前提交
b30e7e0081

+ 1 - 0
Applications/ctkExampleHostedApp/ctkExampleHostedAppMain.cpp

@@ -35,6 +35,7 @@
 #include <QWidget>
 #include <QFileInfo>
 #include <QUrl>
+#include <QDebug>
 
 void print_usage()
 {

+ 1 - 0
Applications/ctkPluginGenerator/ctkPluginGeneratorMain.cpp

@@ -31,6 +31,7 @@
 #include <QSettings>
 #include <QDirIterator>
 #include <QInputDialog>
+#include <QDebug>
 
 int main(int argv, char** argc)
 {

+ 1 - 0
Libs/PluginFramework/CMakeLists.txt

@@ -52,6 +52,7 @@ SET(KIT_SRCS
   ctkPluginTrackerPrivate.tpp
   ctkRequirePlugin.cpp
   ctkRequirePlugin_p.h
+  ctkRuntimeException.cpp
   ctkServiceEvent.cpp
   ctkServiceException.cpp
   ctkServiceFactory.h

+ 140 - 0
Libs/PluginFramework/Testing/Cpp/ctkPluginFrameworkTestMain.cpp

@@ -0,0 +1,140 @@
+/*=============================================================================
+
+  Library: CTK
+
+  Copyright (c) 2010 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 <QCoreApplication>
+#include <QDirIterator>
+#include <QTest>
+#include <QThread>
+#include <QDebug>
+
+#include <ctkPluginContext.h>
+#include <ctkPluginConstants.h>
+#include <ctkPluginFrameworkFactory.h>
+#include <ctkPluginFramework.h>
+#include <ctkPluginException.h>
+#include <ctkServiceReference.h>
+
+#include "ctkTestSuiteInterface.h"
+
+class TestRunner : public QThread
+{
+public:
+
+  TestRunner(ctkPluginContext* context, long testPluginId, int argc, char** argv)
+    : context(context), testPluginId(testPluginId), argc(argc), argv(argv)
+  {
+
+  }
+
+  void run()
+  {
+    // start the main test plugin which registers the test suites (QObject classes)
+    QSharedPointer<ctkPlugin> fwTest = context->getPlugin(testPluginId);
+    fwTest->start();
+
+    QList<ctkServiceReference> refs = context->getServiceReferences<ctkTestSuiteInterface>();
+
+    int result = 0;
+    foreach(ctkServiceReference ref, refs)
+    {
+      result += QTest::qExec(context->getService(ref), argc, argv);
+      if (result > 0) break;
+    }
+
+    if (result > 0) QCoreApplication::exit(result);
+  }
+
+private:
+
+  ctkPluginContext* context;
+  long testPluginId;
+  int argc;
+  char** argv;
+};
+
+int main(int argc, char** argv)
+{
+  QCoreApplication app(argc, argv);
+
+  app.setOrganizationName("CTK");
+  app.setOrganizationDomain("commontk.org");
+  app.setApplicationName("ctkPluginFrameworkCppTests");
+
+  QString pluginDir;
+#ifdef CMAKE_INTDIR
+  pluginDir = qApp->applicationDirPath() + "/../test_plugins/" CMAKE_INTDIR "/";
+#else
+  pluginDir = qApp->applicationDirPath() + "/test_plugins/";
+#endif
+
+  QApplication::addLibraryPath(pluginDir);
+
+  ctkProperties fwProps;
+  fwProps.insert(ctkPluginConstants::FRAMEWORK_STORAGE_CLEAN, ctkPluginConstants::FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT);
+  fwProps.insert("pluginfw.testDir", pluginDir);
+  ctkPluginFrameworkFactory fwFactory(fwProps);
+  QSharedPointer<ctkPluginFramework> framework = fwFactory.getFramework();
+  framework->start();
+
+  ctkPluginContext* context = framework->getPluginContext();
+
+  long fwTestPluginId = -1;
+  QStringList libFilter;
+  libFilter << "*.dll" << "*.so" << "*.dylib";
+  QDirIterator dirIter(pluginDir, libFilter, QDir::Files);
+  while(dirIter.hasNext())
+  {
+    dirIter.next();
+    if (dirIter.fileName().contains("org_commontk_pluginfwtest"))
+    {
+      try
+      {
+        fwTestPluginId = context->installPlugin(QUrl::fromLocalFile(dirIter.filePath()).toString())->getPluginId();
+        break;
+      }
+      catch (const ctkPluginException& e)
+      {
+        qCritical() << e.what();
+      }
+    }
+  }
+
+  if (fwTestPluginId < 0)
+  {
+    qCritical() << "Could not find the plugin framework test plugin: org.commontk.pluginfwtest";
+  }
+
+//  QList<ctkServiceReference> refs = context->getServiceReferences("ctkTestSuiteInterface");
+
+//  int result = 0;
+//  foreach(ctkServiceReference ref, refs)
+//  {
+//    result = QTest::qExec(context->getService(ref), argc, argv);
+//  }
+
+//  return result;
+
+  TestRunner runner(context, fwTestPluginId, argc, argv);
+  runner.connect(&runner, SIGNAL(finished()), &app, SLOT(quit()));
+  runner.start();
+
+  return app.exec();
+}

+ 8 - 35
Libs/PluginFramework/ctkPluginException.cpp

@@ -21,68 +21,41 @@
 
 #include "ctkPluginException.h"
 
+#include <QDebug>
+
 
 ctkPluginException::ctkPluginException(const QString& msg, const Type& type, const std::exception* cause)
-  : std::runtime_error(msg.toStdString()),
+  : ctkRuntimeException(msg, cause),
     type(type)
 {
-  if (cause)
-  {
-    this->cause = QString(cause->what());
-  }
+
 }
 
 ctkPluginException::ctkPluginException(const QString& msg, const std::exception* cause)
-  : std::runtime_error(msg.toStdString()),
+  : ctkRuntimeException(msg, cause),
     type(UNSPECIFIED)
 {
-  if (cause)
-  {
-    this->cause = QString(cause->what());
-  }
+
 }
 
 ctkPluginException::ctkPluginException(const ctkPluginException& o)
-  : std::runtime_error(o.what()), type(o.type), cause(o.cause)
+  : ctkRuntimeException(o), type(o.type)
 {
 
 }
 
 ctkPluginException& ctkPluginException::operator=(const ctkPluginException& o)
 {
-  std::runtime_error::operator=(o);
+  ctkRuntimeException::operator=(o);
   type = o.type;
-  cause = o.cause;
   return *this;
 }
 
-QString ctkPluginException::getCause() const
-{
-  return cause;
-}
-
-void ctkPluginException::setCause(const QString& cause) throw(std::logic_error)
-{
-  if (!this->cause.isEmpty()) throw std::logic_error("The cause for this ctkPluginException instance is already set");
-
-  this->cause = cause;
-}
-
 ctkPluginException::Type ctkPluginException::getType() const
 {
   return type;
 }
 
-const char* ctkPluginException::what() const throw()
-{
-  static std::string fullMsg;
-  fullMsg = std::string(std::runtime_error::what());
-  QString causeMsg = getCause();
-  if (!causeMsg.isEmpty()) fullMsg += std::string("\n  Caused by: ") + causeMsg.toStdString();
-
-  return fullMsg.c_str();
-}
-
 
 QDebug operator<<(QDebug dbg, const ctkPluginException& exc)
 {

+ 51 - 18
Libs/PluginFramework/ctkPluginException.h

@@ -22,15 +22,22 @@
 #ifndef CTKPLUGINEXCEPTION_H
 #define CTKPLUGINEXCEPTION_H
 
-#include <stdexcept>
-
-#include <QString>
-#include <QDebug>
-
-#include "ctkPluginFrameworkExport.h"
-
-
-class CTK_PLUGINFW_EXPORT ctkPluginException : public std::runtime_error
+#include "ctkRuntimeException.h"
+
+/**
+ * A Plugin Framework exception used to indicate that a plugin lifecycle
+ * problem occurred.
+ *
+ * <p>
+ * A {@code ctkPluginException} object is created by the Framework to denote
+ * an exception condition in the lifecycle of a plugin.
+ * {@code ctkPluginException}s should not be created by plugin developers.
+ * An enum type is used to identify the exception type for future extendability.
+ *
+ * <p>
+ * This exception conforms to the general purpose exception chaining mechanism.
+ */
+class CTK_PLUGINFW_EXPORT ctkPluginException : public ctkRuntimeException
 {
 public:
 
@@ -71,28 +78,54 @@ public:
      * The install or update operation failed because another
      * already installed plugin has the same symbolic name and version.
      */
-    DUPLICATE_BUNDLE_ERROR
+    DUPLICATE_PLUGIN_ERROR,
+    /**
+     * The framework received an error while reading the input stream for a plugin.
+     */
+    READ_ERROR,
+    /**
+     * The start transient operation failed because the start level of the
+     * plugin is greater than the current framework start level
+     */
+    START_TRANSIENT_ERROR
   };
 
+  /**
+   * Creates a {@code ctkPluginException} with the specified message, type
+   * and exception cause.
+   *
+   * @param msg The associated message.
+   * @param type The type for this exception.
+   * @param cause The cause of this exception.
+   */
   ctkPluginException(const QString& msg, const Type& type = UNSPECIFIED, const std::exception* cause = 0);
+
+  /**
+   * Creates a {@code ctkPluginException} with the specified message and
+   * exception cause.
+   *
+   * @param msg The associated message.
+   * @param cause The cause of this exception.
+   */
   ctkPluginException(const QString& msg, const std::exception* cause);
 
   ctkPluginException(const ctkPluginException& o);
   ctkPluginException& operator=(const ctkPluginException& o);
 
-  ~ctkPluginException() throw() {}
-
-  QString getCause() const;
-  void setCause(const QString&) throw(std::logic_error);
+  /**
+   * Returns the type for this exception or {@code UNSPECIFIED} if the
+   * type was unspecified or unknown.
+   *
+   * @return The type of this exception.
+   */
   Type getType() const;
 
-  const char* what() const throw();
-
-
 private:
 
+  /**
+   * Type of plugin exception.
+   */
   Type type;
-  QString cause;
 
 };
 

+ 67 - 0
Libs/PluginFramework/ctkRuntimeException.cpp

@@ -0,0 +1,67 @@
+/*=============================================================================
+
+  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 "ctkRuntimeException.h"
+
+ctkRuntimeException::ctkRuntimeException(const QString& msg, const std::exception* cause)
+  : std::runtime_error(msg.toStdString())
+{
+  if (cause)
+  {
+    this->cause = QString(cause->what());
+  }
+}
+
+ctkRuntimeException::ctkRuntimeException(const ctkRuntimeException& o)
+  : std::runtime_error(o.what()), cause(o.cause)
+{
+
+}
+
+ctkRuntimeException& ctkRuntimeException::operator=(const ctkRuntimeException& o)
+{
+  std::runtime_error::operator=(o);
+  cause = o.cause;
+  return *this;
+}
+
+QString ctkRuntimeException::getCause() const
+{
+  return cause;
+}
+
+void ctkRuntimeException::setCause(const QString& cause) throw(std::logic_error)
+{
+  if (!this->cause.isEmpty()) throw std::logic_error("The cause for this ctkServiceException instance is already set");
+
+  this->cause = cause;
+}
+
+const char* ctkRuntimeException::what() const throw()
+{
+  static std::string fullMsg;
+  fullMsg = std::string(std::runtime_error::what());
+  QString causeMsg = getCause();
+  if (!causeMsg.isEmpty()) fullMsg += std::string("\n  Caused by: ") + causeMsg.toStdString();
+
+  return fullMsg.c_str();
+}

+ 53 - 0
Libs/PluginFramework/ctkRuntimeException.h

@@ -0,0 +1,53 @@
+/*=============================================================================
+
+  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.
+
+=============================================================================*/
+
+
+#ifndef CTKRUNTIMEEXCEPTION_H
+#define CTKRUNTIMEEXCEPTION_H
+
+#include <stdexcept>
+
+#include <QString>
+
+#include "ctkPluginFrameworkExport.h"
+
+class CTK_PLUGINFW_EXPORT ctkRuntimeException : public std::runtime_error
+{
+public:
+
+  ctkRuntimeException(const QString& msg, const std::exception* cause = 0);
+  ctkRuntimeException(const ctkRuntimeException& o);
+
+  ctkRuntimeException& operator=(const ctkRuntimeException& o);
+
+  ~ctkRuntimeException() throw() {}
+
+  QString getCause() const;
+  void setCause(const QString& cause) throw(std::logic_error);
+
+  const char* what() const throw();
+
+private:
+
+  QString  cause;
+};
+
+#endif // CTKRUNTIMEEXCEPTION_H

+ 6 - 34
Libs/PluginFramework/ctkServiceException.cpp

@@ -25,65 +25,37 @@
 
 
 ctkServiceException::ctkServiceException(const QString& msg, const Type& type, const std::exception* cause)
-  : std::runtime_error(msg.toStdString()),
+  : ctkRuntimeException(msg, cause),
     type(type)
 {
-  if (cause)
-  {
-    this->cause = QString(cause->what());
-  }
+
 }
 
 ctkServiceException::ctkServiceException(const QString& msg, const std::exception* cause)
-  : std::runtime_error(msg.toStdString()),
+  : ctkRuntimeException(msg, cause),
     type(UNSPECIFIED)
 {
-  if (cause)
-  {
-    this->cause = QString(cause->what());
-  }
+
 }
 
 ctkServiceException::ctkServiceException(const ctkServiceException& o)
-  : std::runtime_error(o.what()), type(o.type), cause(o.cause)
+  : ctkRuntimeException(o), type(o.type)
 {
 
 }
 
 ctkServiceException& ctkServiceException::operator=(const ctkServiceException& o)
 {
-  std::runtime_error::operator=(o);
+  ctkRuntimeException::operator=(o);
   type = o.type;
-  cause = o.cause;
   return *this;
 }
 
-QString ctkServiceException::getCause() const
-{
-  return cause;
-}
-
-void ctkServiceException::setCause(const QString& cause) throw(std::logic_error)
-{
-  if (!this->cause.isEmpty()) throw std::logic_error("The cause for this ctkServiceException instance is already set");
-
-  this->cause = cause;
-}
-
 ctkServiceException::Type ctkServiceException::getType() const
 {
   return type;
 }
 
-const char* ctkServiceException::what() const throw()
-{
-  static std::string fullMsg;
-  fullMsg = std::string(std::runtime_error::what());
-  QString causeMsg = getCause();
-  if (!causeMsg.isEmpty()) fullMsg += std::string("\n  Caused by: ") + causeMsg.toStdString();
-
-  return fullMsg.c_str();
-}
 
 QDebug operator<<(QDebug dbg, const ctkServiceException& exc)
 {

+ 49 - 23
Libs/PluginFramework/ctkServiceException.h

@@ -23,14 +23,20 @@
 #ifndef CTKSERVICEEXCEPTION_H
 #define CTKSERVICEEXCEPTION_H
 
-#include <stdexcept>
-
-#include <QString>
-
-#include "ctkPluginFrameworkExport.h"
-
-
-class CTK_PLUGINFW_EXPORT ctkServiceException : public std::runtime_error
+#include "ctkRuntimeException.h"
+
+/**
+ * A service exception used to indicate that a service problem occurred.
+ *
+ * <p>
+ * A {@code ctkServiceException} object is created by the Framework or
+ * to denote an exception condition in the service. An enum
+ * type is used to identify the exception type for future extendability.
+ *
+ * <p>
+ * This exception conforms to the general purpose exception chaining mechanism.
+ */
+class CTK_PLUGINFW_EXPORT ctkServiceException : public ctkRuntimeException
 {
 public:
 
@@ -38,48 +44,68 @@ public:
     /**
      * No exception type is unspecified.
      */
-    UNSPECIFIED			= 0,
+    UNSPECIFIED = 0,
     /**
      * The service has been unregistered.
      */
-    UNREGISTERED		= 1,
+    UNREGISTERED = 1,
     /**
      * The service factory produced an invalid service object.
      */
-    FACTORY_ERROR		= 2,
+    FACTORY_ERROR = 2,
     /**
      * The service factory threw an exception.
      */
-    FACTORY_EXCEPTION	= 3,
+    FACTORY_EXCEPTION = 3,
     /**
-     * The exception is a subclass of ctkServiceException. The subclass should be
-     * examined for the type of the exception.
+     * An error occurred invoking a remote service.
      */
-    SUBCLASSED			= 4,
+    REMOTE = 5,
     /**
-     * An error occurred invoking a remote service.
+     * The service factory resulted in a recursive call to itself for the
+     * requesting plugin.
      */
-    REMOTE 				= 5
+    FACTORY_RECURSION = 6
   };
 
+  /**
+   * Creates a {@code ctkServiceException} with the specified message,
+   * type and exception cause.
+   *
+   * @param msg The associated message.
+   * @param type The type for this exception.
+   * @param cause The cause of this exception.
+   */
   ctkServiceException(const QString& msg, const Type& type = UNSPECIFIED, const std::exception* cause = 0);
+
+  /**
+   * Creates a {@code ctkServiceException} with the specified message and
+   * exception cause.
+   *
+   * @param msg The associated message.
+   * @param cause The cause of this exception.
+   */
   ctkServiceException(const QString& msg, const std::exception* cause);
 
   ctkServiceException(const ctkServiceException& o);
   ctkServiceException& operator=(const ctkServiceException& o);
 
-  ~ctkServiceException() throw() {}
+  ~ctkServiceException() throw() { }
 
-  QString getCause() const;
-  void setCause(const QString&) throw(std::logic_error);
+  /**
+   * Returns the type for this exception or {@code UNSPECIFIED} if the
+   * type was unspecified or unknown.
+   *
+   * @return The type of this exception.
+   */
   Type getType() const;
 
-  const char* what() const throw();
-
 private:
 
+  /**
+   * Type of service exception.
+   */
   Type type;
-  QString cause;
 
 };
 

+ 1 - 0
Libs/PluginFramework/ctkServiceReference.cpp

@@ -27,6 +27,7 @@
 
 #include <QStringList>
 #include <QMutexLocker>
+#include <QDebug>
 
 ctkServiceReference::ctkServiceReference()
   : d_ptr(new ctkServiceReferencePrivate(0))