--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/qthighway/xqserviceutil/src/xqservicemetadata/old/xqservicemetadata.cpp Tue Aug 31 16:02:37 2010 +0300
@@ -0,0 +1,473 @@
+/*
+* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, version 2.1 of the License.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not,
+* see "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html/".
+*
+* Description: Service metadata parser class implementation
+*
+*/
+
+#include "xqservicelog.h"
+
+#include <QFile>
+#include "xqservicemetadata_p.h"
+#include "xqsfwinterface_p.h"
+
+
+//XML tags and attributes
+//General
+#define NAME_TAG "name"
+#define DESCRIPTION_TAG "description"
+
+//Service related
+#define SERVICE_TAG "service"
+#define SERVICE_FILEPATH "filepath"
+
+//Interface related
+#define INTERFACE_TAG "interface"
+#define INTERFACE_VERSION "version"
+#define INTERFACE_CAPABILITY "capabilities"
+
+
+QT_BEGIN_NAMESPACE
+
+static const char PATH_SEPARATOR[] = "\\";
+
+/*!
+ \class ServiceMetaData
+
+ Utility class (used by service database) that offers support for
+ parsing metadata service xml registry file during service registration. \n
+
+ It uses QXMLStreamReader class for parsing. Supproted Operations are:
+ - Parse the service and interfaces defined in XML file
+ - name, version, capabilitiesList, description and filePath of service can be retrieved
+ - each interface can be retrieved
+*/
+
+/*!
+ * Class constructor
+ *
+ * @param aXmlFilePath path to the xml file that describes the service.
+ */
+ServiceMetaData::ServiceMetaData(const QString &aXmlFilePath)
+{
+ XQSERVICE_DEBUG_PRINT("ServiceMetaData::ServiceMetaData(1)");
+ XQSERVICE_DEBUG_PRINT("aXmlFilePath: %s", qPrintable(aXmlFilePath));
+ xmlDevice = new QFile(aXmlFilePath);
+ ownsXmlDevice = true;
+ latestError = 0;
+}
+
+/*!
+ * Class constructor
+ *
+ * @param device QIODevice that contains the XML data that describes the service.
+ */
+ServiceMetaData::ServiceMetaData(QIODevice *device)
+{
+ XQSERVICE_DEBUG_PRINT("ServiceMetaData::ServiceMetaData(2)");
+ xmlDevice = device;
+ ownsXmlDevice = false;
+ latestError = 0;
+}
+
+/*!
+ * Class destructor
+ *
+ */
+ServiceMetaData::~ServiceMetaData()
+{
+ XQSERVICE_DEBUG_PRINT("ServiceMetaData::~ServiceMetaData");
+ if (ownsXmlDevice)
+ delete xmlDevice;
+}
+
+/*!
+ Sets the device containing the XML data that describes the service to \a device.
+ */
+void ServiceMetaData::setDevice(QIODevice *device)
+{
+ XQSERVICE_DEBUG_PRINT("ServiceMetaData::setDevice");
+ clearMetadata();
+ xmlDevice = device;
+ ownsXmlDevice = false;
+}
+
+/*!
+ Returns the device containing the XML data that describes the service.
+*/
+QIODevice *ServiceMetaData::device() const
+{
+ XQSERVICE_DEBUG_PRINT("ServiceMetaData::device");
+ return xmlDevice;
+}
+
+/*!
+ * Gets the service name
+ *
+ * @return service name or default value (empty string) if it is not available
+ */
+QString ServiceMetaData::name()
+{
+ XQSERVICE_DEBUG_PRINT("ServiceMetaData::name");
+ XQSERVICE_DEBUG_PRINT("serviceName: %s", qPrintable(serviceName));
+ return serviceName;
+}
+
+/*!
+ * Sets the path of service implementation file
+ *
+ * @param aFilePath path of service implementation file
+ */
+void ServiceMetaData::setServiceFilePath(const QString &aFilePath)
+{
+ XQSERVICE_DEBUG_PRINT("ServiceMetaData::setServiceFilePath");
+ XQSERVICE_DEBUG_PRINT("aFilePath: %s", qPrintable(aFilePath));
+ serviceFilePath = aFilePath;
+}
+
+/*!
+ * Gets the path of the service implementation file
+ *
+ * @return service implementation filepath
+ */
+QString ServiceMetaData::filePath()
+{
+ XQSERVICE_DEBUG_PRINT("ServiceMetaData::filePath");
+ XQSERVICE_DEBUG_PRINT("serviceFilePath: %s", qPrintable(serviceFilePath));
+ return serviceFilePath;
+}
+
+/*!
+ * Gets the service description
+ *
+ * @return service description or default value (empty string) if it is not available
+ */
+QString ServiceMetaData::description()
+{
+ XQSERVICE_DEBUG_PRINT("ServiceMetaData::description");
+ XQSERVICE_DEBUG_PRINT("serviceDescription: %s", qPrintable(serviceDescription));
+ return serviceDescription;
+}
+
+/*!
+ Returns the number of interfaces provided by the service description
+ */
+int ServiceMetaData::interfaceCount()
+{
+ XQSERVICE_DEBUG_PRINT("ServiceMetaData::interfaceCount");
+ XQSERVICE_DEBUG_PRINT("serviceInterfaces.count(): %d", serviceInterfaces.count());
+ return serviceInterfaces.count();
+}
+
+/*!
+ Returns the metadata of the interace at \a index; otherwise
+ returns 0.
+ */
+QList<SFWInterface> ServiceMetaData::getInterfaces()
+{
+ XQSERVICE_DEBUG_PRINT("ServiceMetaData::getInterfaces");
+ return serviceInterfaces;
+}
+
+/*!
+ Parses the file and extracts the service metadata \n
+ Custom error codes: \n
+ SFW_ERROR_UNABLE_TO_OPEN_FILE in case can not open the XML file \n
+ SFW_ERROR_INVALID_XML_FILE in case service registry is not a valid XML file \n
+ SFW_ERROR_NO_SERVICE in case XML file has no service tag\n
+ @return true if the metadata was read properly, false if there is an error
+ */
+bool ServiceMetaData::extractMetadata()
+{
+ XQSERVICE_DEBUG_PRINT("ServiceMetaData::extractMetadata");
+ latestError = 0;
+ clearMetadata();
+ QXmlStreamReader xmlReader;
+ bool parseError = false;
+ //Open xml file
+ if (!xmlDevice->isOpen() && !xmlDevice->open(QIODevice::ReadOnly)) {
+ XQSERVICE_DEBUG_PRINT("Couldn't open the file");
+ latestError = ServiceMetaData::SFW_ERROR_UNABLE_TO_OPEN_FILE;
+ parseError = true;
+ } else {
+ //Load xml content
+ xmlReader.setDevice(xmlDevice);
+ // Read XML doc
+ while (!xmlReader.atEnd() && !parseError) {
+ xmlReader.readNext();
+ //Found a <service> node, read service related metadata
+ if (xmlReader.isStartElement() && xmlReader.name() == SERVICE_TAG) {
+ if (!processServiceElement(xmlReader)) {
+ XQSERVICE_DEBUG_PRINT("Couldn't process service element");
+ parseError = true;
+ }
+ }
+ else if (xmlReader.isStartElement() && xmlReader.name() != SERVICE_TAG) {
+ XQSERVICE_DEBUG_PRINT("No service");
+ latestError = ServiceMetaData::SFW_ERROR_NO_SERVICE;
+ parseError = true;
+ }
+ else if (xmlReader.tokenType() == QXmlStreamReader::Invalid) {
+ XQSERVICE_DEBUG_PRINT("Invalid XML");
+ latestError = ServiceMetaData::SFW_ERROR_INVALID_XML_FILE;
+ parseError = true;
+ }
+ }
+ if (ownsXmlDevice)
+ xmlDevice->close();
+ }
+ if (parseError) {
+ clearMetadata();
+ }
+ XQSERVICE_DEBUG_PRINT("parseError: %d", parseError);
+ return !parseError;
+}
+
+/*!
+ Gets the latest parsing error \n
+ @return parsing error(negative value) or 0 in case there is none
+ */
+int ServiceMetaData::getLatestError()
+{
+ XQSERVICE_DEBUG_PRINT("ServiceMetaData::getLatestError");
+ XQSERVICE_DEBUG_PRINT("latestError: %d", latestError);
+ return latestError;
+}
+
+/*!
+ Gets the value of the attribute from the XML node \n
+ @param aDomElement xml node
+ @param aAttributeName attribute name
+ @param aValue [out] attribute value
+ @return true if the value was read, false otherwise
+ */
+bool ServiceMetaData::getAttributeValue(const QXmlStreamReader &aXMLReader, const QString &aAttributeName, QString &aValue)
+{
+ XQSERVICE_DEBUG_PRINT("ServiceMetaData::getAttributeValue");
+ XQSERVICE_DEBUG_PRINT("aAttributeName: %s", qPrintable(aAttributeName));
+ bool result = false;
+ for (int i = 0; i < aXMLReader.attributes().count(); i++){
+ QXmlStreamAttribute att = aXMLReader.attributes()[i];
+ if (att.name() == aAttributeName) {
+ if (att.value().isNull() || att.value().isEmpty()) {
+ result = false;
+ } else {
+ result = true;
+ aValue = att.value().toString();
+ XQSERVICE_DEBUG_PRINT("aValue: %s", qPrintable(aValue));
+ }
+ }
+ }
+ // Capability attribute is allowed to be empty
+ if (aAttributeName == INTERFACE_CAPABILITY) {
+ result = true;
+ }
+ XQSERVICE_DEBUG_PRINT("result: %d", result);
+ return result;
+}
+
+/*!
+ Parses and extracts the service metadata from the current xml <service> node \n
+ Custom error codes: \n
+ SFW_ERROR_NO_SERVICE_NAME in case no service name in XML file \n
+ SFW_ERROR_NO_INTERFACE_VERSION in case no interface version in XML file \n
+ SFW_ERROR_PARSE_SERVICE in case can not parse service section in XML file \n
+ SFW_ERROR_NO_SERVICE_FILEPATH in case no service file path in XML file \n
+ SFW_ERROR_INVALID_XML_FILE in case XML file is not valid \n
+ SFW_ERROR_NO_SERVICE_INTERFACE in case no interface defined for service in XML file \n
+ @param aXMLReader xml stream reader
+ @return true if the metadata was read properly, false if there is an error
+ */
+bool ServiceMetaData::processServiceElement(QXmlStreamReader &aXMLReader)
+{
+ XQSERVICE_DEBUG_PRINT("ServiceMetaData::processServiceElement");
+ Q_ASSERT(aXMLReader.isStartElement() && aXMLReader.name() == SERVICE_TAG);
+ bool parseError = false;
+
+ if (!getAttributeValue(aXMLReader, NAME_TAG, serviceName)) {
+ XQSERVICE_DEBUG_PRINT("No service name");
+ latestError = ServiceMetaData::SFW_ERROR_NO_SERVICE_NAME;
+ parseError = true;
+ }
+
+ if (!parseError) {
+ if (!getAttributeValue(aXMLReader, SERVICE_FILEPATH, serviceFilePath)) {
+ XQSERVICE_DEBUG_PRINT("No service filepath");
+ latestError = ServiceMetaData::SFW_ERROR_NO_SERVICE_FILEPATH;
+ parseError = true;
+ }
+ }
+
+ while (!parseError && !aXMLReader.atEnd()) {
+ aXMLReader.readNext();
+ if (aXMLReader.name() == DESCRIPTION_TAG) {
+ serviceDescription = aXMLReader.readElementText();
+ XQSERVICE_DEBUG_PRINT("serviceDescription: %s", qPrintable(serviceDescription));
+ //Found a <interface> node, read module related metadata
+ } else if (aXMLReader.isStartElement() && aXMLReader.name() == INTERFACE_TAG) {
+ if (!processInterfaceElement(aXMLReader)){
+ XQSERVICE_DEBUG_PRINT("Couldn't process interface element");
+ parseError = true;
+ }
+ //Found </service>, leave the loop
+ } else if (aXMLReader.isEndElement() && aXMLReader.name() == SERVICE_TAG) {
+ XQSERVICE_DEBUG_PRINT("Service element handled");
+ break;
+ } else if (aXMLReader.isEndElement() || aXMLReader.isStartElement()) {
+ XQSERVICE_DEBUG_PRINT("Service parse error");
+ latestError = ServiceMetaData::SFW_ERROR_PARSE_SERVICE;
+ parseError = true;
+ } else if (aXMLReader.tokenType() == QXmlStreamReader::Invalid) {
+ XQSERVICE_DEBUG_PRINT("Invalid XML");
+ latestError = ServiceMetaData::SFW_ERROR_INVALID_XML_FILE;
+ parseError = true;
+ }
+ }
+
+ if (serviceInterfaces.count() == 0 && latestError == 0) {
+ XQSERVICE_DEBUG_PRINT("No service interface");
+ latestError = ServiceMetaData::SFW_ERROR_NO_SERVICE_INTERFACE;
+ parseError = true;
+ }
+ if (parseError) {
+ clearMetadata();
+ }
+ XQSERVICE_DEBUG_PRINT("parseError: %d", parseError);
+ return !parseError;
+}
+
+/*!
+ Parses and extracts the interface metadata from the current xml <interface> node \n
+ Custome error codes: \n
+ SFW_ERROR_NO_INTERFACE_NAME in case no interface name in XML file \n
+ SFW_ERROR_PARSE_INTERFACE in case error parsing interface section \n
+ SFW_ERROR_INVALID_XML_FILE in case XML file is not valid \n
+ @param aXMLReader xml stream reader
+ @return true if the metadata was read properly, false if there is an error
+ */
+bool ServiceMetaData::processInterfaceElement(QXmlStreamReader &aXMLReader)
+{
+ XQSERVICE_DEBUG_PRINT("ServiceMetaData::processInterfaceElement");
+ Q_ASSERT(aXMLReader.isStartElement() && aXMLReader.name() == INTERFACE_TAG);
+ bool parseError = false;
+
+ //Read interface parameter
+ QString tmp;
+ SFWInterface aInterface("");
+ if (getAttributeValue(aXMLReader, NAME_TAG, tmp)) {
+ XQSERVICE_DEBUG_PRINT("Name attribute value");
+ aInterface = SFWInterface(tmp);
+ tmp.clear();
+ if (getAttributeValue(aXMLReader, INTERFACE_VERSION, tmp)) {
+ XQSERVICE_DEBUG_PRINT("Interface version value");
+ bool success = checkVersion(tmp);
+ if ( success ) {
+ aInterface.setVersion(tmp);
+ tmp.clear();
+ if (getAttributeValue(aXMLReader, INTERFACE_CAPABILITY, tmp)) {
+ XQSERVICE_DEBUG_PRINT("Interface capability value");
+ aInterface.setCapabilities(tmp.split(",", QString::SkipEmptyParts));
+ }
+ } else {
+ XQSERVICE_DEBUG_PRINT("Invalid interface version");
+ latestError = ServiceMetaData::SFW_ERROR_INVALID_VERSION;
+ parseError = true;
+ }
+ }
+ else{
+ XQSERVICE_DEBUG_PRINT("No interface version");
+ latestError = ServiceMetaData::SFW_ERROR_NO_INTERFACE_VERSION;
+ parseError = true;
+ }
+ } else {
+ XQSERVICE_DEBUG_PRINT("No interface name");
+ latestError = ServiceMetaData::SFW_ERROR_NO_INTERFACE_NAME;
+ parseError = true;
+ }
+
+ while (!parseError && !aXMLReader.atEnd()) {
+ aXMLReader.readNext();
+ //Read interface description
+ if (aXMLReader.isStartElement() && aXMLReader.name() == DESCRIPTION_TAG) {
+ XQSERVICE_DEBUG_PRINT("Interface description");
+ aInterface.setDescription(aXMLReader.readElementText());
+ //Found </interface>, leave the loop
+ } else if (aXMLReader.isEndElement() && aXMLReader.name() == INTERFACE_TAG) {
+ XQSERVICE_DEBUG_PRINT("Interface handled");
+ break;
+ } else if (aXMLReader.isStartElement() || aXMLReader.isEndElement()) {
+ XQSERVICE_DEBUG_PRINT("Interface parse error");
+ latestError = ServiceMetaData::SFW_ERROR_PARSE_INTERFACE;
+ parseError = true;
+ } else if (aXMLReader.tokenType() == QXmlStreamReader::Invalid) {
+ XQSERVICE_DEBUG_PRINT("Invalid XML");
+ latestError = ServiceMetaData::SFW_ERROR_INVALID_XML_FILE;
+ parseError = true;
+ }
+ }
+
+ if (!parseError) {
+ const QString ident = aInterface.name()+aInterface.version();
+ XQSERVICE_DEBUG_PRINT("ident: %s", qPrintable(ident));
+ if (duplicates.contains(ident.toLower())) {
+ XQSERVICE_DEBUG_PRINT("Duplicate interface");
+ latestError = ServiceMetaData::SFW_ERROR_DUPLICATED_INTERFACE;
+ parseError = true;
+ } else {
+ duplicates.insert(ident.toLower());
+ serviceInterfaces.append(aInterface);
+ }
+ }
+ XQSERVICE_DEBUG_PRINT("parseError: %d", parseError);
+ return !parseError;
+}
+
+bool ServiceMetaData::checkVersion(const QString &version)
+{
+ XQSERVICE_DEBUG_PRINT("ServiceMetaData::checkVersion");
+ //match x.y as version format
+ QRegExp rx("^([1-9][0-9]*)\\.(0+|[1-9][0-9]*)$");
+ int pos = rx.indexIn(version);
+ QStringList list = rx.capturedTexts();
+ bool success = false;
+ if (pos == 0 && list.count() == 3
+ && rx.matchedLength() == version.length() )
+ {
+ list[1].toInt(&success);
+ if ( success ) {
+ list[2].toInt(&success);
+ }
+ }
+ XQSERVICE_DEBUG_PRINT("success: %d", success);
+ return success;
+}
+
+/*!
+ * Clears the service metadata
+ *
+ */
+void ServiceMetaData::clearMetadata()
+{
+ XQSERVICE_DEBUG_PRINT("ServiceMetaData::clearMetadata");
+ serviceName.clear();
+ serviceFilePath.clear();
+ serviceDescription.clear();
+ serviceInterfaces.clear();
+ duplicates.clear();
+}
+
+QT_END_NAMESPACE