PFW: Add setDomainsXML command to import domains from string

BZ: 55694

Unable possibility to import the configurable domains from a string

Create one command that can be called through the command
line of the parameter-framework. The command setDomainXML
allows to import configurable domains with settings from
a string provided as first argument containing the xml description.

Change-Id: I6db7ccb8ba61b5e4c8ba81579a68f40e887d1534
Signed-off-by: Georges-Henri Baron <georges-henrix.baron@intel.com>
Reviewed-on: http://android.intel.com:8080/65408
Reviewed-by: cactus <cactus@intel.com>
Reviewed-by: Dixon, CharlesX <charlesx.dixon@intel.com>
Reviewed-by: Rocard, KevinX <kevinx.rocard@intel.com>
Tested-by: Dixon, CharlesX <charlesx.dixon@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
diff --git a/xmlserializer/XmlDocSource.cpp b/xmlserializer/XmlDocSource.cpp
index e876f16..144b636 100644
--- a/xmlserializer/XmlDocSource.cpp
+++ b/xmlserializer/XmlDocSource.cpp
@@ -1,6 +1,6 @@
 /*
  * INTEL CONFIDENTIAL
- * Copyright © 2011 Intel
+ * Copyright © 2013 Intel
  * Corporation All Rights Reserved.
  *
  * The source code contained or described herein and all documents related to
@@ -18,31 +18,55 @@
  * of the Materials, either expressly, by implication, inducement, estoppel or
  * otherwise. Any license under such intellectual property rights must be
  * express and approved by Intel in writing.
- *
- * CREATED: 2012-08-10
  */
+
 #include "XmlDocSource.h"
 #include <libxml/tree.h>
+#include <libxml/xmlschemas.h>
 #include <stdlib.h>
 
 // Schedule for libxml2 library
 bool CXmlDocSource::_bLibXml2CleanupScheduled;
 
 CXmlDocSource::CXmlDocSource(_xmlDoc *pDoc, _xmlNode *pRootNode):
-      _pDoc(pDoc), _pRootNode(pRootNode)
+      _pDoc(pDoc),
+      _pRootNode(pRootNode),
+      _strXmlSchemaFile(""),
+      _strRootElementType(""),
+      _strRootElementName(""),
+      _strNameAttrituteName(""),
+      _bNameCheck(false)
 {
-    if (!_bLibXml2CleanupScheduled) {
+    init();
+}
 
-        // Schedule cleanup
-        atexit(xmlCleanupParser);
+CXmlDocSource::CXmlDocSource(_xmlDoc *pDoc,
+                             const string& strXmlSchemaFile,
+                             const string& strRootElementType,
+                             const string& strRootElementName,
+                             const string& strNameAttrituteName) :
+    _pDoc(pDoc),
+    _pRootNode(NULL),
+    _strXmlSchemaFile(strXmlSchemaFile),
+    _strRootElementType(strRootElementType),
+    _strRootElementName(strRootElementName),
+    _strNameAttrituteName(strNameAttrituteName),
+    _bNameCheck(true)
+{
+    init();
+}
 
-        _bLibXml2CleanupScheduled = true;
-    }
-
-    if (!_pRootNode) {
-
-        _pRootNode = xmlDocGetRootElement(_pDoc);
-    }
+CXmlDocSource::CXmlDocSource(_xmlDoc* pDoc,
+                             const string& strXmlSchemaFile,
+                             const string& strRootElementType) :
+    _pDoc(pDoc), _pRootNode(NULL),
+    _strXmlSchemaFile(strXmlSchemaFile),
+    _strRootElementType(strRootElementType),
+    _strRootElementName(""),
+    _strNameAttrituteName(""),
+    _bNameCheck(false)
+{
+    init();
 }
 
 CXmlDocSource::~CXmlDocSource()
@@ -54,7 +78,6 @@
     }
 }
 
-// Root element
 void CXmlDocSource::getRootElement(CXmlElement& xmlRootElement) const
 {
     xmlRootElement.setXmlElement(_pRootNode);
@@ -77,3 +100,131 @@
     return _pDoc;
 }
 
