qthighway/xqserviceutil/src/xqservicemetadata/xqaiwinterfacedescriptor.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Fri, 14 May 2010 16:41:33 +0300
changeset 5 453da2cfceef
parent 1 2b40d63a9c3d
child 24 9d760f716ca8
permissions -rw-r--r--
Revision: 201017 Kit: 201019

/*
* Copyright (c) 2009 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:
*
*/

#include "xqservicelog.h"
#include <xqaiwinterfacedescriptor_p.h>
#include <xqaiwinterfacedescriptor.h>
#ifndef QT_NO_DATASTREAM
#include <qdatastream.h>
#endif

#include <QDebug>

//QT_BEGIN_NAMESPACE

/*!
    \class XQAiwInterfaceDescriptor
    \brief The XQAiwInterfaceDescriptor class identifies a service implementation.

    A service can implement multiple interfaces and each interface can have multiple implementations. 
    The XQAiwInterfaceDescriptor class enscapsulates this information, as illustrated
    by the diagram below.

    \image XQAiwInterfaceDescriptor.png Service-Interface-Implementation

    The major version tag indicates the interface version and the minor version tag identifies the implementation
    version. Subsequent versions of the same interface must be binary compatible to previous versions 
    of the same interface. 

    In the above example service A and B implement the interface \i com.nokia.qt.x.
    In fact Service A provides two different implementations for the very same interface. 
    This is indicated by the changed minor version number. Although Service B is 
    using the same interface it's implementation actually utilizes the second version of
    the interface \i com.nokia.qt.x. Binary compatibility guarantees that clients 
    who know version 1 can utilize version 2. If an existing interface has to be changed
    in a non-compatible way a new interface (name) is required.

    \section1 Namespaces

    A XQAiwInterfaceDescriptor (the quadruble of service name, 
    interface name, interface version and implementation version) uniquely 
    identifies a service implementation on a device. Interface names follow 
    the java namespace convention.
    
    The namespace \i com.nokia.qt.* is reserved for future Qt development.

    \sa QServiceFilter, QServiceManager
*/

/*!
    \enum XQAiwInterfaceDescriptor::PropertyKey

    This enum describes the possible property types which can be attached
    to a XQAiwInterfaceDescriptor.

    \value      Capabilities            The capabilities property is a QStringList and
                                        describes the capabilities that a service client
                                        would require to use the service if capability 
                                        checks are enforced.
    \value      Location                This property points to the location
                                        where the plug-in providing this service is stored.
                                        If the service is plug-in based the location is the
                                        name and/or path of the plugin.
    \value      ServiceDescription      This property provides a general description for
                                        the service.
    \value      InterfaceDescription    This property provides a description for the interface 
                                        implementation.
*/

/*!
    Creates a new XQAiwInterfaceDescriptor.
*/
XQAiwInterfaceDescriptor::XQAiwInterfaceDescriptor()
    :  d(0)
{
  XQSERVICE_DEBUG_PRINT("XQAiwInterfaceDescriptor");
  // Memory allocated in assigment operator !!!
}

/*!
    Destroys the XQAiwInterfaceDescriptor object.
*/
XQAiwInterfaceDescriptor::~XQAiwInterfaceDescriptor()
{
    XQSERVICE_DEBUG_PRINT("~XQAiwInterfaceDescriptor");
    if (d)
        delete d;
}

/*!
    Creates a copy of XQAiwInterfaceDescriptor contained in \a other.
*/
XQAiwInterfaceDescriptor::XQAiwInterfaceDescriptor(const XQAiwInterfaceDescriptor& other)
    : d(0)
{
    (*this) = other; //use assignment operator
}


/*!
    Copies the content of the XQAiwInterfaceDescriptor object contained 
    in \a other into this one.
*/
XQAiwInterfaceDescriptor& XQAiwInterfaceDescriptor::operator=(const XQAiwInterfaceDescriptor& other)
{
    XQSERVICE_DEBUG_PRINT("XQAiwInterfaceDescriptor: operator=");
    if ( !other.isValid() ) {
        XQSERVICE_DEBUG_PRINT("other is invalid !!!");
        if (d) 
            delete d;
        d = 0;
        return *this;  // Create empty descriptor
    }
    if (!d)
        d = new XQAiwInterfaceDescriptorPrivate;
    (*d) = *(other.d);
    XQSERVICE_DEBUG_PRINT("XQAiwInterfaceDescriptor: operator= done");
    return *this;
}

