From d003f8a9b40b4c0cf4d3a006dd0c794ca524f8d7 Mon Sep 17 00:00:00 2001
From: Cyrille Valladeau <cyrille.valladeau@c-s.fr>
Date: Tue, 29 Nov 2011 15:35:42 +0100
Subject: [PATCH] ENH: improve new DoxExample framework

---
 .../otbWrapperApplication.cxx                 |  17 +-
 .../ApplicationEngine/otbWrapperApplication.h |  39 ++++-
 .../otbWrapperDocExampleStructure.h           | 149 +++++++++++++-----
 .../ApplicationEngine/otbWrapperCoreTests.cxx |   2 +-
 .../otbWrapperDocExampleStructureTest.cxx     |  23 ++-
 5 files changed, 172 insertions(+), 58 deletions(-)

diff --git a/Code/ApplicationEngine/otbWrapperApplication.cxx b/Code/ApplicationEngine/otbWrapperApplication.cxx
index 3cb147c07e..074d375f56 100644
--- a/Code/ApplicationEngine/otbWrapperApplication.cxx
+++ b/Code/ApplicationEngine/otbWrapperApplication.cxx
@@ -47,7 +47,16 @@ namespace Wrapper
 {
 
 Application::Application()
- : m_Logger(itk::Logger::New())
+  : m_Name(""), 
+    m_Description(""), 
+    m_Logger(itk::Logger::New()), 
+    m_ProgressSourceDescription(""), 
+    m_DocName(""), 
+    m_DocLongDescription(""), 
+    m_DocAuthors(""), 
+    m_DocLimitations(""), 
+    m_DocSeeAlso(""), 
+    m_DocTags()
 {
   // Don't call Init from the constructor, since it calls a virtual method !
 
@@ -55,7 +64,9 @@ Application::Application()
   m_Logger->SetPriorityLevel(itk::LoggerBase::DEBUG);
   m_Logger->SetLevelForFlushing(itk::LoggerBase::CRITICAL);
 
-}
+  m_ParameterList = ParameterGroup::New();
+  m_DocExample = DocExampleStructure::New();
+  }
 
 Application::~Application()
 {
@@ -1066,6 +1077,7 @@ void
 Application::AddChoice(std::string paramKey, std::string paramName)
 {
   GetParameterList()->AddChoice(paramKey, paramName);
+  m_DocExample->AddParameter(paramKey, paramName);
 }
 
 void
@@ -1084,6 +1096,7 @@ void
 Application::AddParameter(ParameterType type, std::string paramKey, std::string paramName)
 {
   GetParameterList()->AddParameter(type, paramKey, paramName);
+  m_DocExample->AddParameter(paramKey, paramName);
 }
 
 void Application::AddRAMParameter(std::string paramKey, std::string paramName, unsigned int defaultValue)
diff --git a/Code/ApplicationEngine/otbWrapperApplication.h b/Code/ApplicationEngine/otbWrapperApplication.h
index 9e8ffa0990..af38dc36db 100644
--- a/Code/ApplicationEngine/otbWrapperApplication.h
+++ b/Code/ApplicationEngine/otbWrapperApplication.h
@@ -34,6 +34,8 @@
 #include "otbWrapperComplexInputImageParameter.h"
 #include "otbWrapperComplexOutputImageParameter.h"
 
+#include "otbWrapperDocExampleStructure.h"
+
 namespace otb
 {
 namespace Wrapper
@@ -53,16 +55,19 @@ public:
   typedef itk::SmartPointer<Self>       Pointer;
   typedef itk::SmartPointer<const Self> ConstPointer;
 
-  /** Defining ::New() static method */
-  //itkNewMacro(Self);
-
   /** RTTI support */
   itkTypeMacro(Application, itk::Object);
 
   /** Set the parameter name */
-  itkSetStringMacro(Name);
+  //itkSetStringMacro(Name);
+
+  virtual void SetName( const std::string & name )
+  {
+    m_Name = name;
+    m_DocExample->SetApplicationName(name);
+    this->Modified();
+  }
 
-  /** Get the parameter name */
   itkGetStringMacro(Name);
 
   /** Set the parameter description */
@@ -514,6 +519,26 @@ public:
     this->Modified();
   }
 
+  DocExampleStructure::Pointer GetDocExample()
+  {
+    return m_DocExample;
+  }
+
+  void SetDocExampleParameterValue( const std::string key, const std::string value )
+  {
+    m_DocExample->SetParameterValue( key, value );
+    this->Modified();
+  }
+
+  std::string GetCLExample()
+  {
+    return m_DocExample->GenerateCLExample();
+  }
+  std::string GetQtExample()
+  {
+    return m_DocExample->GenerateQtExample();
+  }
+
   /** Return all parameters which role is Role_Output in a vector of paris that contains the
   * parameter key and its value.
   */
@@ -647,8 +672,10 @@ private:
   std::string m_DocName;
   /** Long and precise application description . */
   std::string                       m_DocLongDescription;
+  /** Doc example structure */
+  DocExampleStructure::Pointer m_DocExample;
   /** Commanline example. Use ${OTB-DATA} for OTB-Data directory
-* path and ${OTB-BIN} for the directory bin of the OTB binary directory. */
+   path and ${OTB-BIN} for the directory bin of the OTB binary directory. */
   std::string m_DocCLExample;
   /** Author List. Format : "John Doe, Winnie the Pooh".*/
   std::string m_DocAuthors;
diff --git a/Code/ApplicationEngine/otbWrapperDocExampleStructure.h b/Code/ApplicationEngine/otbWrapperDocExampleStructure.h
index ae08f9dd3b..2004a7e1f6 100644
--- a/Code/ApplicationEngine/otbWrapperDocExampleStructure.h
+++ b/Code/ApplicationEngine/otbWrapperDocExampleStructure.h
@@ -18,11 +18,16 @@
 #ifndef __otbWrapperDocExampleStructure_h
 #define __otbWrapperDocExampleStructure_h
 
+#include "itkObject.h"
+#include "itkObjectFactory.h"
+
 #include <string>
 #include <iostream>
 #include <vector>
 #include "itkMacro.h"
 #include "otbConfigure.h"
+#include "itkFixedArray.h"
+
 
 namespace otb
 {
@@ -30,95 +35,130 @@ namespace Wrapper
 {
 
 /** \class DocExampleStructure
- *  \brief This class represent a string parameter for the wrapper framework
+ *  \brief This class is a structure that gathered the necessary
+ *  element to generate an example (for CommandLine, python, Java
+ *  ...).
+ * User has to set the application name, the binary path and a list of
+ *  key/value couple.
  */
-class DocExampleStructure
+class DocExampleStructure :
+  public itk::Object
 {
 public:
-  typedef std::pair<std::string, std::string> PairType;
-  typedef std::vector<PairType> ParameterListType;
+  /** Standard class typedefs */
+  typedef DocExampleStructure           Self;
+  typedef itk::Object                   Superclass;
+  typedef itk::SmartPointer<Self>       Pointer;
+  typedef itk::SmartPointer<const Self> ConstPointer;
+
+  /** Standards macros */
+  itkNewMacro(Self);
+
+  /** Runtime information */
+  itkTypeMacro(DocExampleStructure, itk::Object);
 
+  typedef itk::FixedArray<std::string, 3> ThreeStringType;
+  typedef std::vector<ThreeStringType> ParameterListType;
 
-  void AddParameter( const std::string key, const std::string value )
+  /** Parameter list accessors. */
+  /** Parameter list accessors : adding key and name */
+  void AddParameter( const std::string key, const std::string name )
   {
-    PairType myPair;
-    myPair.first = key;
-    myPair.second = value;
-    this->AddParameter( myPair );
+    std::cout<<"DocExampleStructure::AddParameter"<<std::endl;
+    ThreeStringType mParam;
+    mParam[0] = key;
+    mParam[1] = name;
+    mParam[2] = "";
+    m_ParameterList.push_back( mParam );
   }
   
-  void AddParameter( const PairType myPair )
-  {
-    m_ParameterList.push_back( myPair );
-  }
-
-  PairType GetParameter( unsigned int i )
+ void SetParameterValue( const std::string key, const std::string value )
   {
-    if( m_ParameterList.size() <= i )
-      itkGenericExceptionMacro( "Index "<<i<<" out of range. (max index: "<<m_ParameterList.size()<<")." );
+    bool found = false;
+    unsigned int i=0;
+    while ( i<m_ParameterList.size() && !found )
+      {
+      if( this->GetParameterKey(i) == key )
+        {
+        m_ParameterList[i][2] = value;
+        found = true;
+        }
+      i++;
+      }
 
-    return m_ParameterList[i];
+    if( !found)
+      itkGenericExceptionMacro( "No parameter with key "<<key<<" found." );
   }
 
+ /** Get the parameter list. */
   ParameterListType GetParameterList()
   {
     return m_ParameterList;
   }
 
-  std::string GetParameterKey( unsigned int i )
+  /** Get a specific parameter couple.*/
+  ThreeStringType GetParameter( unsigned int i )
   {
-    return this->GetParameter(i).first;
+    if( m_ParameterList.size() <= i )
+      itkGenericExceptionMacro( "Index "<<i<<" out of range. (max index: "<<m_ParameterList.size()<<")." );
+
+    return m_ParameterList[i];
   }
 
-  int GetParameterValueAsInt( unsigned int i )
+  /** Get a specific parameter couple key.*/
+  std::string GetParameterKey( unsigned int i )
   {
-    return atoi(this->GetParameter(i).second.c_str());
+    return this->GetParameter(i)[0];
   }
 
- float GetParameterValueAsFloat( unsigned int i )
+ /** Get a specific parameter couple key.*/
+  std::string GetParameterName( unsigned int i )
   {
-    return  atoi(this->GetParameter(i).second.c_str());
+    return this->GetParameter(i)[1];
   }
 
-  std::string GetParameterValueAsString( unsigned int i )
+  /** Get a specific parameter couple value as string.*/
+  std::string GetParameterValue( unsigned int i )
   {
-    return  this->GetParameter(i).second;
+    return  this->GetParameter(i)[2];
   }
-
+  /** Set Application name. */
   void SetApplicationName( const std::string name )
   {
     m_ApplicationName = name;
   }
-
+  /** Get Application name. */
   std::string GetApplicationName()
   {
     return m_ApplicationName;
   }
-
+  /** Set the list of paths. */
   void SetBinPath( const std::vector<std::string> bPath )
   {
     m_BinPath = bPath;
   }
-  
+    /** Add a path to the list. */
   void AddBinPath( std::string myPath )
   {
     m_BinPath.push_back( myPath );
   }
-
+  /** Get the list of paths. */
   std::vector<std::string> GetBinPath()
   {
     return m_BinPath;
   }
 
+  /** Generation of the documentation for CommandLine. */
   std::string GenerateCLExample()
   {
     if( m_ApplicationName.empty() || m_BinPath.size() == 0 ||  m_ParameterList.size() == 0 )
       {
-      itkGenericExceptionMacro( "Missing attributs to generate the example." );
+      return "";
       }
     
     itk::OStringStream oss;
     oss << OTB_CONFIG << "/bin/otbApplicationLauncherCommandLine ";
+    oss << m_ApplicationName << " ";
     
     for (unsigned int i=0; i< m_BinPath.size(); i++)
       {
@@ -127,7 +167,10 @@ public:
 
     for (unsigned int i=0; i< m_ParameterList.size(); i++)
       {
-      oss << "-" << m_ParameterList[i].first << " " << m_ParameterList[i].second <<" ";
+      if( this->GetParameterValue(i) != "" )
+        {
+        oss<< "-" << this->GetParameterKey(i) << " " << this->GetParameterValue(i) <<" ";
+        }
       }
 
 
@@ -140,23 +183,55 @@ public:
     
   }
 
+  /** Generation of teh documentation for Qt. */
+  std::string GenerateQtExample()
+  {
+    if( m_ApplicationName.empty() || m_BinPath.size() == 0 ||  m_ParameterList.size() == 0 )
+      {
+      return "";
+      }
+
+    itk::OStringStream oss;
+    for (unsigned int i=0; i< m_ParameterList.size(); i++)
+      {
+      if( this->GetParameterValue(i) != "" )
+        {
+        oss << this->GetParameterName(i) << ": " << this->GetParameterValue(i) << "<br />";
+        }
+      }
+
+
+    std::string res = oss.str();
+
+    return res;
+    
+  }
+
+
+protected:
   /** Constructor */
   DocExampleStructure()
-  {}
+  {
+    itk::OStringStream oss;
+    oss << OTB_CONFIG << "/bin";
+    m_BinPath.push_back( oss.str() );
+  }
 
   /** Destructor */
   virtual ~DocExampleStructure()
   {}
 
-protected:
-
-
 private:
   DocExampleStructure(const DocExampleStructure &); //purposely not implemented
   void operator =(const DocExampleStructure&); //purposely not implemented
 
+  /** List of the application parameters. List of key/value couples. */
   ParameterListType m_ParameterList;
+  /** List of the application parameter names. List of key/name couples. */
+  ParameterListType m_ParameterNameList;
+  /** application name */
   std::string m_ApplicationName;
+  /** paths where to the application. */
   std::vector<std::string> m_BinPath;
 
 
diff --git a/Testing/Code/ApplicationEngine/otbWrapperCoreTests.cxx b/Testing/Code/ApplicationEngine/otbWrapperCoreTests.cxx
index a44321347a..fb013b1c75 100644
--- a/Testing/Code/ApplicationEngine/otbWrapperCoreTests.cxx
+++ b/Testing/Code/ApplicationEngine/otbWrapperCoreTests.cxx
@@ -53,7 +53,7 @@ void RegisterTests()
   REGISTER_TEST(otbWrapperRAMParameterNew);
   REGISTER_TEST(otbWrapperApplicationHtmlDocGeneratorNew);
   REGISTER_TEST(otbWrapperApplicationHtmlDocGeneratorTest1);
-  REGISTER_TEST(otbWrapperDocExampleStructure);
+  REGISTER_TEST(otbWrapperDocExampleStructureNew);
   REGISTER_TEST(otbWrapperDocExampleStructureTest);
 }
 
diff --git a/Testing/Code/ApplicationEngine/otbWrapperDocExampleStructureTest.cxx b/Testing/Code/ApplicationEngine/otbWrapperDocExampleStructureTest.cxx
index e7d0d7c198..04ffbfe30a 100644
--- a/Testing/Code/ApplicationEngine/otbWrapperDocExampleStructureTest.cxx
+++ b/Testing/Code/ApplicationEngine/otbWrapperDocExampleStructureTest.cxx
@@ -22,10 +22,10 @@
 #include "otbWrapperDocExampleStructure.h"
 #include "itksys/SystemTools.hxx"
 
-int otbWrapperDocExampleStructure(int argc, char* argv[])
+int otbWrapperDocExampleStructureNew(int argc, char* argv[])
 {
   typedef otb::Wrapper::DocExampleStructure DocExampleStructureType;
-  DocExampleStructureType docStruct;
+  DocExampleStructureType::Pointer docStruct = DocExampleStructureType::New();
 
   return EXIT_SUCCESS;
 }
@@ -34,24 +34,23 @@ int otbWrapperDocExampleStructure(int argc, char* argv[])
 int otbWrapperDocExampleStructureTest(int argc, char* argv[])
 {
   typedef otb::Wrapper::DocExampleStructure DocExampleStructureType;
-  DocExampleStructureType docStruct;
+  DocExampleStructureType::Pointer docStruct = DocExampleStructureType::New();
   
-  docStruct.SetApplicationName("TestApplication");
+  docStruct->SetApplicationName("TestApplication");
   
   std::vector<std::string> bPath;
   bPath.push_back("binPath1");
 
-  docStruct.SetBinPath(bPath);
-  docStruct.AddBinPath("binPath2");
+  docStruct->SetBinPath(bPath);
+  docStruct->AddBinPath("binPath2");
   
-  DocExampleStructureType::PairType mPair;
-  mPair.first = "key1";
-  mPair.second = "val1";
-  docStruct.AddParameter( mPair );
+  docStruct->AddParameter( "key1", "name1" );
+  docStruct->AddParameter( "key2", "name2" );
 
-  docStruct.AddParameter( "key2", "val2" );
+  docStruct->SetParameterValue( "key1", "val1" );
+  docStruct->SetParameterValue( "key2", "val2" );
 
-  std::string exp = docStruct.GenerateCLExample();
+  std::string exp = docStruct->GenerateCLExample();
 
   if( exp.find("otbApplicationLauncherCommandLine binPath1 binPath2 -key1 val1 -key2 val2") == std::string::npos )
     {
-- 
GitLab