+bool CXmlDocSource::validate(CXmlSerializingContext& serializingContext)
+{
+    // Check that the doc has been created
+    if (!_pDoc) {
+
+        serializingContext.setError("Could not parse document ");
+
+        return false;
+    }
+
+    // Validate
+    if (!isInstanceDocumentValid()) {
+
+        serializingContext.setError("Document is not valid");
+
+        return false;
+    }
+
+    // Check Root element type
+    if (getRootElementName() != _strRootElementType) {
+
+        serializingContext.setError("Error: Wrong XML structure document ");
+        serializingContext.appendLineToError("Root Element " + getRootElementName()
+                                             + " mismatches expected type " + _strRootElementType);
+
+        return false;
+    }
+
+    if (_bNameCheck) {
+
+        string strRootElementNameCheck = getRootElementAttributeString(_strNameAttrituteName);
+
+        // Check Root element name attribute (if any)
+        if (!_strRootElementName.empty() && strRootElementNameCheck != _strRootElementName) {
+
+            serializingContext.setError("Error: Wrong XML structure document ");
+            serializingContext.appendLineToError(_strRootElementType + " element "
+                                                 + _strRootElementName + " mismatches expected "
+                                                 + _strRootElementType + " type "
+                                                 + strRootElementNameCheck);
+
+            return false;
+        }
+    }
+
+    return true;
+}
+
+void CXmlDocSource::init()
+{
+    if (!_bLibXml2CleanupScheduled) {
+
+        // Schedule cleanup
+        atexit(xmlCleanupParser);
+
+        _bLibXml2CleanupScheduled = true;
+    }
+
+    if (!_pRootNode) {
+
+        _pRootNode = xmlDocGetRootElement(_pDoc);
+    }
+}
+
+bool CXmlDocSource::isInstanceDocumentValid()
+{
+#ifdef LIBXML_SCHEMAS_ENABLED
+    xmlDocPtr pSchemaDoc = xmlReadFile(_strXmlSchemaFile.c_str(), NULL, XML_PARSE_NONET);
+
+    if (!pSchemaDoc) {
+        // Unable to load Schema
+        return false;
+    }
+
+    xmlSchemaParserCtxtPtr pParserCtxt = xmlSchemaNewDocParserCtxt(pSchemaDoc);
+
+    if (!pParserCtxt) {
+
+        // Unable to create schema context
+        xmlFreeDoc(pSchemaDoc);
+        return false;
+    }
+
+    // Get Schema
+    xmlSchemaPtr pSchema = xmlSchemaParse(pParserCtxt);
+
+    if (!pSchema) {
+
+        // Invalid Schema
+        xmlSchemaFreeParserCtxt(pParserCtxt);
+        xmlFreeDoc(pSchemaDoc);
+        return false;
+    }
+    xmlSchemaValidCtxtPtr pValidationCtxt = xmlSchemaNewValidCtxt(pSchema);
+
+    if (!pValidationCtxt) {
+
+        // Unable to create validation context
+        xmlSchemaFree(pSchema);
+        xmlSchemaFreeParserCtxt(pParserCtxt);
+        xmlFreeDoc(pSchemaDoc);
+        return false;
+    }
+
+    xmlSetStructuredErrorFunc(this, schemaValidityStructuredErrorFunc);
+
+    bool isDocValid = xmlSchemaValidateDoc(pValidationCtxt, _pDoc) == 0;
+
+    xmlSchemaFreeValidCtxt(pValidationCtxt);
+    xmlSchemaFree(pSchema);
+    xmlSchemaFreeParserCtxt(pParserCtxt);
+    xmlFreeDoc(pSchemaDoc);
+
+    return isDocValid;
+#else
+    return true;
+#endif
+}
+
+void CXmlDocSource::schemaValidityStructuredErrorFunc(void* pUserData, _xmlError* pError)
+{
+    (void)pUserData;
+
+#ifdef LIBXML_SCHEMAS_ENABLED
+    // Display message
+    puts(pError->message);
+#endif
+}