[PFW] Add getFormattedMapping for InstanceConfigurableElements

BZ: 99822

The mapping data need to be printed, however helper methods are
missing to achieve this easily.

This patch aims to add a new method "getFormattedMapping()" for
CMappingData, allowing to format the mapping data as a string.

Change-Id: Ia030c6b88905fcb7591ad45339712051eb88d1c1
Signed-off-by: Frederic Boisnard <fredericx.boisnard@intel.com>
Reviewed-on: http://android.intel.com:8080/109301
Reviewed-by: Benavoli, Patrick <patrick.benavoli@intel.com>
Reviewed-by: De Chivre, Renaud <renaud.de.chivre@intel.com>
Reviewed-by: Rocard, KevinX <kevinx.rocard@intel.com>
Reviewed-by: Denneulin, Guillaume <guillaume.denneulin@intel.com>
Tested-by: Barthes, FabienX <fabienx.barthes@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
diff --git a/parameter/ComponentInstance.cpp b/parameter/ComponentInstance.cpp
index 83e7448..4ffdab9 100644
--- a/parameter/ComponentInstance.cpp
+++ b/parameter/ComponentInstance.cpp
@@ -56,6 +56,18 @@
     return base::hasMappingData() || (_pComponentType && _pComponentType->hasMappingData());
 }
 
+string CComponentInstance::getFormattedMapping() const
+{
+    // Try myself first then associated component type
+    string strValue = base::getFormattedMapping();
+    if (_pComponentType) {
+
+        strValue += _pComponentType->getFormattedMapping();
+    }
+
+    return strValue;
+}
+
 bool CComponentInstance::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext)
 {
     // Context
diff --git a/parameter/ComponentInstance.h b/parameter/ComponentInstance.h
index 536adb8..7a2f268 100644
--- a/parameter/ComponentInstance.h
+++ b/parameter/ComponentInstance.h
@@ -36,6 +36,12 @@
     // Mapping info
     virtual bool getMappingData(const string& strKey, const string*& pStrValue) const;
     virtual bool hasMappingData() const;
+    /**
+     * Returns the mapping associated to the current TypeElement instance
+     *
+     * @return A string containing the mapping as a comma separated key value pairs
+     */
+    virtual string getFormattedMapping() const;
 
     // From IXmlSink
     virtual bool fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext);
diff --git a/parameter/ComponentType.cpp b/parameter/ComponentType.cpp
index 3b5729a..0f7dc32 100644
--- a/parameter/ComponentType.cpp
+++ b/parameter/ComponentType.cpp
@@ -56,6 +56,18 @@
     return base::hasMappingData() || (_pExtendsComponentType && _pExtendsComponentType->hasMappingData());
 }
 
+string CComponentType::getFormattedMapping() const
+{
+    // Try myself first then associated component type
+    string strValue = base::getFormattedMapping();
+    if (_pExtendsComponentType) {
+
+        strValue += _pExtendsComponentType->getFormattedMapping();
+    }
+
+    return strValue;
+}
+
 bool CComponentType::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext)
 {
     // Context
diff --git a/parameter/ComponentType.h b/parameter/ComponentType.h
index 7984fa7..d255e62 100644
--- a/parameter/ComponentType.h
+++ b/parameter/ComponentType.h
@@ -39,6 +39,12 @@
     // Mapping info
     virtual bool getMappingData(const string& strKey, const string*& pStrValue) const;
     virtual bool hasMappingData() const;
+    /**
+     * Returns the mapping associated to the current TypeElement instance
+     *
+     * @return A string containing the mapping as a comma separated key value pairs
+     */
+    virtual string getFormattedMapping() const;
 
     // From IXmlSink
     virtual bool fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext);
diff --git a/parameter/InstanceConfigurableElement.cpp b/parameter/InstanceConfigurableElement.cpp
index 40ef18b..cc84a3e 100644
--- a/parameter/InstanceConfigurableElement.cpp
+++ b/parameter/InstanceConfigurableElement.cpp
@@ -55,6 +55,13 @@
     return getTypeElement()->getMappingData(strKey, pStrValue);
 }
 
