Browse Source

FactoryItem - Improve management of error and warning strings

* Overloaded factoryItem can now "output" custom error or warning string using
method "appendInstantiateErrorString" or "appendInstantiateWarningString"

* Doing so ensure that the messages are displayed, indented and formatted
appropriately.
Jean-Christophe Fillion-Robin 13 years ago
parent
commit
a0db420fc9

+ 14 - 3
Libs/Core/ctkAbstractFactory.h

@@ -48,6 +48,9 @@ public:
   virtual QString loadErrorString()const;
   virtual bool load() = 0;
 
+  QStringList instantiateErrorStrings()const;
+  QStringList instantiateWarningStrings()const;
+
   BaseClassType* instantiate();
   bool instantiated()const;
   virtual void uninstantiate();
@@ -56,11 +59,20 @@ public:
   bool verbose()const;
 
 protected:
+
+  void appendInstantiateErrorString(const QString& msg);
+  void clearInstantiateErrorStrings();
+
+  void appendInstantiateWarningString(const QString& msg);
+  void clearInstantiateWarningStrings();
+
   /// Must be reimplemented in subclasses to instanciate a BaseClassType*
   virtual BaseClassType* instanciator() = 0;
   BaseClassType* Instance;
 
 private:
+  QStringList InstantiateErrorStrings;
+  QStringList InstantiateWarningStrings;
   bool Verbose;
 };
 
@@ -113,8 +125,8 @@ public:
 
 protected:
 
-  void displayRegistrationStatus(QtMsgType type, const QString& description,
-                                 const QString& status, bool display);
+  void displayStatusMessage(const QtMsgType& type, const QString& description,
+                            const QString& status, bool display);
 
   /// \brief Call the load method associated with the item.
   /// If succesfully loaded, add it to the internal map.
@@ -136,7 +148,6 @@ private:
   HashType RegisteredItemMap;
   QSharedPointer<HashType> SharedRegisteredItemMap;
 
-
   bool Verbose;
 };
 

+ 94 - 17
Libs/Core/ctkAbstractFactory.tpp

@@ -46,9 +46,53 @@ QString ctkAbstractFactoryItem<BaseClassType>::loadErrorString()const
 }
 
 //----------------------------------------------------------------------------
