tools/servicefw/servicefw.cpp
changeset 0 876b1a06bc25
equal deleted inserted replaced
-1:000000000000 0:876b1a06bc25
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the Qt Mobility Components.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include <stdio.h>
       
    43 
       
    44 #include <QtCore>
       
    45 #include <QTextStream>
       
    46 #include <qservicemanager.h>
       
    47 #include <QString>
       
    48 
       
    49 QT_USE_NAMESPACE
       
    50 
       
    51 QTM_USE_NAMESPACE
       
    52 
       
    53 class CommandProcessor : public QObject
       
    54 {
       
    55     Q_OBJECT
       
    56 
       
    57 public:
       
    58     CommandProcessor(QObject *parent = 0);
       
    59     ~CommandProcessor();
       
    60 
       
    61     void execute(const QStringList &options, const QString &cmd, const QStringList &args);
       
    62     void showUsage();
       
    63     static void showUsage(QTextStream *stream);
       
    64 
       
    65 public slots:
       
    66     void browse(const QStringList &args);
       
    67     void search(const QStringList &args);
       
    68     void add(const QStringList &args);
       
    69     void remove(const QStringList &args);
       
    70 
       
    71 private:
       
    72     bool setOptions(const QStringList &options);
       
    73     void showAllEntries();
       
    74     void showInterfaceInfo(const QServiceFilter &filter);
       
    75     void showServiceInfo(const QString &service);
       
    76 
       
    77     QServiceManager *serviceManager;
       
    78     QTextStream *stdoutStream;
       
    79 };
       
    80 
       
    81 CommandProcessor::CommandProcessor(QObject *parent)
       
    82     : QObject(parent),
       
    83       serviceManager(0),
       
    84       stdoutStream(new QTextStream(stdout))
       
    85 {
       
    86 }
       
    87 
       
    88 CommandProcessor::~CommandProcessor()
       
    89 {
       
    90     delete stdoutStream;
       
    91 }
       
    92 
       
    93 void CommandProcessor::execute(const QStringList &options, const QString &cmd, const QStringList &args)
       
    94 {
       
    95     if (cmd.isEmpty()) {
       
    96         *stdoutStream << "Error: no command given\n\n";
       
    97         showUsage();
       
    98         return;
       
    99     }
       
   100 
       
   101     if (!setOptions(options))
       
   102         return;
       
   103 
       
   104     int methodIndex = metaObject()->indexOfMethod(cmd.toAscii() + "(QStringList)");
       
   105     if (methodIndex < 0) {
       
   106         *stdoutStream << "Bad command: " << cmd << "\n\n";
       
   107         showUsage();
       
   108         return;
       
   109     }
       
   110 
       
   111     if (!metaObject()->method(methodIndex).invoke(this, Q_ARG(QStringList, args)))
       
   112         *stdoutStream << "Cannot invoke method for command:" << cmd << '\n';
       
   113 }
       
   114 
       
   115 void CommandProcessor::showUsage()
       
   116 {
       
   117     showUsage(stdoutStream);
       
   118 }
       
   119 
       
   120 void CommandProcessor::showUsage(QTextStream *stream)
       
   121 {
       
   122     *stream << "Usage: servicefw [options] <command> [command parameters]\n\n"
       
   123             "Commands:\n"
       
   124             "\tbrowse     List all registered services\n"
       
   125             "\tsearch     Search for a service or interface\n"
       
   126             "\tadd        Register a service\n"
       
   127             "\tremove     Unregister a service\n"
       
   128             "\n"
       
   129             "Options:\n"
       
   130             "\t--system   Use the system-wide services database instead of the\n"
       
   131             "\t           user-specific database\n"
       
   132             "\n";
       
   133 }
       
   134 
       
   135 void CommandProcessor::browse(const QStringList &args)
       
   136 {
       
   137     Q_UNUSED(args);
       
   138     showAllEntries();
       
   139 }
       
   140 
       
   141 void CommandProcessor::search(const QStringList &args)
       
   142 {
       
   143     if (args.isEmpty()) {
       
   144         *stdoutStream << "Usage:\n\tsearch <service|interface [version]>\n\n"
       
   145                 "Examples:\n"
       
   146                 "\tsearch SomeService\n"
       
   147                 "\tsearch com.nokia.SomeInterface\n"
       
   148                 "\tsearch com.nokia.SomeInterface 3.5\n"
       
   149                 "\tsearch com.nokia.SomeInterface 3.5+\n";
       
   150         return;
       
   151     }
       
   152 
       
   153     const QString &name = args[0];
       
   154     if (name.contains('.')) {
       
   155         QServiceFilter filter;
       
   156         if (args.count() > 1) {
       
   157             const QString &version = args[1];
       
   158             bool minimumMatch = version.endsWith('+');
       
   159             filter.setInterface(name,
       
   160                     minimumMatch ? (version.mid(0, version.length()-1)) : version,
       
   161                     minimumMatch ? QServiceFilter::MinimumVersionMatch : QServiceFilter::ExactVersionMatch);
       
   162             if (filter.interfaceName().isEmpty()) { // setInterface() failed
       
   163                 *stdoutStream << "Error: invalid interface version: " << version << '\n';
       
   164                 return;
       
   165             }
       
   166         } else {
       
   167             filter.setInterface(name);
       
   168         }
       
   169         showInterfaceInfo(filter);
       
   170     } else {
       
   171         showServiceInfo(name);
       
   172     }
       
   173 }
       
   174 
       
   175 static const char * const errorTable[] = {
       
   176     "No error", //0
       
   177     "Storage read error",
       
   178     "Invalid service location",
       
   179     "Invalid service xml",
       
   180     "Invalid service interface descriptor",
       
   181     "Service already exists",
       
   182     "Interface implementation already exists",
       
   183     "Loading of plug-in failed",
       
   184     "Service or interface not found",
       
   185     "Insufficient capabilities to access service",
       
   186     "Unknown error"
       
   187 };
       
   188 
       
   189 void CommandProcessor::add(const QStringList &args)
       
   190 {
       
   191     if (args.isEmpty()) {
       
   192         *stdoutStream << "Usage:\n\tadd <service-xml-file>\n";
       
   193         return;
       
   194     }
       
   195 
       
   196     const QString &xmlPath = args[0];
       
   197     if (!QFile::exists(xmlPath)) {
       
   198         *stdoutStream << "Error: cannot find file " << xmlPath << '\n';
       
   199         return;
       
   200     }
       
   201 
       
   202     if (serviceManager->addService(xmlPath)) {
       
   203         *stdoutStream << "Registered service at " << xmlPath << '\n';
       
   204     } else {
       
   205         int error = serviceManager->error();
       
   206         if (error > 11) //map anything larger than 11 to 11
       
   207             error = 11;
       
   208         *stdoutStream << "Error: cannot register service at " << xmlPath
       
   209                 << " (" << errorTable[error] << ")" << '\n';
       
   210     }
       
   211 }
       
   212 
       
   213 void CommandProcessor::remove(const QStringList &args)
       
   214 {
       
   215     if (args.isEmpty()) {
       
   216         *stdoutStream << "Usage:\n\tremove <service-name>\n";
       
   217         return;
       
   218     }
       
   219 
       
   220     const QString &service = args[0];
       
   221     if (serviceManager->removeService(service))
       
   222         *stdoutStream << "Unregistered service " << service << '\n';
       
   223     else
       
   224         *stdoutStream << "Error: cannot unregister service " << service << '\n';
       
   225 }
       
   226 
       
   227 bool CommandProcessor::setOptions(const QStringList &options)
       
   228 {
       
   229     if (serviceManager)
       
   230         delete serviceManager;
       
   231 
       
   232     QStringList opts = options;
       
   233     QMutableListIterator<QString> i(opts);
       
   234     while (i.hasNext()) {
       
   235         if (i.next() == "--system") {
       
   236             serviceManager = new QServiceManager(QService::SystemScope, this);
       
   237             i.remove();
       
   238         }
       
   239     }
       
   240 
       
   241     if (!opts.isEmpty()) {
       
   242         *stdoutStream << "Bad options: " << opts.join(" ") << "\n\n";
       
   243         showUsage();
       
   244         return false;
       
   245     }
       
   246 
       
   247     // other initialization, if not triggered by an option
       
   248     if (!serviceManager)
       
   249         serviceManager = new QServiceManager(this);
       
   250 
       
   251     return true;
       
   252 }
       
   253 
       
   254 void CommandProcessor::showAllEntries()
       
   255 {
       
   256     QStringList services = serviceManager->findServices();
       
   257     if (services.isEmpty())
       
   258         *stdoutStream << "No services found.\n";
       
   259     else if (services.count() == 1)
       
   260         *stdoutStream << "Found 1 service.\n\n";
       
   261     else
       
   262         *stdoutStream << "Found " << services.count() << " services.\n\n";
       
   263     foreach (const QString &service, services)
       
   264         showServiceInfo(service);
       
   265 }
       
   266 
       
   267 void CommandProcessor::showInterfaceInfo(const QServiceFilter &filter)
       
   268 {
       
   269     QString interface = filter.interfaceName();
       
   270     if (filter.majorVersion() >= 0 && filter.minorVersion() >= 0) {
       
   271         interface += QString(" %1.%2").arg(filter.majorVersion()).arg(filter.minorVersion());
       
   272         if (filter.versionMatchRule() == QServiceFilter::MinimumVersionMatch)
       
   273             interface += '+';
       
   274     }
       
   275 
       
   276     QList<QServiceInterfaceDescriptor> descriptors = serviceManager->findInterfaces(filter);
       
   277     if (descriptors.isEmpty()) {
       
   278         *stdoutStream << "Interface " << interface << " not found.\n";
       
   279         return;
       
   280     }
       
   281 
       
   282     *stdoutStream << interface << " is implemented by:\n";
       
   283     foreach (const QServiceInterfaceDescriptor &desc, descriptors)
       
   284         *stdoutStream << '\t' << desc.serviceName() << '\n';
       
   285 }
       
   286 
       
   287 void CommandProcessor::showServiceInfo(const QString &service)
       
   288 {
       
   289     QList<QServiceInterfaceDescriptor> descriptors = serviceManager->findInterfaces(service);
       
   290     if (descriptors.isEmpty()) {
       
   291         *stdoutStream << "Service " << service << " not found.\n";
       
   292         return;
       
   293     }
       
   294 
       
   295     QString description = descriptors[0].attribute(
       
   296             QServiceInterfaceDescriptor::ServiceDescription).toString();
       
   297     QStringList capabilities = descriptors[0].attribute(
       
   298             QServiceInterfaceDescriptor::Capabilities).toStringList();
       
   299 
       
   300     *stdoutStream << service << ":\n";
       
   301     if (!description.isEmpty())
       
   302         *stdoutStream << '\t' << description << '\n';
       
   303     *stdoutStream << "\tLibrary: " << descriptors[0].attribute(
       
   304                     QServiceInterfaceDescriptor::Location).toString() << '\n'
       
   305             << "\tCapabilities: " << (capabilities.isEmpty() ? "" : capabilities.join(", ")) << '\n'
       
   306             << "\tImplements:\n";
       
   307 
       
   308     foreach (const QServiceInterfaceDescriptor &desc, descriptors) {
       
   309         *stdoutStream << "\t\t" << desc.interfaceName() << ' '
       
   310                 << desc.majorVersion() << '.' << desc.minorVersion() << '\n';
       
   311     }
       
   312 }
       
   313 
       
   314 int main(int argc, char *argv[])
       
   315 {
       
   316     QCoreApplication app(argc, argv);
       
   317     QStringList args = QCoreApplication::arguments();
       
   318 
       
   319     if (args.count() == 1 || args.value(1) == "--help" || args.value(1) == "-h") {
       
   320         QTextStream stream(stdout);
       
   321         CommandProcessor::showUsage(&stream);
       
   322         return 0;
       
   323     }
       
   324 
       
   325     QStringList options;
       
   326     for (int i=1; i<args.count(); i++) {
       
   327         if (args[i].startsWith("--"))
       
   328             options += args[i];
       
   329     }
       
   330 
       
   331     CommandProcessor processor;
       
   332     processor.execute(options, args.value(options.count() + 1), args.mid(options.count() + 2));
       
   333     return 0;
       
   334 }
       
   335 
       
   336 #include "servicefw.moc"