+// Returns the formatted mapping
+string CInstanceConfigurableElement::getFormattedMapping() const
+{
+    // Delegate
+    return getTypeElement()->getFormattedMapping();
+}
+
 bool CInstanceConfigurableElement::map(IMapper& mapper, string& strError)
 {
     bool bHasMappingData = getTypeElement()->hasMappingData();
diff --git a/parameter/InstanceConfigurableElement.h b/parameter/InstanceConfigurableElement.h
index e27ad4b..b1ffdf8 100644
--- a/parameter/InstanceConfigurableElement.h
+++ b/parameter/InstanceConfigurableElement.h
@@ -48,9 +48,16 @@
     // Instantiated type
     const CTypeElement* getTypeElement() const;
 
-    // Mapping info
     bool getMappingData(const string& strKey, const string*& pStrValue) const;
 
+    /**
+     * Returns the mapping data associated to the type element of the current
+     * InstanceConfigurableElement, as a formatted string
+     *
+     * @return A string containing the formatted mapping
+     */
+    string getFormattedMapping() const;
+
     // From CElement
     virtual string getKind() const;
 
diff --git a/parameter/MappingData.cpp b/parameter/MappingData.cpp
index 4ec58e3..63c65af 100644
--- a/parameter/MappingData.cpp
+++ b/parameter/MappingData.cpp
@@ -24,6 +24,7 @@
  */
 #include "MappingData.h"
 #include "Tokenizer.h"
+#include "Utility.h"
 #include <assert.h>
 
 CMappingData::CMappingData()
@@ -86,6 +87,15 @@
     return false;
 }
 
+string CMappingData::asString() const
+{
+    string strValue;
+
+    CUtility::asString(_keyToValueMap, strValue, ", ", ":");
+
+    return strValue;
+}
+
 bool CMappingData::addValue(const string& strkey, const string& strValue)
 {
     if (_keyToValueMap.find(strkey) != _keyToValueMap.end()) {
diff --git a/parameter/MappingData.h b/parameter/MappingData.h
index 03f8e2a..0d16eb3 100644
--- a/parameter/MappingData.h
+++ b/parameter/MappingData.h
@@ -42,6 +42,13 @@
     // Query
     bool getValue(const string& strkey, const string*& pStrValue) const;
 
+    /**
+     * Formats the mapping as a list of comma-space separated key:value pairs
+     *
+     * @return the formatted string
+     */
+    string asString() const;
+
 private:
     bool addValue(const string& strkey, const string& strValue);
 
diff --git a/parameter/ParameterMgr.cpp b/parameter/ParameterMgr.cpp
index 02bedb9..6293129 100644
--- a/parameter/ParameterMgr.cpp
+++ b/parameter/ParameterMgr.cpp
@@ -771,7 +771,9 @@
     list<string> lstrSelectionCriteria;
     getSelectionCriteria()->listSelectionCriteria(lstrSelectionCriteria, false, true);
     // Concatenate the criterion list as the command result
-    CUtility::concatenate(lstrSelectionCriteria, strResult);
+    string strCriteriaStates;
+    CUtility::asString(lstrSelectionCriteria, strCriteriaStates);
+    strResult += strCriteriaStates;
 
     return CCommandHandler::ESucceeded;
 }
@@ -933,7 +935,7 @@
     getSelectionCriteria()->listSelectionCriteria(lstrResult, true, humanReadable);
 
     // Concatenate the criterion list as the command result
-    CUtility::concatenate(lstrResult, strResult);
+    CUtility::asString(lstrResult, strResult);
 
     return CCommandHandler::ESucceeded;
 }
@@ -1077,7 +1079,7 @@
     list<string> lstrResult;
     if (!restoreConfiguration(remoteCommand.getArgument(0), remoteCommand.getArgument(1), lstrResult)) {
         //Concatenate the error list as the command result
-        CUtility::concatenate(lstrResult, strResult);
+        CUtility::asString(lstrResult, strResult);
 
         return  CCommandHandler::EFailed;
     }
@@ -1652,7 +1654,7 @@
     list<string> lstrError;
     if (! syncerSet.sync(*_pMainParameterBlackboard, false, &lstrError)){
 
-        CUtility::concatenate(lstrError, strError);
+        CUtility::asString(lstrError, strError);
         return false;
     };
 
diff --git a/parameter/TypeElement.cpp b/parameter/TypeElement.cpp
index 405dc7d..5bfc2d7 100644
--- a/parameter/TypeElement.cpp
+++ b/parameter/TypeElement.cpp
@@ -126,6 +126,15 @@
     return _pMappingData;
 }
 