/*!
    Compares a XQAiwInterfaceDescriptor to \a other. Returns true if they 
    are equal and false otherwise.
*/
bool XQAiwInterfaceDescriptor::operator==(const XQAiwInterfaceDescriptor& other) const
{
    XQSERVICE_DEBUG_PRINT("XQAiwInterfaceDescriptor: operator==");
    
    if (! (isValid() && other.isValid()) )
        return false;

    if (!d)
        return false;

    if ((*d) == *(other.d))
    {
        XQSERVICE_DEBUG_PRINT("== true");
        return true;
    }
    
    XQSERVICE_DEBUG_PRINT("== false");
    return false;
}

/*!
    \fn bool XQAiwInterfaceDescriptor::operator!=(const XQAiwInterfaceDescriptor& other) const

    Compares a XQAiwInterfaceDescriptor to \a other. Returns true
    if they are not equal and false otherwise.
*/

/*!
    Returns true if this descriptor is valid; otherwise returns false.
*/
bool XQAiwInterfaceDescriptor::isValid() const
{
    XQSERVICE_DEBUG_PRINT("XQAiwInterfaceDescriptor:isValid");
    if (d)
    {
        XQSERVICE_DEBUG_PRINT("isValid=yes");
        return true;
    }
    XQSERVICE_DEBUG_PRINT("isValid=false");
    return false;
}

/*!
    Returns true if this implementation is provided for all users on the system.

    \sa QServiceManager::Scope
*/
bool XQAiwInterfaceDescriptor::inSystemScope() const
{
    return d ? d->systemScope : false;
}

/*!
    Returns the name of service that provides this implementation.
*/
QString XQAiwInterfaceDescriptor::serviceName() const
{
    return d ? d->serviceName : QString();
}

/*!
    Returns the name of the interface that is implemented.
*/
QString XQAiwInterfaceDescriptor::interfaceName() const
{
    return d ? d->interfaceName : QString();
}


/*!
    Returns the version of the interface. 
    
    Subsequent versions of an interface are binary compatible 
    to previous versions of the same interface. If an intcerface 
    is broken it must use a new interface name.
*/
int XQAiwInterfaceDescriptor::majorVersion() const
{
    return d ? d->major : -1;
}

/*!
    Returns the version of the implementation. 
*/
int XQAiwInterfaceDescriptor::minorVersion() const
{
    return d ? d->minor : -1;
}

/*!
    Returns the value for the property \a key; otherwise returns 
    an invalid QVariant.
*/
QVariant XQAiwInterfaceDescriptor::property(XQAiwInterfaceDescriptor::PropertyKey key) const
{
    if (d)
    {
        return d->properties.value(key);
    }
    return QVariant();
}

/*!
    Extension:
    Sets given property. To be used by service management only.
*/
bool XQAiwInterfaceDescriptor::setProperty(XQAiwInterfaceDescriptor::PropertyKey key, const QVariant value )
{
    XQSERVICE_DEBUG_PRINT("XQAiwInterfaceDescriptor::setPropery %d", key);
    if (key < ImplementationId)
    {
        return false;  // Do not allow changing other properties
    }
    
    if (!d)
        d = new XQAiwInterfaceDescriptorPrivate;  // Ensure allocation
    
    if (d)
    {
        d->properties[key] = value;
        return true;
    }
    return false;
}


/*!
    Returns the value for the custom property \a key; otherwise 
    returns a null string.
*/
QString XQAiwInterfaceDescriptor::customProperty(const QString& key) const
{
    XQSERVICE_DEBUG_PRINT("XQAiwInterfaceDescriptor::customProperty %s", qPrintable(key));
    QString val;
    if (d)
    {
        val = d->customProperties[key];
    }
    XQSERVICE_DEBUG_PRINT("XQAiwInterfaceDescriptor::customProperty value %s", qPrintable(val));
    
    return val;
}

