diff options
author | Guillaume Denneulin <guillaume.denneulin@intel.com> | 2014-01-31 15:09:42 +0100 |
---|---|---|
committer | David Wagner <david.wagner@intel.com> | 2014-02-13 16:08:59 +0100 |
commit | 3ba083ee0b0ff7e01caeb3bc7395377071e20fe6 (patch) | |
tree | d639c767d5308ee2658db9d1fc0f946067a74c94 | |
parent | 7613e74a97d67c392a241ad3a62c6533b31f48ab (diff) | |
download | external_parameter-framework-3ba083ee0b0ff7e01caeb3bc7395377071e20fe6.zip external_parameter-framework-3ba083ee0b0ff7e01caeb3bc7395377071e20fe6.tar.gz external_parameter-framework-3ba083ee0b0ff7e01caeb3bc7395377071e20fe6.tar.bz2 |
In structure XML files, implement component library files inclusion
BZ: 168727
In the PFW structure file, it is not possible to include a component
library from another XML file.
Implement the possibility to import component from another XML file
that would be included in a structure XML file and that would
describe a component library.
Change-Id: Id6125140de1c8e9882375d01199f695b929f45e2
Signed-off-by: Guillaume Denneulin <guillaume.denneulin@intel.com>
-rw-r--r-- | Schemas/ComponentLibrary.xsd | 15 | ||||
-rw-r--r-- | Schemas/ComponentTypeSet.xsd | 39 | ||||
-rw-r--r-- | Schemas/Parameter.xsd | 8 | ||||
-rw-r--r-- | Schemas/Subsystem.xsd | 47 | ||||
-rw-r--r-- | parameter/ComponentLibrary.cpp | 32 | ||||
-rw-r--r-- | parameter/ComponentLibrary.h | 4 | ||||
-rwxr-xr-x | parameter/Element.cpp | 33 | ||||
-rw-r--r-- | parameter/Element.h | 12 | ||||
-rw-r--r-- | xmlserializer/XmlFileDocSource.cpp | 27 | ||||
-rw-r--r-- | xmlserializer/XmlFileDocSource.h | 11 |
10 files changed, 173 insertions, 55 deletions
diff --git a/Schemas/ComponentLibrary.xsd b/Schemas/ComponentLibrary.xsd new file mode 100644 index 0000000..09d2e27 --- /dev/null +++ b/Schemas/ComponentLibrary.xsd @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + <xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2005/08/xml.xsd"/> + <xs:include schemaLocation="ComponentTypeSet.xsd"/> + <xs:element name="ComponentLibrary" type="ComponentTypeSetType"> + <xs:key name="ComponentTypeUniqueness"> + <xs:selector xpath=".//ComponentType"/> + <xs:field xpath="@Name"/> + </xs:key> + <xs:keyref name="ComponentTypeNotFound" refer="ComponentTypeUniqueness"> + <xs:selector xpath=".//ComponentType/Component"/> + <xs:field xpath="@Type"/> + </xs:keyref> + </xs:element> +</xs:schema> diff --git a/Schemas/ComponentTypeSet.xsd b/Schemas/ComponentTypeSet.xsd new file mode 100644 index 0000000..d00be00 --- /dev/null +++ b/Schemas/ComponentTypeSet.xsd @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + <xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2005/08/xml.xsd"/> + <xs:include schemaLocation="Parameter.xsd"/> + <xs:complexType name="ComponentType"> + <xs:sequence> + <xs:sequence maxOccurs="unbounded"> + <xs:group ref="ParameterBlockGroup"/> + </xs:sequence> + </xs:sequence> + <xs:attributeGroup ref="Nameable"/> + <xs:attribute name="Extends" use="optional"/> + <xs:attribute name="Mapping" use="optional"/> + </xs:complexType> + <xs:group name="ComponentTypeSetGroup"> + <xs:choice> + <xs:element name="ComponentLibrary" type="ComponentTypeSetType"/> + <xs:element name="ComponentTypeSet" type="ComponentTypeSetType"/> + <xs:element name="ComponentType" type="ComponentType"> + <xs:unique name="ComponentTypeSubElementsUniqueness"> + <xs:selector xpath="*"/> + <xs:field xpath="@Name"/> + </xs:unique> + </xs:element> + </xs:choice> + </xs:group> + <xs:complexType name="ComponentTypeSetType"> + <xs:sequence> + <xs:group ref="ComponentTypeSetGroup" minOccurs="0" maxOccurs="unbounded"/> + </xs:sequence> + <xs:attribute ref="xml:base"/> + </xs:complexType> + <xs:element name="ComponentTypeSet" type="ComponentTypeSetType"> + <xs:unique name="ComponentTypeUniquenessInComponentTypeSet"> + <xs:selector xpath=".//ComponentType"/> + <xs:field xpath="@Name"/> + </xs:unique> + </xs:element> +</xs:schema> diff --git a/Schemas/Parameter.xsd b/Schemas/Parameter.xsd index ad3d739..3b635fc 100644 --- a/Schemas/Parameter.xsd +++ b/Schemas/Parameter.xsd @@ -4,6 +4,14 @@ <xs:attribute name="Name" type="xs:NMTOKEN" use="required"/>
<xs:attribute name="Description" type="xs:string" use="optional"/>
</xs:attributeGroup>
+ <xs:attributeGroup name="TypedNameable">
+ <xs:attributeGroup ref="Nameable"/>
+ <xs:attribute name="Type" type="xs:NMTOKEN" use="required"/>
+ </xs:attributeGroup>
+ <xs:complexType name="ComponentInstance">
+ <xs:attributeGroup ref="TypedNameable"/>
+ <xs:attribute name="Mapping" use="optional"/>
+ </xs:complexType>
<xs:simpleType name="SizeType">
<xs:restriction base="xs:positiveInteger">
<xs:pattern value="8|16|32"/>
diff --git a/Schemas/Subsystem.xsd b/Schemas/Subsystem.xsd index aa2c35c..ab0fdf6 100644 --- a/Schemas/Subsystem.xsd +++ b/Schemas/Subsystem.xsd @@ -1,39 +1,10 @@ <?xml version="1.0" encoding="UTF-8"?>
<!--W3C Schema generated by XMLSpy v2007 (http://www.altova.com)-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
- <xs:include schemaLocation="Parameter.xsd"/>
- <xs:attributeGroup name="TypedNameable">
- <xs:attributeGroup ref="Nameable"/>
- <xs:attribute name="Type" type="xs:NMTOKEN" use="required"/>
- </xs:attributeGroup>
- <xs:complexType name="ComponentInstance">
- <xs:attributeGroup ref="TypedNameable"/>
- <xs:attribute name="Mapping" use="optional"/>
- </xs:complexType>
- <xs:complexType name="ComponentType">
- <xs:sequence>
- <xs:sequence maxOccurs="unbounded">
- <xs:group ref="ParameterBlockGroup"/>
- </xs:sequence>
- </xs:sequence>
- <xs:attributeGroup ref="Nameable"/>
- <xs:attribute name="Extends" use="optional"/>
- <xs:attribute name="Mapping" use="optional"/>
- </xs:complexType>
+ <xs:include schemaLocation="ComponentLibrary.xsd"/>
<xs:complexType name="SubsystemType">
<xs:sequence>
- <xs:element name="ComponentLibrary">
- <xs:complexType>
- <xs:sequence>
- <xs:element name="ComponentType" type="ComponentType" minOccurs="0" maxOccurs="unbounded">
- <xs:unique name="ComponentTypeSubElementsUniqueness">
- <xs:selector xpath="*"/>
- <xs:field xpath="@Name"/>
- </xs:unique>
- </xs:element>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
+ <xs:element ref="ComponentLibrary"/>
<xs:element name="InstanceDefinition">
<xs:complexType>
<xs:sequence>
@@ -60,21 +31,9 @@ <xs:attribute name="Type" use="required"/>
</xs:complexType>
<xs:element name="Subsystem" type="SubsystemType">
- <xs:key name="ComponentTypeUniqueness">
- <xs:selector xpath="ComponentLibrary/ComponentType"/>
- <xs:field xpath="@Name"/>
- </xs:key>
<xs:keyref name="InstanceDefinitionComponentTypeNotFound" refer="ComponentTypeUniqueness">
<xs:selector xpath="InstanceDefinition/Component"/>
<xs:field xpath="@Type"/>
- </xs:keyref>
- <xs:keyref name="ComponentTypeNotFound" refer="ComponentTypeUniqueness">
- <xs:selector xpath="ComponentLibrary/ComponentType/Component"/>
- <xs:field xpath="@Type"/>
- </xs:keyref>
- <!--xs:keyref name="ExtendedComponentTypeNotFound" refer="ComponentTypeUniqueness">
- <xs:selector xpath="ComponentLibrary/ComponentType"/>
- <xs:field xpath="@Extends"/>
- </xs:keyref-->
+ </xs:keyref>
</xs:element>
</xs:schema>
diff --git a/parameter/ComponentLibrary.cpp b/parameter/ComponentLibrary.cpp index f133213..f3576e8 100644 --- a/parameter/ComponentLibrary.cpp +++ b/parameter/ComponentLibrary.cpp @@ -45,3 +45,35 @@ const CComponentType* CComponentLibrary::getComponentType(const string& strName) return static_cast<const CComponentType*>(findChild(strName)); } +bool CComponentLibrary::fromXml(const CXmlElement& xmlElement, + CXmlSerializingContext& serializingContext) +{ + CXmlElement childElement; + + CXmlElement::CChildIterator it(xmlElement); + + // XML populate all component libraries + while (it.next(childElement)) { + + // Filter component library/type set elements + if (childElement.getType() == "ComponentLibrary" || + childElement.getType() == "ComponentTypeSet") { + + if (!fromXml(childElement, serializingContext)) { + + return false; + } + } else { + // Regular child creation and populating + CElement* pChild = createChild(childElement, serializingContext); + + if (!pChild || !pChild->fromXml(childElement, serializingContext)) { + + return false; + } + } + } + + return true; +} + diff --git a/parameter/ComponentLibrary.h b/parameter/ComponentLibrary.h index 443d634..835373b 100644 --- a/parameter/ComponentLibrary.h +++ b/parameter/ComponentLibrary.h @@ -38,6 +38,10 @@ public: const CComponentType* getComponentType(const string& strName) const; virtual string getKind() const; + + // From IXmlSink + virtual bool fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext); + private: virtual bool childrenAreDynamic() const; }; diff --git a/parameter/Element.cpp b/parameter/Element.cpp index b68205b..43f1c57 100755 --- a/parameter/Element.cpp +++ b/parameter/Element.cpp @@ -263,15 +263,9 @@ bool CElement::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& se } else { // Child needs creation - pChild = elementSerializingContext.getElementLibrary()->createElement(childElement); + pChild = createChild(childElement, serializingContext); - if (pChild) { - - // Store created child! - addChild(pChild); - } else { - - elementSerializingContext.setError("Unable to create XML element " + childElement.getPath()); + if (!pChild) { return false; } @@ -403,6 +397,29 @@ CElement* CElement::getLastChild() return _childArray[uiNbChildren - 1]; } +CElement* CElement::createChild(const CXmlElement& childElement, + CXmlSerializingContext& serializingContext) +{ + // Context + CXmlElementSerializingContext& elementSerializingContext = + static_cast<CXmlElementSerializingContext&>(serializingContext); + + // Child needs creation + CElement* pChild = elementSerializingContext.getElementLibrary()->createElement(childElement); + + if (!pChild) { + + elementSerializingContext.setError( + "Unable to create XML element " + childElement.getPath()); + + return NULL; + } + // Store created child! + addChild(pChild); + + return pChild; +} + bool CElement::removeChild(CElement* pChild) { ChildArrayIterator it; diff --git a/parameter/Element.h b/parameter/Element.h index b381898..01e4254 100644 --- a/parameter/Element.h +++ b/parameter/Element.h @@ -120,6 +120,18 @@ protected: CElement* findAscendantOfKind(const string& strKind); CElement* getRoot(); const CElement* getRoot() const; + + /** + * Creates a child CElement from a child XML Element + * + * @param[in] childElement the XML element to create CElement from + * @param[in] elementSerializingContext the serializing context + * + * @return child a pointer on the CElement object that has been added to the tree + */ + CElement* createChild(const CXmlElement& childElement, + CXmlSerializingContext& elementSerializingContext); + private: // Logging (done by root) virtual void doLog(bool bIsWarning, const string& strLog) const; diff --git a/xmlserializer/XmlFileDocSource.cpp b/xmlserializer/XmlFileDocSource.cpp index 4df2ad1..53e7c86 100644 --- a/xmlserializer/XmlFileDocSource.cpp +++ b/xmlserializer/XmlFileDocSource.cpp @@ -24,6 +24,7 @@ #include "XmlFileDocSource.h" #include <libxml/parser.h> +#include <libxml/xinclude.h> #define base CXmlDocSource @@ -32,7 +33,7 @@ CXmlFileDocSource::CXmlFileDocSource(const string& strXmlInstanceFile, const string& strRootElementType, const string& strRootElementName, const string& strNameAttrituteName) : - base(xmlReadFile(strXmlInstanceFile.c_str(),NULL, 0), + base(readFile(strXmlInstanceFile), strXmlSchemaFile, strRootElementType, strRootElementName, @@ -44,7 +45,7 @@ CXmlFileDocSource::CXmlFileDocSource(const string& strXmlInstanceFile, CXmlFileDocSource::CXmlFileDocSource(const string& strXmlInstanceFile, const string& strXmlSchemaFile, const string& strRootElementType) : - base(xmlReadFile(strXmlInstanceFile.c_str(), NULL, 0), + base(readFile(strXmlInstanceFile), strXmlSchemaFile, strRootElementType), _strXmlInstanceFile(strXmlInstanceFile) @@ -66,7 +67,7 @@ bool CXmlFileDocSource::isParsable(CXmlSerializingContext& serializingContext) c bool CXmlFileDocSource::populate(CXmlSerializingContext& serializingContext) { - if (!base::validate(serializingContext)) { + if (!validate(serializingContext)) { // Add the file's name in the error message serializingContext.appendLineToError("File : " + _strXmlInstanceFile); @@ -76,3 +77,23 @@ bool CXmlFileDocSource::populate(CXmlSerializingContext& serializingContext) return true; } + +_xmlDoc* CXmlFileDocSource::readFile(const string& strFileName) +{ + // Read xml file + xmlDocPtr pDoc = xmlReadFile(strFileName.c_str(), NULL, 0); + + if (!pDoc) { + + return NULL; + } + // Process file inclusion + // WARNING: this symbol is available if libxml2 has been compiled with LIBXML_XINCLUDE_ENABLED + if (xmlXIncludeProcess(pDoc) < 0) { + + xmlFreeDoc(pDoc); + return NULL; + } + + return pDoc; +} diff --git a/xmlserializer/XmlFileDocSource.h b/xmlserializer/XmlFileDocSource.h index 98ba6e3..1efafe2 100644 --- a/xmlserializer/XmlFileDocSource.h +++ b/xmlserializer/XmlFileDocSource.h @@ -73,6 +73,17 @@ public: virtual bool isParsable(CXmlSerializingContext& serializingContext) const; private: + /** + * Read xml file + * + * This function reads an xml file and processes eventual included files + * WARNING: to compile this function, libxml2 has to be compiled with LIBXML_XINCLUDE_ENABLED + * + * @param[in] strFileName the file name + * + * @return a pointer to generated xml document object + */ + static _xmlDoc* readFile(const string& strFileName); /** * Instance file |