+string CTypeElement::getFormattedMapping() const
+{
+    if (_pMappingData) {
+
+        return _pMappingData->asString();
+    }
+    return "";
+}
+
 // From IXmlSource
 void CTypeElement::toXml(CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) const
 {
diff --git a/parameter/TypeElement.h b/parameter/TypeElement.h
index bf0b306..db40412 100644
--- a/parameter/TypeElement.h
+++ b/parameter/TypeElement.h
@@ -42,6 +42,13 @@
     virtual bool getMappingData(const string& strKey, const string*& pStrValue) const;
     virtual bool hasMappingData() const;
 
+    /**
+     * Returns the mapping associated to the current TypeElement instance
+     *
+     * @return A string containing the mapping as a comma separated key value pairs
+     */
+    virtual string getFormattedMapping() const;
+
     // Element properties
     virtual void showProperties(string& strResult) const;
 
diff --git a/utility/Utility.cpp b/utility/Utility.cpp
index afedc07..ccf3bc6 100644
--- a/utility/Utility.cpp
+++ b/utility/Utility.cpp
@@ -24,23 +24,43 @@
 
 #include "Utility.h"
 
-// Concatenate string list
-void CUtility::concatenate(const std::list<std::string>& lstr, std::string& strOutput, const std::string& strSeparator)
+#include <sstream>
+#include <iterator>
+
+// Format string list
+void CUtility::asString(const std::list<std::string>& lstr,
+                        std::string& strOutput,
+                        const std::string& strSeparator)
 {
-    bool bStart = true;
+    std::ostringstream ostrFormatedList;
 
-    std::list<std::string>::const_iterator iterator(lstr.begin());
-    std::list<std::string>::const_iterator end(lstr.end());
+    std::copy(lstr.begin(), lstr.end(),
+              std::ostream_iterator<std::string>(ostrFormatedList, strSeparator.c_str()));
 
-    while (iterator != end) {
+    strOutput = ostrFormatedList.str();
 
-        if (bStart) {
-            // Do not add a separator before first element
-            bStart = false;
-        } else {
-            // Add the separator bettween each element
-            strOutput += strSeparator;
-        }
-        strOutput += *iterator++;
+    // Remove last separator
+    if (strOutput.size() > strSeparator.size()) {
+
+        strOutput.erase(strOutput.size() - strSeparator.size());
     }
 }
+
+// Format string map
+void CUtility::asString(const std::map<std::string, std::string>& mapStr,
+                        std::string& strOutput,
+                        const std::string& strItemSeparator,
+                        const std::string& strKeyValueSeparator)
+{
+    std::list<std::string> listKeysValues;
+
+    std::map<std::string, std::string>::const_iterator iter;
+
+    for(iter = mapStr.begin(); iter != mapStr.end(); ++iter) {
+
+        listKeysValues.push_back(iter->first + strKeyValueSeparator + iter->second);
+    }
+
+    CUtility::asString(listKeysValues, strOutput, strItemSeparator);
+}
+
diff --git a/utility/Utility.h b/utility/Utility.h
index 7c395c0..ec82278 100644
--- a/utility/Utility.h
+++ b/utility/Utility.h
@@ -27,12 +27,36 @@
 
 #include <string>
 #include <list>
+#include <map>
 
 class CUtility
 {
 public:
-    // Concatenate string list
-    static void concatenate(const std::list<std::string>& lstr, std::string& strOutput, const std::string& separator = "\n");
+    /**
+    * Format the items of a map into a string as a list of key-value pairs. The map must be
+    * composed of pairs of strings.
+    *
+    * @param[in] mapStr A map of strings
+    * @param[out] strOutput The output string
+    * @param[in] separator The separator to use between each item
+    */
+    static void asString(const std::list<std::string>& lstr,
+                         std::string& strOutput,
+                         const std::string& separator = "\n");
+
+    /**
+     * Format the items of a map into a string as a list of key-value pairs. The map must be
+     * composed of pairs of strings.
+     *
+     * @param[in] mapStr A map of strings
+     * @param[out] strOutput The output string
+     * @param[in] strItemSeparator The separator to use between each item (key-value pair)
+     * @param[in] strKeyValueSeparator The separator to use between key and value
+     */
+    static void asString(const std::map<std::string, std::string>& mapStr,
+                         std::string& strOutput,
+                         const std::string& strItemSeparator = ", ",
+                         const std::string& strKeyValueSeparator = ":");
 };
 
 #endif // UTILITY_H