QStringList XQAiwInterfaceDescriptor::customPropertyKeys() const
{
    XQSERVICE_DEBUG_PRINT("XQAiwInterfaceDescriptor::customPropertyKeys");
    if (d)
    {
        return d->customProperties.keys();
    }

    return QStringList();
}

#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug dbg, const XQAiwInterfaceDescriptor &desc)
{
    if (desc.isValid()) {
        QString interface = QString("%1 %2.%3").arg(desc.interfaceName())
                .arg(desc.majorVersion() < 0 ? '?' : desc.majorVersion())
                .arg(desc.minorVersion() < 0 ? '?' : desc.minorVersion());
        dbg.nospace() << "XQAiwInterfaceDescriptor(";
        dbg.nospace() << "service=" << desc.serviceName() << ", ";
        dbg.nospace() << "interface=" << interface;
        dbg.nospace() << ")";
    } else {
        dbg.nospace() << "XQAiwInterfaceDescriptor(invalid)";
    }
    return dbg.space();
}
#endif

#ifndef QT_NO_DATASTREAM

QDataStream &operator<<(QDataStream &out, const XQAiwInterfaceDescriptor::PropertyKey &k)
{
    out << qint8(k);
    return out;
}

QDataStream &operator>>(QDataStream &in, XQAiwInterfaceDescriptor::PropertyKey &k)
{
    quint8 key;
    in >> key;
    k = (XQAiwInterfaceDescriptor::PropertyKey)key;
    return in;
}
/*! 
    \fn QDataStream &operator<<(QDataStream &out, const XQAiwInterfaceDescriptor &dc)
    \relates XQAiwInterfaceDescriptor

    Writes service interface descriptor \a dc to the stream \a out and returns a reference
    to the stream.
*/

QDataStream &operator<<(QDataStream &out, const XQAiwInterfaceDescriptor &dc)
{
    const quint32 magicNumber = 0x77AFAFA;
    const quint16 majorVersion = 1;
    const quint16 minorVersion = 0;
    const qint8 valid = dc.isValid();
    out << magicNumber << majorVersion << minorVersion;
    out << valid;
    if (valid) {
       out << dc.d->serviceName; 
       out << dc.d->interfaceName;
       out << dc.d->major;
       out << dc.d->minor;
       out << dc.d->properties;
       out << dc.d->customProperties;
       out << dc.d->systemScope;
    }
    return out;
}

/*!
    \fn QDataStream &operator>>(QDataStream &in, XQAiwInterfaceDescriptor &dc)
    \relates XQAiwInterfaceDescriptor

    Reads a service interface descriptor into \a dc from the stream \a in and returns a
    reference to the stream.
*/
QDataStream &operator>>(QDataStream &in, XQAiwInterfaceDescriptor &dc)
{
    const quint32 magicNumber = 0x77AFAFA;
    quint32 storedMagicNumber;
    in >> storedMagicNumber;
    if (storedMagicNumber != magicNumber) {
        qWarning() << "Datastream doesn't provide searialized XQAiwInterfaceDescriptor";
        return in;
    }
    
    const quint16 currentMajorVersion = 1;
    quint16 majorVersion = 0;
    quint16 minorVersion = 0;

    in >> majorVersion >> minorVersion;
    if (majorVersion != currentMajorVersion) {
        qWarning() << "Unknown serialization format for XQAiwInterfaceDescriptor.";
        return in;
    }
    //Allow all minor versions.

    qint8 valid;
    in >> valid;
    if (valid) {
        if (!dc.isValid())
            dc.d = new XQAiwInterfaceDescriptorPrivate;
        in >> dc.d->serviceName;
        in >> dc.d->interfaceName;
        in >> dc.d->major;
        in >> dc.d->minor;
        in >> dc.d->properties;
        in >> dc.d->customProperties;
        in >> dc.d->systemScope;
    } else { //input stream contains invalid descriptor
        //use assignment operator
        dc = XQAiwInterfaceDescriptor();
    }

    return in;
}
#endif //QT_NO_DATASTREAM



//QT_END_NAMESPACE