+template<typename BaseClassType>
+QStringList ctkAbstractFactoryItem<BaseClassType>::instantiateErrorStrings()const
+{
+  return this->InstantiateErrorStrings;
+}
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+void ctkAbstractFactoryItem<BaseClassType>::appendInstantiateErrorString(const QString& errorString)
+{
+  this->InstantiateErrorStrings << errorString;
+}
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+void ctkAbstractFactoryItem<BaseClassType>::clearInstantiateErrorStrings()
+{
+  this->InstantiateErrorStrings.clear();
+}
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+QStringList ctkAbstractFactoryItem<BaseClassType>::instantiateWarningStrings()const
+{
+  return this->InstantiateWarningStrings;
+}
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+void ctkAbstractFactoryItem<BaseClassType>::appendInstantiateWarningString(const QString& msg)
+{
+  this->InstantiateWarningStrings << msg;
+}
+
+//----------------------------------------------------------------------------
+template<typename BaseClassType>
+void ctkAbstractFactoryItem<BaseClassType>::clearInstantiateWarningStrings()
+{
+  this->InstantiateWarningStrings.clear();
+}
+
+//----------------------------------------------------------------------------
 template<typename BaseClassType>  
 BaseClassType* ctkAbstractFactoryItem<BaseClassType>::instantiate()
 {
+  this->clearInstantiateErrorStrings();
+  this->clearInstantiateWarningStrings();
   if (this->Instance)
     {
     return this->Instance;
@@ -122,7 +166,37 @@ template<typename BaseClassType>
 BaseClassType* ctkAbstractFactory<BaseClassType>::instantiate(const QString& itemKey)
 {
   ctkAbstractFactoryItem<BaseClassType>* _item = this->item(itemKey);
-  return (_item ? _item->instantiate() : 0);
+  BaseClassType* instance = 0;
+  bool wasInstantiated = false;
+  if (_item)
+    {
+    wasInstantiated = _item->instantiated();
+    instance = _item->instantiate();
+    }
+  if (!wasInstantiated)
+    {
+    this->displayStatusMessage(instance ? QtDebugMsg : QtCriticalMsg,
+                               QString("Attempt to instantiate \"%1\"").arg(itemKey),
+                               instance ? "OK" : "Failed", this->verbose());
+    if (_item)
+      {
+      if(!_item->instantiateErrorStrings().isEmpty())
+        {
+        qCritical().nospace() << qPrintable(QString(" ").repeated(2) + QLatin1String("Error(s):\n"))
+                              << qPrintable(QString(" ").repeated(4) +
+                                            _item->instantiateErrorStrings().join(
+                                              QString("\n") + QString(" ").repeated(4)));
+        }
+      if(!_item->instantiateWarningStrings().isEmpty())
+        {
+        qWarning().nospace() << qPrintable(QString(" ").repeated(2) + QLatin1String("Warning(s):\n"))
+                             << qPrintable(QString(" ").repeated(4) +
+                                           _item->instantiateWarningStrings().join(
+                                             QString("\n") + QString(" ").repeated(4)));
+        }
+      }
+    }
+  return instance;
 }
 
 //----------------------------------------------------------------------------
@@ -163,8 +237,8 @@ QStringList ctkAbstractFactory<BaseClassType>::itemKeys() const
 
 //----------------------------------------------------------------------------
 template<typename BaseClassType>
-void ctkAbstractFactory<BaseClassType>::displayRegistrationStatus(
-    QtMsgType type, const QString& description, const QString& status, bool display)
+void ctkAbstractFactory<BaseClassType>::displayStatusMessage(
+    const QtMsgType& type, const QString& description, const QString& status, bool display)
 {
   QString msg = QString("%1 [%2]").arg(description + " ", -70, QChar('.')).arg(status);
   if (display)
@@ -193,36 +267,38 @@ bool ctkAbstractFactory<BaseClassType>::registerItem(const QString& key,
   const QSharedPointer<ctkAbstractFactoryItem<BaseClassType> > & _item)
 {
   // Sanity checks
-  if (!_item || key.isEmpty() || this->item(key))
+  if (!_item)
     {
     if (this->verbose())
       {
-      qDebug() << __FUNCTION__ << "key is empty or already exists:"
-               << key << "; item: " << _item;
+      qDebug() << __FUNCTION__ << "key is empty - item: " << _item;
       }
     return false;
     }
 
+  QString description = QString("Attempt to register \"%1\"").arg(key);
+
+  if (this->item(key))
+    {
+    this->displayStatusMessage(QtWarningMsg, description, "Already registered", this->verbose());
+    return false;
+    }
+
   if (this->sharedItem(key))
     {
-    if (this->verbose())
-      {
-      qDebug() << "Item" << key << "has already been registered";
-      }
+    this->displayStatusMessage(QtDebugMsg, description,
+                               "Already registered in other factory", this->verbose());
     return false;
     }
   
   // Attempt to load it
   if (!_item->load())
     {
-    QString errorStr;
-    if (!_item->loadErrorString().isEmpty())
-      {
-      errorStr = " - " + _item->loadErrorString();
-      }
-    if (this->verbose())
+    this->displayStatusMessage(QtCriticalMsg, description, "Failed", this->verbose());
+    if (this->verbose() && !_item->loadErrorString().isEmpty())
       {
-      qCritical() << "Failed to load object:" << key << errorStr ;
+      qCritical().nospace() << qPrintable(QString(" ").repeated(2) + QLatin1String("Error(s):\n"))
+                            << qPrintable(QString(" ").repeated(4) + _item->loadErrorString());
       }
     return false;
     }
@@ -231,6 +307,7 @@ bool ctkAbstractFactory<BaseClassType>::registerItem(const QString& key,
   this->RegisteredItemMap.insert(key, _item);
   this->SharedRegisteredItemMap.data()->insert(key, _item);
 
+  this->displayStatusMessage(QtDebugMsg, description, "OK", this->verbose());
   return true;
 }
 

+ 11 - 15
Libs/Core/ctkAbstractFileBasedFactory.tpp

@@ -100,33 +100,29 @@ bool ctkAbstractFileBasedFactory<BaseClassType>
 ::registerFileItem(const QString& key, const QFileInfo& fileInfo)
 {
   QString description = QString("Attempt to register \"%1\"").arg(key);
-  if(this->sharedItem(key) || this->item(key))
+  if (this->item(key))
     {
-    this->displayRegistrationStatus(QtDebugMsg, description,
-                                    "Already registered", this->verbose());
+    this->displayStatusMessage(QtWarningMsg, description, "Already registered", this->verbose());
+    return false;
+    }
+  if (this->sharedItem(key))
+    {
+    this->displayStatusMessage(QtDebugMsg, description,
+                               "Already registered in other factory", this->verbose());
     return false;
     }
   QSharedPointer<ctkAbstractFactoryItem<BaseClassType> >
     itemToRegister(this->createFactoryFileBasedItem());
   if (itemToRegister.isNull())
     {
-    this->displayRegistrationStatus(QtWarningMsg, description,
-                                    "Failed to create FileBasedItem", this->verbose());
+    this->displayStatusMessage(QtWarningMsg, description,
+                               "Failed to create FileBasedItem", this->verbose());
     return false;
     }
   dynamic_cast<ctkAbstractFactoryFileBasedItem<BaseClassType>*>(itemToRegister.data())
     ->setPath(fileInfo.filePath());
   this->initItem(itemToRegister.data());
-  bool res = this->registerItem(key, itemToRegister);
-  if(res)
-    {
-    this->displayRegistrationStatus(QtDebugMsg, description, "OK", this->verbose());
-    }
-  else
-    {
-    this->displayRegistrationStatus(QtWarningMsg, description, "Failed", this->verbose());
-    }
-  return res;
+  return this->registerItem(key, itemToRegister);
 }
 
 //-----------------------------------------------------------------------------

+ 11 - 14
Libs/Core/ctkAbstractObjectFactory.tpp

@@ -61,26 +61,23 @@ template<typename ClassType>
 bool ctkAbstractObjectFactory<BaseClassType>::registerObject(const QString& key)
 {
   QString description = QString("Attempt to register \"%1\"").arg(key);
-  if(this->sharedItem(key) || this->item(key))
+  if (this->item(key))
     {
-    this->displayRegistrationStatus(QtDebugMsg, description,
-                                    "Already registered", this->verbose());
+    this->displayStatusMessage(QtWarningMsg, description, "Already registered", this->verbose());
+    return false;
+    }
+
+  if (this->sharedItem(key))
+    {
+    this->displayStatusMessage(QtDebugMsg, description,
+                               "Already registered in other factory", this->verbose());
     return false;
     }
   QSharedPointer<ctkFactoryObjectItem<BaseClassType, ClassType> > objectItem =
     QSharedPointer<ctkFactoryObjectItem<BaseClassType, ClassType> >(
-      new ctkFactoryObjectItem<BaseClassType, ClassType>() );
+      new ctkFactoryObjectItem<BaseClassType, ClassType>());
   objectItem->setVerbose(this->verbose());
-  bool res = this->registerItem(key, objectItem);
-  if(res)
-    {
-    this->displayRegistrationStatus(QtDebugMsg, description, "OK", this->verbose());
-    }
-  else
-    {
-    this->displayRegistrationStatus(QtWarningMsg, description, "Failed", this->verbose());
-    }
-  return res;
+  return this->registerItem(key, objectItem);
 }
 
 #endif