remove remote applets support

remove the remote plasmoid support along QtJolie.
support for remote *dataengines* will probably come back, but in a bit different way
This commit is contained in:
Marco Martin 2013-02-11 21:38:18 +01:00
parent bfe5c1e942
commit f1eec52a74
119 changed files with 10 additions and 10300 deletions

View File

@ -94,38 +94,18 @@ set(plasma_LIB_SRCS
private/componentinstaller.cpp
private/datacontainer_p.cpp
private/dataenginemanager.cpp
private/dataengineservice.cpp
private/effects/halopainter.cpp
private/getsource.cpp
private/packages.cpp
private/packagejob.cpp
private/packagejobthread.cpp
private/plasmoidservice.cpp
private/remotedataengine.cpp
private/remoteservice.cpp
private/remoteservicejob.cpp
private/runnerjobs.cpp
private/serviceprovider.cpp
private/storage.cpp
private/storagethread.cpp
private/applet_p.cpp
private/containment_p.cpp
querymatch.cpp
remote/accessmanager.cpp
remote/accessappletjob.cpp
remote/authorizationinterface.cpp
remote/authorizationmanager.cpp
remote/authorizationrule.cpp
remote/clientpinrequest.cpp
remote/credentials.cpp
remote/denyallauthorization.cpp
remote/pinpairingauthorization.cpp
remote/pinpairingdialog.cpp
remote/serviceaccessjob.cpp
#remote/signing.cpp TODO: re-enable, needs gpgmepp though
remote/trustedonlyauthorization.cpp
runnercontext.cpp
runnermanager.cpp
runnersyntax.cpp
@ -139,20 +119,6 @@ set(plasma_LIB_SRCS
theme.cpp
version.cpp
#Temporary QtJolie branch
private/qtjolie-branch/qtjolie/abstractadaptor.cpp
private/qtjolie-branch/qtjolie/client.cpp
private/qtjolie-branch/qtjolie/clientthread.cpp
private/qtjolie-branch/qtjolie/value.cpp
private/qtjolie-branch/qtjolie/fault.cpp
private/qtjolie-branch/qtjolie/message.cpp
private/qtjolie-branch/qtjolie/metaservice.cpp
private/qtjolie-branch/qtjolie/pendingcall.cpp
private/qtjolie-branch/qtjolie/pendingcallwatcher.cpp
private/qtjolie-branch/qtjolie/pendingreply.cpp
private/qtjolie-branch/qtjolie/server.cpp
private/qtjolie-branch/qtjolie/serverthread.cpp
applet.cpp
containment.cpp
corona.cpp
@ -162,9 +128,6 @@ set(plasma_LIB_SRCS ${plasma_LIB_SRCS} private/effectwatcher.cpp)
kconfig_add_kcfg_files(plasma_LIB_SRCS data/kconfigxt/libplasma-theme-global.kcfgc)
kde4_add_ui_files(plasma_LIB_SRCS
remote/pinpairing.ui
private/publish.ui)
#NEPOMUK_GENERATE_FROM_ONTOLOGY(
# nwc.nrl
# ${metadata_test_BINARY_DIR}
@ -226,14 +189,6 @@ set(plasma_LIB_INCLUDES
plasma.h
${CMAKE_CURRENT_BINARY_DIR}/plasma_export.h
querymatch.h
remote/accessappletjob.h
remote/accessmanager.h
remote/authorizationmanager.h
remote/authorizationrule.h
remote/authorizationinterface.h
remote/clientpinrequest.h
remote/credentials.h
remote/serviceaccessjob.h
runnercontext.h
runnermanager.h
runnersyntax.h

View File

@ -69,7 +69,6 @@
#include <solid/powermanagement.h>
#endif
#include "authorizationrule.h"
#include "configloader.h"
#include "containment.h"
#include "corona.h"
@ -79,8 +78,6 @@
#include "svg.h"
#include "framesvg.h"
#include "private/framesvg_p.h"
#include "remote/authorizationmanager.h"
#include "remote/authorizationmanager_p.h"
#include "theme.h"
#include "paintutils.h"
#include "abstractdialogmanager.h"
@ -90,10 +87,7 @@
#include "private/containment_p.h"
#include "private/package_p.h"
#include "private/packages_p.h"
#include "private/plasmoidservice_p.h"
#include "private/remotedataengine_p.h"
#include "private/service_p.h"
#include "ui_publish.h"
namespace Plasma
@ -356,7 +350,7 @@ ConfigLoader *Applet::configScheme() const
DataEngine *Applet::dataEngine(const QString &name) const
{
return d->dataEngine(name, d->remoteLocation);
return d->dataEngine(name);
}
Package Applet::package() const
@ -800,43 +794,6 @@ bool Applet::hasConfigurationInterface() const
return d->hasConfigurationInterface;
}
void Applet::publish(AnnouncementMethods methods, const QString &resourceName)
{
if (!d->remotingService) {
d->remotingService = new PlasmoidService(this);
}
const QString resName = resourceName.isEmpty() ? i18nc("%1 is the name of a plasmoid, %2 the name of the machine that plasmoid is published on",
"%1 on %2", name(), QHostInfo::localHostName())
: resourceName;
#ifndef NDEBUG
kDebug() << "publishing package under name " << resName;
#endif
if (d->package && d->package->isValid()) {
d->remotingService->d->publish(methods, resName, d->package->metadata());
} else if (!d->package && d->appletDescription.isValid()) {
d->remotingService->d->publish(methods, resName, d->appletDescription);
} else {
delete d->remotingService;
d->remotingService = 0;
#ifndef NDEBUG
kDebug() << "Can not publish invalid applets.";
#endif
}
}
void Applet::unpublish()
{
if (d->remotingService) {
d->remotingService->d->unpublish();
}
}
bool Applet::isPublished() const
{
return d->remotingService && d->remotingService->d->isPublished();
}
void Applet::setHasConfigurationInterface(bool hasInterface)
{
if (hasInterface == d->hasConfigurationInterface) {
@ -880,7 +837,6 @@ void Applet::showConfigurationInterface()
return;
}
d->publishUI.publishCheckbox = 0;
if (d->package) {
KConfigDialog *dialog = 0;
@ -949,7 +905,6 @@ void Applet::showConfigurationInterface()
if (hasPages) {
d->addGlobalShortcutsPage(dialog);
d->addPublishPage(dialog);
dialog->show();
} else {
delete dialog;

View File

@ -709,19 +709,6 @@ class PLASMA_EXPORT Applet : public QObject
*/
void runAssociatedApplication();
//REMOTE WIDGETS
/**
* Publishes and optionally announces this applet on the network for remote access.
* @param methods the methods to use for announcing this applet.
* @param resourceName the name under which this applet will be published (has to be unique
* for each machine)
*/
void publish(Plasma::AnnouncementMethods methods, const QString &resourceName);
void unpublish();
bool isPublished() const;
//Completely UI-specific, remove or move to scriptengine
/**
* Shows a busy indicator that overlays the applet
@ -856,7 +843,6 @@ class PLASMA_EXPORT Applet : public QObject
Q_PRIVATE_SLOT(d, void cleanUpAndDelete())
Q_PRIVATE_SLOT(d, void configDialogFinished())
Q_PRIVATE_SLOT(d, void updateShortcuts())
Q_PRIVATE_SLOT(d, void publishCheckboxStateChanged(int state))
Q_PRIVATE_SLOT(d, void globalShortcutChanged())
Q_PRIVATE_SLOT(d, void propagateConfigChanged())

View File

@ -36,6 +36,7 @@
#include <kaction.h>
#include <kcoreauthorized.h>
#include <klocalizedstring.h>
#include <kmenu.h>
#include <kmessagebox.h>
#include <qmimedatabase.h>
@ -55,9 +56,6 @@
#include "pluginloader.h"
#include "svg.h"
#include "remote/accessappletjob.h"
#include "remote/accessmanager.h"
#include "private/applet_p.h"
#include "private/containmentactionspluginsconfig_p.h"

View File

@ -38,14 +38,10 @@
#include "datacontainer.h"
#include "package.h"
#include "pluginloader.h"
#include "remote/authorizationmanager.h"
#include "remote/authorizationmanager_p.h"
#include "service.h"
#include "scripting/dataenginescript.h"
#include "private/datacontainer_p.h"
#include "private/dataengineservice_p.h"
#include "private/remotedataengine_p.h"
#include "private/service_p.h"
#include "private/storage_p.h"
@ -415,40 +411,6 @@ Service* DataEngine::createDefaultService(QObject *parent)
return PluginLoader::self()->loadService(d->serviceName, args, parent);
}
void DataEnginePrivate::publish(AnnouncementMethods methods, const QString &name)
{
if (!publishedService) {
publishedService = new DataEngineService(q);
}
//QString resourceName =
//i18nc("%1 is the name of a dataengine, %2 the name of the machine that engine is published
//on",
//"%1 dataengine on %2", name(), AuthorizationManager::self()->d->myCredentials.name());
#ifndef NDEBUG
kDebug() << "name: " << name;
#endif
publishedService->d->publish(methods, name);
}
void DataEnginePrivate::unpublish(const QString &name)
{
Q_UNUSED(name)
if (publishedService) {
publishedService->d->unpublish();
}
}
bool DataEnginePrivate::isPublished() const
{
if (publishedService) {
return publishedService->d->isPublished();
} else {
return false;
}
}
Package DataEngine::package() const
{
return d->package ? *d->package : Package();
@ -492,8 +454,7 @@ DataEnginePrivate::DataEnginePrivate(DataEngine *e, const KPluginInfo &info)
minPollingInterval(-1),
valid(true),
script(0),
package(0),
publishedService(0)
package(0)
{
updateTimestamp.start();
@ -612,10 +573,6 @@ void DataEnginePrivate::connectSource(DataContainer *s, QObject *visualization,
{
//kDebug() << "connect source called" << s->objectName() << "with interval" << pollingInterval;
//FIXME: at the moment a remote dataengine can only poll, a push mechanism will be needed instead
if (pollingInterval == 0 && qobject_cast<RemoteDataEngine *>(q)) {
pollingInterval = 5000;
}
if (pollingInterval > 0) {
// never more frequently than allowed, never more than 20 times per second
uint min = qMax(50, minPollingInterval); // for qMax below

View File

@ -28,7 +28,6 @@
#include <kdebug.h>
#include "private/dataenginemanager_p.h"
#include "private/remotedataengine_p.h"
#include "servicejob.h"
namespace Plasma
@ -45,18 +44,6 @@ void DataEngineConsumerPrivate::slotJobFinished(Plasma::ServiceJob *job)
#ifndef NDEBUG
kDebug() << "pair = " << pair;
#endif
if (!remoteEngines.contains(pair)) {
#ifndef NDEBUG
kDebug() << "engine does not exist yet!";
#endif
} else {
QUrlPathInfo engineLocation = QUrlPathInfo(QUrl(location));
engineLocation.setFileName(job->result().toString());
#ifndef NDEBUG
kDebug() << "setting location : " << engineLocation.url();
#endif
remoteEngines[pair]->setLocation(engineLocation.url());
}
}
void DataEngineConsumerPrivate::slotServiceReady(Plasma::Service *plasmoidService)
@ -87,36 +74,6 @@ void DataEngineConsumerPrivate::slotServiceReady(Plasma::Service *plasmoidServic
this, SLOT(slotJobFinished(Plasma::ServiceJob*)));
}
DataEngine *DataEngineConsumerPrivate::remoteDataEngine(const QString &name, const QUrl &location)
{
QPair<QString, QString> pair(location.toString(), name);
#ifndef NDEBUG
kDebug() << "pair = " << pair;
#endif
if (remoteEngines.contains(pair)) {
#ifndef NDEBUG
kDebug() << "existing remote dataengine at " << location;
#endif
return remoteEngines[pair];
}
#ifndef NDEBUG
kDebug() << "new remote dataengine at " << location;
#endif
RemoteDataEngine *engine = new RemoteDataEngine(QUrl());
remoteEngines[pair] = engine;
Service *plasmoidService = Service::access(location);
plasmoidService->setDestination(location.toString());
engineNameForService[plasmoidService] = name;
#ifndef NDEBUG
kDebug() << "name = " << name;
#endif
connect(plasmoidService, SIGNAL(serviceReady(Plasma::Service*)),
this, SLOT(slotServiceReady(Plasma::Service*)));
return engine;
}
DataEngineConsumer::DataEngineConsumer()
: d(new DataEngineConsumerPrivate)
{
@ -131,12 +88,8 @@ DataEngineConsumer::~DataEngineConsumer()
delete d;
}
DataEngine *DataEngineConsumer::dataEngine(const QString &name, const QUrl &location)
DataEngine *DataEngineConsumer::dataEngine(const QString &name)
{
if (!location.isEmpty()) {
return d->remoteDataEngine(name, location);
}
if (d->loadedEngines.contains(name)) {
DataEngine *engine = DataEngineManager::self()->engine(name);
if (engine->isValid()) {

View File

@ -64,13 +64,8 @@ public:
*
* @param name the name of the DataEngine. This corresponds to the plugin name
* of the DataEngine.
* @param location if a non-empty URI is passed in, then a connection with a
* remote DataEngine at the location is attempted to be made.
* The returned pointer is a proxy object for this connection.
* In the common case, location is always an empty URI (QUrl())
* and the DataEngine is loaded locally.
*/
DataEngine *dataEngine(const QString &name, const QUrl &location = QUrl());
DataEngine *dataEngine(const QString &name);
private:
DataEngineConsumerPrivate * const d;

View File

@ -27,12 +27,14 @@
#include <QFile>
#include <QHostInfo>
#include <QVBoxLayout>
#include <qstandardpaths.h>
#include <kaction.h>
#include <kdebug.h>
#include <kiconloader.h>
#include <klocale.h>
#include <klocalizedstring.h>
#include <kkeysequencewidget.h>
#include <kstandarddirs.h>
#include <kglobal.h>
@ -44,12 +46,6 @@
#include "scripting/appletscript.h"
#include "private/containment_p.h"
#if ENABLE_REMOTE_WIDGETS
#include "remote/authorizationmanager.h"
#include "remote/authorizationmanager_p.h"
#include "remote/authorizationrule.h"
#endif
namespace Plasma
{
@ -321,7 +317,6 @@ KConfigDialog *AppletPrivate::generateGenericConfigDialog()
void AppletPrivate::addStandardConfigurationPages(KConfigDialog *dialog)
{
addGlobalShortcutsPage(dialog);
addPublishPage(dialog);
}
void AppletPrivate::addGlobalShortcutsPage(KConfigDialog *dialog)
@ -349,40 +344,6 @@ void AppletPrivate::addGlobalShortcutsPage(KConfigDialog *dialog)
#endif
}
void AppletPrivate::addPublishPage(KConfigDialog *dialog)
{
#if ENABLE_REMOTE_WIDGETS
QWidget *page = new QWidget;
publishUI.setupUi(page);
publishUI.publishCheckbox->setChecked(q->isPublished());
QObject::connect(publishUI.publishCheckbox, SIGNAL(clicked(bool)), dialog, SLOT(settingsModified()));
publishUI.allUsersCheckbox->setEnabled(q->isPublished());
QObject::connect(publishUI.allUsersCheckbox, SIGNAL(clicked(bool)), dialog, SLOT(settingsModified()));
QString resourceName =
i18nc("%1 is the name of a plasmoid, %2 the name of the machine that plasmoid is published on",
"%1 on %2", q->name(), QHostInfo::localHostName());
if (AuthorizationManager::self()->d->matchingRule(resourceName, Credentials())) {
publishUI.allUsersCheckbox->setChecked(true);
} else {
publishUI.allUsersCheckbox->setChecked(false);
}
q->connect(publishUI.publishCheckbox, SIGNAL(stateChanged(int)),
q, SLOT(publishCheckboxStateChanged(int)));
dialog->addPage(page, i18n("Share"), "applications-internet");
#endif
}
void AppletPrivate::publishCheckboxStateChanged(int state)
{
if (state == Qt::Checked) {
publishUI.allUsersCheckbox->setEnabled(true);
} else {
publishUI.allUsersCheckbox->setEnabled(false);
}
}
void AppletPrivate::configDialogFinished()
{
if (shortcutEditor) {
@ -393,35 +354,6 @@ void AppletPrivate::configDialogFinished()
}
}
#if ENABLE_REMOTE_WIDGETS
if (KConfigDialog::exists(configDialogId()) && publishUI.publishCheckbox) {
q->config().writeEntry("Share", publishUI.publishCheckbox->isChecked());
if (publishUI.publishCheckbox->isChecked()) {
QString resourceName =
i18nc("%1 is the name of a plasmoid, %2 the name of the machine that plasmoid is published on",
"%1 on %2", q->name(), QHostInfo::localHostName());
q->publish(Plasma::ZeroconfAnnouncement, resourceName);
if (publishUI.allUsersCheckbox->isChecked()) {
if (!AuthorizationManager::self()->d->matchingRule(resourceName, Credentials())) {
AuthorizationRule *rule = new AuthorizationRule(resourceName, "");
rule->setPolicy(AuthorizationRule::Allow);
rule->setTargets(AuthorizationRule::AllUsers);
AuthorizationManager::self()->d->rules.append(rule);
}
} else {
AuthorizationRule *matchingRule =
AuthorizationManager::self()->d->matchingRule(resourceName, Credentials());
if (matchingRule) {
AuthorizationManager::self()->d->rules.removeAll(matchingRule);
}
}
} else {
q->unpublish();
}
}
#endif
if (!configLoader) {
// the config loader will trigger this for us, so we don't need to.
propagateConfigChanged();

View File

@ -32,7 +32,6 @@
#include "plasma/applet.h"
#include "plasma/dataengineconsumer.h"
#include "plasma/ui_publish.h"
class KKeySequenceWidget;
@ -159,7 +158,6 @@ public:
ItemStatus itemStatus;
KUrl remoteLocation;
Ui::publishWidget publishUI;
// the applet can change size policy by itself, so save the old one for eventual restore
QSizePolicy preferredSizePolicy;

View File

@ -34,6 +34,7 @@
#include <kcoreauthorized.h>
#include <kiconloader.h>
#include <klocale.h>
#include <klocalizedstring.h>
#include <kurlmimedata.h>
#include <kwindowsystem.h>
@ -51,9 +52,6 @@
#include "pluginloader.h"
#include "svg.h"
#include "remote/accessappletjob.h"
#include "remote/accessmanager.h"
#include "private/applet_p.h"
#include "private/containmentactionspluginsconfig_p.h"

View File

@ -62,21 +62,6 @@ class DataEnginePrivate
**/
bool isUsed() const;
/**
* @param methods ways to announce this engine on the network.
*/
void publish(AnnouncementMethods methods, const QString &name);
/**
* remove this engine from the network.
*/
void unpublish(const QString &name = QString());
/**
* @return whether or not this engine is published.
*/
bool isPublished() const;
/**
* a datacontainer has been destroyed, clean up stuff
*/
@ -113,7 +98,6 @@ class DataEnginePrivate
QString engineName;
QString serviceName;
Package *package;
Service *publishedService;
QString waitingSourceRequest;
};

View File

@ -30,7 +30,6 @@ namespace Plasma
{
class DataEngineConsumer;
class RemoteDataEngine;
class Service;
class ServiceMonitor;
class ServiceJob;
@ -41,9 +40,7 @@ class DataEngineConsumerPrivate : public QObject
public:
QSet<QString> loadedEngines;
QMap<QPair<QString, QString>, RemoteDataEngine*> remoteEngines;
QMap<Service*, QString> engineNameForService;
DataEngine *remoteDataEngine(const QString &name, const QUrl &location);
public Q_SLOTS:
void slotJobFinished(Plasma::ServiceJob *job);

View File

@ -1,59 +0,0 @@
/*
* Copyright © 2009 Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2 as
* published by the Free Software Foundation
*
* 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "dataengineservice_p.h"
#include "../dataengine.h"
#include "getsource_p.h"
#include <kdebug.h>
namespace Plasma
{
DataEngineService::DataEngineService(DataEngine *engine)
: Plasma::Service(engine),
m_engine(engine)
{
setName("dataengineservice");
engine->connectAllSources(this, 1000);
connect(engine, SIGNAL(sourceAdded(QString)), this, SLOT(sourceAdded(QString)));
}
Plasma::ServiceJob* DataEngineService::createJob(const QString& operation, QHash<QString,QVariant>& parameters)
{
return new GetSource(m_engine, operation, parameters, this);
}
void DataEngineService::dataUpdated(QString source, Plasma::DataEngine::Data data)
{
if (data != m_data[source]) {
m_data[source] = data;
m_peersAlreadyUpdated[source] = QStringList();
}
}
void DataEngineService::sourceAdded(QString source)
{
m_engine->connectSource(source, this, 1000);
}
}
#include "moc_dataengineservice_p.cpp"

View File

@ -1,60 +0,0 @@
/*
* Copyright © 2009 Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2 as
* published by the Free Software Foundation
*
* 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef PLASMA_DATAENGINESERVICE_P_H
#define PLASMA_DATAENGINESERVICE_P_H
#include <QStringList>
#include "../dataengine.h"
#include "../service.h"
namespace Plasma
{
class DataEngine;
class GetSource;
class DataEngineService : public Plasma::Service
{
Q_OBJECT
public:
DataEngineService(DataEngine *engine);
public Q_SLOTS:
void dataUpdated(QString source, Plasma::DataEngine::Data data);
protected:
Plasma::ServiceJob* createJob(const QString& operation,
QHash<QString,QVariant>& parameters);
private Q_SLOTS:
void sourceAdded(QString source);
private:
DataEngine *m_engine;
QHash<QString, QStringList> m_peersAlreadyUpdated;
QHash<QString, DataEngine::Data> m_data;
friend class GetSource;
};
}
#endif // PLASMA_DATAENGINESERVICE_P_H

View File

@ -1,83 +0,0 @@
/*
* Copyright © 2008 Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2 as
* published by the Free Software Foundation
*
* 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "getsource_p.h"
#include "authorizationmanager_p.h"
#include "dataengineservice_p.h"
#include "service_p.h"
#include "../remote/authorizationmanager.h"
#include "../remote/authorizationrule.h"
#include "../dataengine.h"
#include "../service.h"
#include <kdebug.h>
namespace Plasma
{
GetSource::GetSource(DataEngine *engine, const QString& operation,
QHash<QString,QVariant>& parameters,
DataEngineService *service)
: ServiceJob(QString("publickey"), operation, parameters, service),
m_engine(engine),
m_service(service)
{
}
void GetSource::start()
{
#ifndef NDEBUG
kDebug() << "Trying to perform the action" << operationName();
#endif
//TODO: check with capabilities before performing actions.
if (operationName() == "GetSource") {
QString source = parameters().value("SourceName").toString();
QString UUID = parameters().value("UUID").toString();
if (!m_service->m_peersAlreadyUpdated[source].contains(UUID)) {
m_service->m_peersAlreadyUpdated[source].append(UUID);
setResult(m_service->m_data[source]);
} else {
setResult(false); //no update needed
}
} else if (operationName() == "GetSourceNames") {
setResult(m_engine->sources());
} else if (operationName() == "ServiceForSource") {
QString source = parameters().value("SourceName").toString();
Service *service = m_engine->serviceForSource(source);
QString serviceName = "plasma-service-" + service->name();
#ifndef NDEBUG
kDebug() << "serviceForSource: getting source " << serviceName;
#endif
service->d->publish(Plasma::NoAnnouncement, serviceName);
if (!AuthorizationManager::self()->d->matchingRule(serviceName, identity())) {
AuthorizationRule *rule = new AuthorizationRule(serviceName, identity().id());
rule->setPolicy(AuthorizationRule::Allow);
AuthorizationManager::self()->d->rules.append(rule);
}
setResult(serviceName);
}
}
}
#include "moc_getsource_p.cpp"

View File

@ -1,48 +0,0 @@
/*
* Copyright © 2009 Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2 as
* published by the Free Software Foundation
*
* 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef GETSOURCE_H
#define GETSOURCE_H
#include "../servicejob.h"
namespace Plasma
{
class DataEngine;
class DataEngineService;
class GetSource : public Plasma::ServiceJob
{
Q_OBJECT
public:
GetSource(DataEngine *engine, const QString& operation,
QHash<QString,QVariant>& parameters,
DataEngineService *service = 0);
void start();
private:
DataEngine *m_engine;
DataEngineService *m_service;
};
}
#endif //JOBVIEW_H

View File

@ -1,148 +0,0 @@
/*
* Copyright © 2009 Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2 as
* published by the Free Software Foundation
*
* 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "plasmoidservice_p.h"
#include "authorizationmanager_p.h"
#include "dataengineconsumer.h"
#include <plasma/applet.h>
#include <plasma/dataengine.h>
#include <plasma/private/dataengine_p.h>
#include <plasma/remote/authorizationmanager.h>
#include <plasma/remote/authorizationrule.h>
#include <plasma/service.h>
#include <plasma/servicejob.h>
#include <kdebug.h>
#include <kzip.h>
#include <kservicetypetrader.h>
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QHostInfo>
namespace Plasma
{
PlasmoidServiceJob::PlasmoidServiceJob(const QString &destination,
const QString &operation,
QHash<QString,QVariant>& parameters,
PlasmoidService *service)
: Plasma::ServiceJob(destination, operation, parameters,
static_cast<Plasma::Service*>(service)),
m_service(service)
{
}
void PlasmoidServiceJob::start()
{
if (operationName() == "GetPackage") {
#ifndef NDEBUG
kDebug() << "sending " << m_service->m_packagePath;
#endif
if (m_service->m_packagePath.isEmpty()) {
// just return the plugin name in this case
setResult(m_service->m_pluginName);
} else {
QFileInfo fileInfo(m_service->m_packagePath);
if (fileInfo.exists() && fileInfo.isAbsolute()) {
#ifndef NDEBUG
kDebug() << "file exists, let's try and read it";
#endif
QFile file(m_service->m_packagePath);
file.open(QIODevice::ReadOnly);
setResult(file.readAll());
} else {
setResult(QString());
}
}
} else if (operationName() == "GetMetaData") {
QFile file(m_service->m_metadata);
setResult(file.readAll());
} else if (operationName() == "DataEngine") {
DataEngine *engine = m_service->dataEngine(parameters()["EngineName"].toString());
QString serviceName = "plasma-dataengine-" + parameters()["EngineName"].toString();
engine->d->publish(NoAnnouncement, serviceName);
if (!AuthorizationManager::self()->d->matchingRule(serviceName, identity())) {
AuthorizationRule *rule = new AuthorizationRule(serviceName, identity().id());
rule->setPolicy(AuthorizationRule::Allow);
AuthorizationManager::self()->d->rules.append(rule);
}
setResult(serviceName);
}
setResult(false);
}
PlasmoidService::PlasmoidService(Applet *applet)
: Plasma::Service(applet),
m_pluginName(applet->pluginName())
{
setName("plasmoidservice");
if (applet->package().isValid()) {
const QString root = applet->package().path();
m_metadata = root + "metadata.desktop";
m_tempFile.open();
m_packagePath = m_tempFile.fileName();
m_tempFile.close();
// put everything into a zip archive
KZip creation(m_packagePath);
creation.setCompression(KZip::NoCompression);
if (creation.open(QIODevice::WriteOnly)) {
QDir dir(root);
foreach (const QString &entry, dir.entryList(QDir::Files)) {
creation.addLocalFile(root + entry, entry);
}
foreach (const QString &entry, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) {
creation.addLocalDirectory(root + entry, entry);
}
creation.close();
} else {
#ifndef NDEBUG
kDebug() << "could not open archive";
#endif
}
} else {
#ifndef NDEBUG
kDebug() << "applet lacks a valid package";
#endif
const QString constraint = QString("[X-KDE-PluginInfo-Name] == '%1'").arg(applet->pluginName());
KService::List offers = KServiceTypeTrader::self()->query("Plasma/Applet", constraint);
if (!offers.isEmpty()) {
m_metadata = offers.first()->entryPath();
}
}
}
Plasma::ServiceJob* PlasmoidService::createJob(const QString& operation, QHash<QString,QVariant>& parameters)
{
return new PlasmoidServiceJob(destination(), operation, parameters, this);
}
}
#include "moc_plasmoidservice_p.cpp"

View File

@ -1,76 +0,0 @@
/*
* Copyright © 2009 Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2 as
* published by the Free Software Foundation
*
* 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef PLASMOIDSERVICE_H
#define PLASMOIDSERVICE_H
#include "dataengineconsumer.h"
#include "../package.h"
#include "../service.h"
#include "../servicejob.h"
#include <qtemporaryfile.h>
namespace Plasma
{
class Applet;
class DataEngine;
class GetSource;
class PlasmoidService;
class PlasmoidServiceJob : public ServiceJob
{
Q_OBJECT
public:
PlasmoidServiceJob(const QString &destination,
const QString &operation,
QHash<QString,QVariant>& parameters,
PlasmoidService *parent);
void start();
private:
PlasmoidService *m_service;
QString m_pluginName;
};
class PlasmoidService : public Service, DataEngineConsumer
{
Q_OBJECT
public:
PlasmoidService(Applet *applet);
protected:
Plasma::ServiceJob* createJob(const QString& operation, QHash<QString,QVariant>& parameters);
private:
QString m_packagePath;
QString m_metadata;
QString m_pluginName;
QTemporaryFile m_tempFile;
friend class PlasmoidServiceJob;
};
}
#endif

View File

@ -1,5 +0,0 @@
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_TO_ASCII")
add_subdirectory(qtjolie)
add_subdirectory(includes)
add_subdirectory(tests)

View File

@ -1,12 +0,0 @@
install( FILES
QtJolie/AbstractAdaptor
QtJolie/Client
QtJolie/Fault
QtJolie/Message
QtJolie/MetaService
QtJolie/PendingCall
QtJolie/PendingCallWatcher
QtJolie/PendingReply
QtJolie/Server
QtJolie/Value
DESTINATION ${INCLUDE_INSTALL_DIR}/QtJolie COMPONENT Devel)

View File

@ -1,2 +0,0 @@
#include "../qtjolie/abstractadaptor.h"

View File

@ -1,2 +0,0 @@
#include "../qtjolie/client.h"

View File

@ -1,2 +0,0 @@
#include "../qtjolie/fault.h"

View File

@ -1,2 +0,0 @@
#include "../qtjolie/message.h"

View File

@ -1,2 +0,0 @@
#include "../qtjolie/metaservice.h"

View File

@ -1,2 +0,0 @@
#include "../qtjolie/pendingcall.h"

View File

@ -1,2 +0,0 @@
#include "../qtjolie/pendingcallwatcher.h"

View File

@ -1,2 +0,0 @@
#include "../qtjolie/pendingreply.h"

View File

@ -1,2 +0,0 @@
#include "../qtjolie/server.h"

View File

@ -1,2 +0,0 @@
#include "../qtjolie/value.h"

View File

@ -1,51 +0,0 @@
project(QtJolie)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/../
${CMAKE_CURRENT_BINARY_DIR}
${QT_INCLUDE_DIR})
set(qtjolie_LIB_SRCS
abstractadaptor.cpp
client.cpp
clientthread.cpp
value.cpp
fault.cpp
message.cpp
metaservice.cpp
pendingcall.cpp
pendingcallwatcher.cpp
pendingreply.cpp
server.cpp
serverthread.cpp
)
kde4_add_library(QtJolie SHARED ${qtjolie_LIB_SRCS})
target_link_libraries(QtJolie ${QT_QTNETWORK_LIBRARY})
install(TARGETS QtJolie
DESTINATION ${LIB_INSTALL_DIR})
set_target_properties(QtJolie PROPERTIES VERSION 1.0.0 SOVERSION 1)
install(FILES
abstractadaptor.h
client.h
value.h
fault.h
message.h
metaservice.h
pendingcall.h
pendingcallwatcher.h
pendingreply.h
server.h
DESTINATION ${INCLUDE_INSTALL_DIR}/qtjolie COMPONENT Devel)
if(NOT WIN32) # pkgconfig file
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/QtJolie.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/QtJolie.pc @ONLY)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/QtJolie.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
endif(NOT WIN32)
configure_file("QtJolie.prf.cmake" "${CMAKE_BINARY_DIR}/QtJolie.prf" @ONLY)
install(FILES "${CMAKE_BINARY_DIR}/QtJolie.prf" DESTINATION ${CMAKE_INSTALL_PREFIX}/mkspecs/features)

View File

@ -1,11 +0,0 @@
prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=@EXEC_INSTALL_PREFIX@
libdir=@LIB_INSTALL_DIR@
includedir=@INCLUDE_INSTALL_DIR@
Name: QtJolie
Description: A QtDbus like API for JOLIE
Version: 1.0.0
Requires: QtCore
Libs: -L${libdir} -llibQtJolie
Cflags: -I${includedir}

View File

@ -1,13 +0,0 @@
QTJOLIE_INCDIR = @INCLUDE_INSTALL_DIR@
QTJOLIE_LIBDIR = @LIB_INSTALL_DIR@
CONFIG *= qt
INCLUDEPATH += $$QTJOLIE_INCDIR
LIBS += -L$$QTJOLIE_LIBDIR
LINKAGE = -llibQtJolie
CONFIG(debug, debug|release) {
windows:LINKAGE = -llibQtJolied
mac:LINKAGE = -llibQtJolie_debug
}
LIBS += $$LINKAGE

View File

@ -1,43 +0,0 @@
/**
* This file is part of the KDE project
* Copyright (C) 2009 Kevin Ottens <ervin@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "abstractadaptor.h"
namespace Jolie
{
class AbstractAdaptorPrivate
{
};
}
using namespace Jolie;
AbstractAdaptor::AbstractAdaptor(QObject *parent)
: QObject(parent), d(new AbstractAdaptorPrivate)
{
}
AbstractAdaptor::~AbstractAdaptor()
{
delete d;
}
#include "moc_abstractadaptor.cpp"

View File

@ -1,53 +0,0 @@
/**
* This file is part of the KDE project
* Copyright (C) 2009 Kevin Ottens <ervin@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef QTJOLIE_ABSTRACTADAPTOR_H
#define QTJOLIE_ABSTRACTADAPTOR_H
#include <QtCore/QObject>
namespace Jolie
{
class AbstractAdaptorPrivate;
class Server;
class ServerPrivate;
class Message;
class Q_DECL_EXPORT AbstractAdaptor : public QObject
{
Q_OBJECT
protected:
AbstractAdaptor(QObject *parent = 0);
public:
~AbstractAdaptor();
private:
virtual void relay(Server *server, int clientId, const Message &message) = 0;
friend class ServerPrivate;
AbstractAdaptorPrivate * const d;
};
} // namespace Jolie
#endif

View File

@ -1,79 +0,0 @@
/**
* This file is part of the KDE project
* Copyright (C) 2009 Kevin Ottens <ervin@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "client.h"
#include "client_p.h"
#include "clientthread_p.h"
#include "message.h"
#include "pendingcall.h"
#include "pendingreply.h"
using namespace Jolie;
Client::Client(const QString &hostName, quint16 port)
: d(new ClientPrivate(this))
{
d->readerThread = new ClientThread(hostName, port, d);
d->readerThread->start();
}
Client::~Client()
{
delete d->readerThread;
delete d;
}
Client::Error Client::error() const
{
return d->error;
}
QString Client::errorString() const
{
return d->errorString;
}
PendingCall Client::asyncCall(const Message &message)
{
Q_ASSERT(!d->pendingCalls.contains(message.id()));
d->pendingCalls[message.id()] = new PendingCallPrivate(message);
d->readerThread->sendMessage(message);
return PendingCall(d->pendingCalls[message.id()]);
}
Message Client::call(const Message &message)
{
PendingReply pending = asyncCall(message);
pending.waitForFinished();
return pending.reply();
}
void Client::callNoReply(const Message &message)
{
d->readerThread->sendMessage(message);
}
void ClientPrivate::messageReceived(const Message &message)
{
QExplicitlySharedDataPointer<PendingCallPrivate> pending = pendingCalls.take(message.id());
pending->setReply(message);
}

View File

@ -1,63 +0,0 @@
/**
* This file is part of the KDE project
* Copyright (C) 2009 Kevin Ottens <ervin@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef QTJOLIE_CLIENT_H
#define QTJOLIE_CLIENT_H
#include <QtCore/QtGlobal>
class QIODevice;
class QObject;
namespace Jolie
{
class ClientPrivate;
class Message;
class PendingCall;
class Q_DECL_EXPORT Client
{
public:
enum Error
{
NoError,
UnexpectedClose,
UnkownError
};
explicit Client(const QString &hostName, quint16 port);
~Client();
Error error() const;
QString errorString() const;
PendingCall asyncCall(const Message &message);
Message call(const Message &message);
void callNoReply(const Message &message);
private:
friend class ClientPrivate;
ClientPrivate * const d;
};
} // namespace Jolie
#endif

View File

@ -1,60 +0,0 @@
/**
* This file is part of the KDE project
* Copyright (C) 2009 Kevin Ottens <ervin@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef QTJOLIE_CLIENT_P_H
#define QTJOLIE_CLIENT_P_H
#include "client.h"
#include "pendingcall_p.h"
#include <QtCore/QMap>
#include <QtCore/QObject>
namespace Jolie
{
class ClientThread;
class ClientPrivate : public QObject
{
Q_OBJECT
public:
ClientPrivate(Client *client)
: q(client),
readerThread(0),
error(Client::NoError) {}
public slots:
void messageReceived(const Jolie::Message &message);
private:
friend class Client;
Client * const q;
ClientThread *readerThread;
Client::Error error;
QString errorString;
QMap<int, QExplicitlySharedDataPointer<PendingCallPrivate> > pendingCalls;
};
} // namespace Jolie
#endif

View File

@ -1,91 +0,0 @@
/**
* This file is part of the KDE project
* Copyright (C) 2009 Kevin Ottens <ervin@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "clientthread_p.h"
#include <QtNetwork/QTcpSocket>
#include "client_p.h"
#include "message.h"
#include "sodephelpers_p.h"
using namespace Jolie;
ClientThread::ClientThread(const QString &hostName, quint16 port, ClientPrivate *client)
: QThread(), m_hostName(hostName), m_port(port), m_socket(0), m_client(client)
{
moveToThread(this);
}
ClientThread::~ClientThread()
{
quit();
wait();
}
void ClientThread::sendMessage(const Message &message)
{
QMutexLocker locker(&m_mutex);
m_messageQueue.enqueue(message);
QMetaObject::invokeMethod(this, "writeMessageQueue", Qt::QueuedConnection);
}
void ClientThread::writeMessageQueue()
{
QMutexLocker locker(&m_mutex);
while (!m_messageQueue.isEmpty()) {
sodepWrite(*m_socket, m_messageQueue.dequeue());
}
}
void ClientThread::readMessage()
{
if (m_socket->bytesAvailable()==0) {
return;
}
Message message = sodepReadMessage(*m_socket);
emit messageReceived(message);
if (m_socket->bytesAvailable()>0) {
QMetaObject::invokeMethod(this, "readMessage", Qt::QueuedConnection);
}
}
void ClientThread::run()
{
m_socket = new QTcpSocket;
connect(m_socket, SIGNAL(readyRead()),
this, SLOT(readMessage()), Qt::QueuedConnection);
connect(this, SIGNAL(messageReceived(Jolie::Message)),
m_client, SLOT(messageReceived(Jolie::Message)));
m_socket->connectToHost(m_hostName, m_port);
m_socket->waitForConnected(30000);
exec();
delete m_socket;
}
#include "moc_clientthread_p.cpp"

View File

@ -1,69 +0,0 @@
/**
* This file is part of the KDE project
* Copyright (C) 2009 Kevin Ottens <ervin@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef QTJOLIE_CLIENTTHREAD_P_H
#define QTJOLIE_CLIENTTHREAD_P_H
#include <QtCore/QThread>
#include <QtCore/QMutex>
#include <QtCore/QQueue>
class QAbstractSocket;
namespace Jolie
{
class Message;
class ClientPrivate;
class ClientThread : public QThread
{
Q_OBJECT
public:
explicit ClientThread(const QString &hostName, quint16 port, ClientPrivate *client);
~ClientThread();
void run();
void sendMessage(const Message &message);
signals:
void messageReceived(const Jolie::Message &message);
private slots:
void readMessage();
void writeMessageQueue();
private:
QString m_hostName;
quint16 m_port;
QAbstractSocket *m_socket;
ClientPrivate *m_client;
QQueue<Message> m_messageQueue;
QMutex m_mutex;
};
} // namespace Jolie
#endif

View File

@ -1,88 +0,0 @@
/**
* This file is part of the KDE project
* Copyright (C) 2008 Kevin Ottens <ervin@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "fault.h"
#include <QtCore/QByteArray>
#include "sodephelpers_p.h"
namespace Jolie
{
class FaultPrivate
{
public:
QByteArray name;
Value data;
};
} // namespace Jolie
using namespace Jolie;
static int _qtjolie_faultTypeId = qRegisterMetaType<Fault>();
Fault::Fault()
: d(new FaultPrivate)
{
}
Fault::Fault(const QByteArray &name, const Value &data)
: d(new FaultPrivate)
{
d->name = name;
d->data = data;
}
Fault::Fault(const Fault &other)
: d(new FaultPrivate)
{
*d = *other.d;
}
Fault::~Fault()
{
delete d;
}
Fault &Fault::operator=(const Fault &other)
{
*d = *other.d;
return *this;
}
QByteArray Fault::name() const
{
return d->name;
}
Value Fault::data() const
{
return d->data;
}
bool Fault::isValid() const
{
return !d->name.isEmpty();
}

View File

@ -1,58 +0,0 @@
/**
* This file is part of the KDE project
* Copyright (C) 2008 Kevin Ottens <ervin@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef QTJOLIE_FAULT_H
#define QTJOLIE_FAULT_H
#include <qtjolie/value.h>
#include <QtCore/QMetaType>
namespace Jolie
{
class FaultPrivate;
class Q_DECL_EXPORT Fault
{
public:
Fault();
explicit Fault(const QByteArray &name, const Value &data = Value());
Fault(const Fault &other);
~Fault();
Fault &operator=(const Fault &other);
QByteArray name() const;
Value data() const;
bool isValid() const;
private:
FaultPrivate * const d;
};
} // namespace Jolie
Q_DECLARE_METATYPE(Jolie::Fault)
#endif

View File

@ -1,124 +0,0 @@
/**
* This file is part of the KDE project
* Copyright (C) 2008 Kevin Ottens <ervin@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "message.h"
#include <QtCore/QByteArray>
#include "sodephelpers_p.h"
namespace Jolie
{
class MessagePrivate
{
public:
MessagePrivate() : id(0) {}
qint64 id;
QByteArray resourcePath;
QByteArray operationName;
Fault fault;
Value data;
};
} // namespace Jolie
using namespace Jolie;
static int _qtjolie_messageTypeId = qRegisterMetaType<Message>();
Message::Message()
: d(new MessagePrivate)
{
}
Message::Message(const QByteArray &resourcePath, const QByteArray &operationName, qint64 id)
: d(new MessagePrivate)
{
static qint64 lastId = 0;
if (id==0) {
d->id = ++lastId;
} else {
d->id = id;
}
d->resourcePath = resourcePath;
d->operationName = operationName;
}
Message::Message(const Message &other)
: d(new MessagePrivate)
{
*d = *other.d;
}
Message::~Message()
{
delete d;
}
Message &Message::operator=(const Message &other)
{
*d = *other.d;
return *this;
}
qint64 Message::id() const
{
return d->id;
}
QByteArray Message::resourcePath() const
{
return d->resourcePath;
}
QByteArray Message::operationName() const
{
return d->operationName;
}
Fault Message::fault() const
{
return d->fault;
}
void Message::setFault(const Fault &fault)
{
d->fault = fault;
}
Value Message::data() const
{
return d->data;
}
void Message::setData(const Value &data)
{
d->data = data;
}
bool Message::isValid()
{
return !d->resourcePath.isEmpty() && !d->operationName.isEmpty();
}

View File

@ -1,67 +0,0 @@
/**
* This file is part of the KDE project
* Copyright (C) 2008 Kevin Ottens <ervin@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef QTJOLIE_MESSAGE_H
#define QTJOLIE_MESSAGE_H
#include <qtjolie/value.h>
#include <qtjolie/fault.h>
#include <QtCore/QMetaType>
namespace Jolie
{
class MessagePrivate;
class Q_DECL_EXPORT Message
{
public:
Message();
explicit Message(const QByteArray &resourcePath,
const QByteArray &operationName,
qint64 id = 0);
Message(const Message &other);
~Message();
Message &operator=(const Message &other);
qint64 id() const;
QByteArray resourcePath() const;
QByteArray operationName() const;
Fault fault() const;
void setFault(const Fault &fault);
Value data() const;
void setData(const Value &data);
bool isValid();
private:
MessagePrivate * const d;
};
} // namespace Jolie
Q_DECLARE_METATYPE(Jolie::Message)
#endif

View File

@ -1,121 +0,0 @@
/**
* This file is part of the KDE project
* Copyright (C) 2009 Kevin Ottens <ervin@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "metaservice.h"
#include <QtCore/QProcess>
#include "client.h"
#include "message.h"
namespace Jolie
{
class MetaServicePrivate
{
public:
QProcess metaserviceProcess;
};
} // namespace Jolie
using namespace Jolie;
MetaService::MetaService()
: d(new MetaServicePrivate)
{
}
MetaService::~MetaService()
{
delete d;
}
bool MetaService::start()
{
d->metaserviceProcess.start(QString::fromUtf8("metaservice"));
return d->metaserviceProcess.waitForStarted();
}
bool MetaService::stop()
{
Client client(QString::fromUtf8("localhost"), 9000);
Message message("/", "shutdown");
client.callNoReply(message);
return d->metaserviceProcess.waitForFinished(30000);
}
bool MetaService::isRunning() const
{
return d->metaserviceProcess.state()==QProcess::Running;
}
QString MetaService::loadService(const QString &name, const QString &fileName)
{
Client client(QString::fromUtf8("localhost"), 9000);
Message message("/", "loadEmbeddedJolieService");
Value value;
value.children("resourcePrefix") << Value(name.toUtf8());
value.children("filepath") << Value(fileName.toUtf8());
message.setData(value);
Message reply = client.call(message);
return QString::fromUtf8(reply.data().toByteArray());
}
QStringList MetaService::loadedServices() const
{
Client client(QString::fromUtf8("localhost"), 9000);
Message message("/", "getServices");
Message reply = client.call(message);
QList<Value> services = reply.data().children("service");
QStringList result;
foreach (const Value &service, services) {
result << QString::fromUtf8(service.children("resourceName").first().toByteArray());
}
return result;
}
void MetaService::unloadService(const QString &name)
{
Client client(QString::fromUtf8("localhost"), 9000);
Message message("/", "unloadEmbeddedService");
message.setData(Value(name.toUtf8()));
client.call(message);
}
QString Jolie::MetaService::addRedirection(const QString &name, const QString &url, const Value &inProtocol, const Value &outProtocol)
{
Client client(QString::fromUtf8("localhost"), 9000);
Message message("/", "addRedirection");
Value value;
value.children("resourcePrefix") << Value(name.toUtf8());
value.children("location") << Value(url.toUtf8());
value.children("protocol") << inProtocol;
value.children("exposedProtocol") << outProtocol;
message.setData(value);
Message reply = client.call(message);
return QString::fromUtf8(reply.data().toByteArray());
}

View File

@ -1,55 +0,0 @@
/**
* This file is part of the KDE project
* Copyright (C) 2009 Kevin Ottens <ervin@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef QTJOLIE_METASERVICE_H
#define QTJOLIE_METASERVICE_H
#include <QtCore/QIODevice>
#include <QtCore/QList>
namespace Jolie
{
class MetaServicePrivate;
class Value;
class Q_DECL_EXPORT MetaService
{
public:
MetaService();
~MetaService();
bool start();
bool stop();
bool isRunning() const;
QString loadService(const QString &name, const QString &fileName);
QStringList loadedServices() const;
void unloadService(const QString &name);
QString addRedirection(const QString &name, const QString &url, const Value &inProtocol, const Value &outProtocol);
private:
MetaServicePrivate * const d;
};
} // namespace Jolie
#endif

View File

@ -1,71 +0,0 @@
/**
* This file is part of the KDE project
* Copyright (C) 2009 Kevin Ottens <ervin@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "pendingcall.h"
#include "pendingcall_p.h"
#include "pendingcallwatcher.h"
using namespace Jolie;
PendingCall::PendingCall(const PendingCall &other)
: d(other.d)
{
}
PendingCall::PendingCall(QExplicitlySharedDataPointer<PendingCallPrivate> dd)
: d(dd)
{
}
PendingCall::~PendingCall()
{
}
PendingCall &PendingCall::operator=(const PendingCall &other)
{
d = other.d;
return *this;
}
void PendingCallPrivate::setReply(const Message &message)
{
Q_ASSERT(message.id()==id);
isFinished = true;
reply = message;
foreach (PendingCallWaiter *waiter, waiters) {
waiter->eventLoop.quit();
}
waiters.clear();
foreach (PendingCallWatcher *watcher, watchers) {
emit watcher->finished(watcher);
}
watchers.clear();
}
void PendingCallWaiter::waitForFinished(PendingCallPrivate *pendingCall)
{
if (pendingCall==0) return;
pendingCall->waiters << this;
eventLoop.exec();
}

View File

@ -1,54 +0,0 @@
/**
* This file is part of the KDE project
* Copyright (C) 2009 Kevin Ottens <ervin@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef QTJOLIE_PENDINGCALL_H
#define QTJOLIE_PENDINGCALL_H
#include <QtCore/QExplicitlySharedDataPointer>
namespace Jolie
{
class Client;
class PendingCallPrivate;
class Message;
class Q_DECL_EXPORT PendingCall
{
public:
PendingCall(const PendingCall &other);
~PendingCall();
PendingCall &operator=(const PendingCall &other);
private:
friend class Client;
friend class PendingCallWatcher;
friend class PendingReply;
PendingCall(); // Not defined
PendingCall(QExplicitlySharedDataPointer<PendingCallPrivate> dd);
QExplicitlySharedDataPointer<PendingCallPrivate> d;
};
} // namespace Jolie
#endif

View File

@ -1,70 +0,0 @@
/**
* This file is part of the KDE project
* Copyright (C) 2009 Kevin Ottens <ervin@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef QTJOLIE_PENDINGCALL_P_H
#define QTJOLIE_PENDINGCALL_P_H
#include <QtCore/QEventLoop>
#include <QtCore/QObject>
#include <QtCore/QSharedData>
#include "message.h"
namespace Jolie
{
class PendingCallPrivate;
class PendingCallWatcher;
class PendingCallWaiter
{
public:
void waitForFinished(PendingCallPrivate *pendingCall);
private:
friend class PendingCallPrivate;
QEventLoop eventLoop;
};
class PendingCallPrivate : public QSharedData
{
public:
PendingCallPrivate(const Message &message)
: id(message.id()), isFinished(false) {}
void setReply(const Message &message);
private:
friend class PendingCall;
friend class PendingCallWatcher;
friend class PendingCallWaiter;
friend class PendingReply;
qint64 id;
bool isFinished;
Message reply;
QList<PendingCallWaiter*> waiters;
QList<PendingCallWatcher*> watchers;
};
} // namespace Jolie
#endif

View File

@ -1,50 +0,0 @@
/**
* This file is part of the KDE project
* Copyright (C) 2009 Kevin Ottens <ervin@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "pendingcallwatcher.h"
#include "pendingcall_p.h"
using namespace Jolie;
PendingCallWatcher::PendingCallWatcher(const PendingCall &other, QObject *parent)
: QObject(parent), PendingCall(other.d)
{
d->watchers << this;
}
PendingCallWatcher::~PendingCallWatcher()
{
d->watchers.removeAll(this);
}
bool PendingCallWatcher::isFinished() const
{
return d->isFinished;
}
void PendingCallWatcher::waitForFinished()
{
PendingCallWaiter waiter;
waiter.waitForFinished(d.data());
}
#include "moc_pendingcallwatcher.cpp"

View File

@ -1,52 +0,0 @@
/**
* This file is part of the KDE project
* Copyright (C) 2009 Kevin Ottens <ervin@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef QTJOLIE_PENDINGCALLWATCHER_H
#define QTJOLIE_PENDINGCALLWATCHER_H
#include <QtCore/QObject>
#include <qtjolie/pendingcall.h>
namespace Jolie
{
class Q_DECL_EXPORT PendingCallWatcher : public QObject, public PendingCall
{
Q_OBJECT
public:
PendingCallWatcher(const PendingCall &call, QObject *parent=0);
~PendingCallWatcher();
bool isFinished() const;
void waitForFinished();
Q_SIGNALS:
void finished(Jolie::PendingCallWatcher *self);
private:
friend class PendingCallPrivate;
PendingCallWatcher(); // Not defined
};
} // namespace Jolie
#endif

View File

@ -1,75 +0,0 @@
/**
* This file is part of the KDE project
* Copyright (C) 2009 Kevin Ottens <ervin@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "pendingreply.h"
#include "pendingcall_p.h"
using namespace Jolie;
PendingReply::PendingReply()
: PendingCall(QExplicitlySharedDataPointer<PendingCallPrivate>())
{
}
PendingReply::PendingReply(const PendingReply &other)
: PendingCall(other.d)
{
}
PendingReply::PendingReply(const PendingCall &call)
: PendingCall(call.d)
{
}
PendingReply::~PendingReply()
{
}
PendingReply &PendingReply::operator=(const PendingReply &other)
{
d = other.d;
return *this;
}
PendingReply &PendingReply::operator=(const PendingCall &call)
{
d = call.d;
return *this;
}
bool PendingReply::isFinished() const
{
return d ? d->isFinished : false;
}
Message PendingReply::reply() const
{
return d ? d->reply : Message();
}
void PendingReply::waitForFinished()
{
PendingCallWaiter waiter;
waiter.waitForFinished(d.data());
}

View File

@ -1,51 +0,0 @@
/**
* This file is part of the KDE project
* Copyright (C) 2009 Kevin Ottens <ervin@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef QTJOLIE_PENDINGREPLY_H
#define QTJOLIE_PENDINGREPLY_H
#include <qtjolie/pendingcall.h>
namespace Jolie
{
class Q_DECL_EXPORT PendingReply : public PendingCall
{
public:
PendingReply();
PendingReply(const PendingReply &other);
PendingReply(const PendingCall &call);
~PendingReply();
PendingReply &operator=(const PendingReply &other);
PendingReply &operator=(const PendingCall &call);
bool isFinished() const;
Message reply() const;
void waitForFinished();
private:
friend class PendingCallPrivate;
};
} // namespace Jolie
#endif

View File

@ -1,88 +0,0 @@
/**
* This file is part of the KDE project
* Copyright (C) 2009 Kevin Ottens <ervin@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "server.h"
#include "server_p.h"
#include <QtCore/QDebug>
#include "abstractadaptor.h"
#include "serverthread_p.h"
#include "message.h"
#include "pendingcall.h"
#include "pendingreply.h"
using namespace Jolie;
Server::Server(quint16 port)
: d(new ServerPrivate(this))
{
d->serverThread = new ServerThread(port, d);
d->serverThread->start();
}
Server::~Server()
{
delete d->serverThread;
delete d;
}
Server::Error Server::error() const
{
return d->error;
}
QString Server::errorString() const
{
return d->errorString;
}
void Server::sendReply(int clientId, const Message &reply)
{
d->serverThread->sendMessage(clientId, reply);
}
bool Server::registerAdaptor(const QByteArray &path, AbstractAdaptor *adaptor)
{
if (path.isEmpty() || d->adaptors.contains(path)) {
return false;
}
d->adaptors[path] = adaptor;
return true;
}
bool Server::unregisterAdaptor(const QByteArray &path)
{
return d->adaptors.take(path)!=0;
}
void ServerPrivate::messageReceived(int descriptor, const Message &message)
{
if (adaptors.contains(message.resourcePath())) {
adaptors[message.resourcePath()]->relay(q, descriptor, message);
} else {
qWarning() << "Got a message for an unregistered object:"
<< message.operationName()
<< "@"
<< message.resourcePath();
}
}

View File

@ -1,61 +0,0 @@
/**
* This file is part of the KDE project
* Copyright (C) 2009 Kevin Ottens <ervin@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef QTJOLIE_SERVER_H
#define QTJOLIE_SERVER_H
#include <QtCore/QtGlobal>
namespace Jolie
{
class AbstractAdaptor;
class ServerPrivate;
class Message;
class Q_DECL_EXPORT Server
{
public:
enum Error
{
NoError,
UnexpectedClose,
UnkownError
};
explicit Server(quint16 port);
~Server();
Error error() const;
QString errorString() const;
void sendReply(int clientId, const Message &reply);
bool registerAdaptor(const QByteArray &path, AbstractAdaptor *adaptor);
bool unregisterAdaptor(const QByteArray &path);
private:
friend class ServerPrivate;
ServerPrivate * const d;
};
} // namespace Jolie
#endif

View File

@ -1,60 +0,0 @@
/**
* This file is part of the KDE project
* Copyright (C) 2009 Kevin Ottens <ervin@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef QTJOLIE_SERVER_P_H
#define QTJOLIE_SERVER_P_H
#include "server.h"
#include <QtCore/QMap>
#include <QtCore/QObject>
class QIODevice;
namespace Jolie
{
class ServerThread;
class AbstractAdaptor;
class ServerPrivate : public QObject
{
Q_OBJECT
public:
ServerPrivate(Server *server)
: q(server),
error(Server::NoError) {}
public slots:
void messageReceived(int descriptor, const Jolie::Message &message);
private:
friend class Server;
Server * const q;
ServerThread *serverThread;
Server::Error error;
QString errorString;
QMap<QByteArray, AbstractAdaptor*> adaptors;
};
} // namespace Jolie
#endif

View File

@ -1,112 +0,0 @@
/**
* This file is part of the KDE project
* Copyright (C) 2009 Kevin Ottens <ervin@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "serverthread_p.h"
#include <QtNetwork/QTcpSocket>
#include <QtNetwork/QTcpServer>
#include "server_p.h"
#include "message.h"
#include "sodephelpers_p.h"
using namespace Jolie;
Q_DECLARE_METATYPE(QAbstractSocket*)
static int _jolie_socketDataTypeId = qRegisterMetaType<QAbstractSocket*>();
ServerThread::ServerThread(quint16 port, ServerPrivate *server)
: QThread(), m_port(port), m_serverSocket(0), m_server(server)
{
moveToThread(this);
}
ServerThread::~ServerThread()
{
quit();
wait();
}
void ServerThread::sendMessage(int descriptor, const Message &message)
{
QMutexLocker locker(&m_mutex);
m_messageQueue.enqueue(QPair<int, Message>(descriptor, message));
QMetaObject::invokeMethod(this, "writeMessageQueue", Qt::QueuedConnection);
}
void ServerThread::writeMessageQueue()
{
QMutexLocker locker(&m_mutex);
while (!m_messageQueue.isEmpty()) {
QPair<int, Message> pair = m_messageQueue.dequeue();
sodepWrite(*m_sockets[pair.first], pair.second);
}
}
void ServerThread::onIncomingConnection()
{
while (m_serverSocket->hasPendingConnections()) {
QAbstractSocket *socket = m_serverSocket->nextPendingConnection();
m_sockets[socket->socketDescriptor()] = socket;
connect(socket, SIGNAL(readyRead()),
this, SLOT(onReadyRead()), Qt::QueuedConnection);
}
}
void ServerThread::onReadyRead()
{
QAbstractSocket *socket = static_cast<QAbstractSocket*>(sender());
readMessage(socket);
}
void ServerThread::readMessage(QAbstractSocket *socket)
{
if (socket->bytesAvailable()==0) {
return;
}
Message message = sodepReadMessage(*socket);
emit messageReceived(socket->socketDescriptor(), message);
if (socket->bytesAvailable()>0) {
QMetaObject::invokeMethod(this, "readMessage", Qt::QueuedConnection, Q_ARG(QAbstractSocket*, socket));
}
}
void ServerThread::run()
{
m_serverSocket = new QTcpServer;
connect(this, SIGNAL(messageReceived(int,Jolie::Message)),
m_server, SLOT(messageReceived(int,Jolie::Message)));
connect(m_serverSocket, SIGNAL(newConnection()),
this, SLOT(onIncomingConnection()), Qt::QueuedConnection);
m_serverSocket->listen(QHostAddress::Any, m_port);
exec();
delete m_serverSocket;
}
#include "moc_serverthread_p.cpp"

View File

@ -1,76 +0,0 @@
/**
* This file is part of the KDE project
* Copyright (C) 2009 Kevin Ottens <ervin@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef QTJOLIE_SERVERTHREAD_P_H
#define QTJOLIE_SERVERTHREAD_P_H
#include <QtCore/QThread>
#include <QtCore/QMap>
#include <QtCore/QMutex>
#include <QtCore/QPair>
#include <QtCore/QQueue>
class QAbstractSocket;
class QTcpServer;
namespace Jolie
{
class Message;
class ServerPrivate;
class ServerThread : public QThread
{
Q_OBJECT
public:
explicit ServerThread(quint16 port, ServerPrivate *server);
~ServerThread();
void run();
void sendMessage(int descriptor, const Message &message);
signals:
void messageReceived(int descriptor, const Jolie::Message &message);
private slots:
void onIncomingConnection();
void onReadyRead();
void readMessage(QAbstractSocket *socket);
void writeMessageQueue();
private:
quint16 m_port;
QTcpServer *m_serverSocket;
QMap<int, QAbstractSocket*> m_sockets;
ServerPrivate *m_server;
QQueue< QPair<int, Message> > m_messageQueue;
QMutex m_mutex;
};
} // namespace Jolie
#endif

View File

@ -1,279 +0,0 @@
/**
* This file is part of the KDE project
* Copyright (C) 2008 Kevin Ottens <ervin@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef QTJOLIE_SODEPHELPERS_P_H
#define QTJOLIE_SODEPHELPERS_P_H
#include <QtCore/QIODevice>
#include <QtCore/QByteArray>
#include "value.h"
#include "fault.h"
#include "message.h"
namespace Jolie
{
inline void sodepWrite(QIODevice &io, double value)
{
const char *in = (const char*)&value;
char out[8];
for (int i=0; i<8; ++i) {
out[i] = in[7-i];
}
io.write(out, 8);
}
inline void sodepWrite(QIODevice &io, qint32 value)
{
const char *in = (const char*)&value;
char out[4];
for (int i=0; i<4; ++i) {
out[i] = in[3-i];
}
io.write(out, 4);
}
inline void sodepWrite(QIODevice &io, qint64 value)
{
const char *in = (const char*)&value;
char out[8];
for (int i=0; i<8; ++i) {
out[i] = in[7-i];
}
io.write(out, 8);
}
inline void sodepWrite(QIODevice &io, const QByteArray &value)
{
sodepWrite(io, value.size());
io.write(value);
}
inline void sodepWrite(QIODevice &io, const Value &value)
{
if (value.isDouble()) {
io.putChar(3);
sodepWrite(io, value.toDouble());
} else if (value.isInt()) {
io.putChar(2);
sodepWrite(io, value.toInt());
} else if (value.isByteArray()) {
io.putChar(1);
sodepWrite(io, value.toByteArray());
} else {
io.putChar(0);
}
sodepWrite(io, value.childrenNames().size());
foreach (const QByteArray &name, value.childrenNames()) {
sodepWrite(io, name);
QList<Value> values = value.children(name);
qint32 valueCount = values.size();
sodepWrite(io, valueCount);
for (int j=0; j<valueCount; ++j) {
sodepWrite(io, values[j]);
}
}
}
inline void sodepWrite(QIODevice &io, const Fault &fault)
{
if (!fault.isValid()) {
io.putChar(0);
return;
}
io.putChar(1);
sodepWrite(io, fault.name());
sodepWrite(io, fault.data());
}
inline void sodepWrite(QIODevice &io, const Message &message)
{
sodepWrite(io, message.id());
sodepWrite(io, message.resourcePath());
sodepWrite(io, message.operationName());
sodepWrite(io, message.fault());
sodepWrite(io, message.data());
}
inline double sodepReadDouble(QIODevice &io)
{
while (io.bytesAvailable()<8) {
io.waitForReadyRead(-1);
}
double d;
char *out = (char*)&d;
char in[8];
io.read(in, 8);
for (int i=0; i<8; ++i) {
out[i] = in[7-i];
}
return d;
}
inline qint32 sodepReadInt32(QIODevice &io)
{
while (io.bytesAvailable()<4) {
io.waitForReadyRead(-1);
}
qint32 i;
char *out = (char*)&i;
char in[4];
io.read(in, 4);
for (int j=0; j<4; ++j) {
out[j] = in[3-j];
}
return i;
}
inline qint64 sodepReadInt64(QIODevice &io)
{
while (io.bytesAvailable()<8) {
io.waitForReadyRead(-1);
}
qint64 i;
char *out = (char*)&i;
char in[8];
io.read(in, 8);
for (int j=0; j<8; ++j) {
out[j] = in[7-j];
}
return i;
}
inline QByteArray sodepReadByteArray(QIODevice &io)
{
qint32 length = sodepReadInt32(io);
while (io.bytesAvailable()<length) {
io.waitForReadyRead(-1);
}
char *data = new char[length+1];
io.read(data, length);
QByteArray result(data, length);
delete[] data;
return result;
}
inline Value sodepReadValue(QIODevice &io)
{
Value result;
while (io.bytesAvailable()<1) {
io.waitForReadyRead(-1);
}
char code;
io.getChar(&code);
switch(code) {
case 3: {
result = Value(sodepReadDouble(io));
break;
}
case 2: {
result = Value(sodepReadInt32(io));
break;
}
case 1: {
result = Value(sodepReadByteArray(io));
break;
}
default:
break;
}
qint32 childrenCount = sodepReadInt32(io);
for (int i=0; i<childrenCount; ++i) {
QByteArray name = sodepReadByteArray(io);
qint32 valueCount = sodepReadInt32(io);
for (int j=0; j<valueCount; ++j) {
result.children(name) << sodepReadValue(io);
}
}
return result;
}
inline Fault sodepReadFault(QIODevice &io)
{
while (io.bytesAvailable()<1) {
io.waitForReadyRead(-1);
}
char code;
io.getChar(&code);
if (code!=1) {
return Fault();
}
QByteArray name = sodepReadByteArray(io);
Value data = sodepReadValue(io);
return Fault(name, data);
}
inline Message sodepReadMessage(QIODevice &io)
{
qint64 id = sodepReadInt64(io);
QByteArray resourcePath = sodepReadByteArray(io);
QByteArray operationName = sodepReadByteArray(io);
Message result(resourcePath, operationName, id);
result.setFault(sodepReadFault(io));
result.setData(sodepReadValue(io));
return result;
}
} // namespace Jolie
#endif

View File

@ -1,149 +0,0 @@
/**
* This file is part of the KDE project
* Copyright (C) 2008 Kevin Ottens <ervin@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "value.h"
#include <QtCore/QVariant>
#include "sodephelpers_p.h"
namespace Jolie
{
class ValuePrivate
{
public:
QVariant content;
QMap<QByteArray, Value::List> children;
};
} // namespace Jolie
using namespace Jolie;
static int _qtjolie_valueTypeId = qRegisterMetaType<Value>();
Value::Value()
: d(new ValuePrivate)
{
}
Value::Value(const QByteArray &content)
: d(new ValuePrivate)
{
d->content = content;
}
Value::Value(qint32 content)
: d(new ValuePrivate)
{
d->content = content;
}
Value::Value(double content)
: d(new ValuePrivate)
{
d->content = content;
}
Value::Value(const Value &other)
: d(new ValuePrivate)
{
*d = *other.d;
}
Value::~Value()
{
delete d;
}
Value &Value::operator=(const Value &other)
{
*d = *other.d;
return *this;
}
QList<QByteArray> Value::childrenNames() const
{
return d->children.keys();
}
Value::List &Value::children(const QByteArray &name)
{
return d->children[name];
}
const Value::List &Value::children(const QByteArray &name) const
{
return d->children[name];
}
QByteArray Value::toByteArray() const
{
if (isByteArray()) {
return d->content.toByteArray();
} else {
return QByteArray();
}
}
qint32 Value::toInt() const
{
if (isInt()) {
return d->content.toInt();
} else if (isByteArray()) {
return d->content.toByteArray().toInt();
} else {
return 0;
}
}
double Value::toDouble() const
{
if (isDouble()) {
return d->content.toDouble();
} else if (isByteArray()) {
return d->content.toByteArray().toInt();
} else {
return 0.0;
}
}
bool Value::isByteArray() const
{
return d->content.type()==QVariant::ByteArray;
}
bool Value::isInt() const
{
return d->content.type()==QVariant::Int;
}
bool Value::isDouble() const
{
return d->content.type()==QVariant::Double;
}
bool Value::isValid() const
{
return isByteArray() || isInt() || isDouble();
}

View File

@ -1,72 +0,0 @@
/**
* This file is part of the KDE project
* Copyright (C) 2008 Kevin Ottens <ervin@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef QTJOLIE_VALUE_H
#define QTJOLIE_VALUE_H
#include <QtCore/QIODevice>
#include <QtCore/QList>
#include <QtCore/QMetaType>
namespace Jolie
{
class ValuePrivate;
class Q_DECL_EXPORT Value
{
public:
typedef QList<Value> List;
Value();
explicit Value(const QByteArray &content);
explicit Value(qint32 content);
explicit Value(double content);
Value(const Value &other);
~Value();
Value &operator=(const Value &other);
QList<QByteArray> childrenNames() const;
Value::List &children(const QByteArray &name);
const Value::List &children(const QByteArray &name) const;
QByteArray toByteArray() const;
qint32 toInt() const;
double toDouble() const;
bool isByteArray() const;
bool isInt() const;
bool isDouble() const;
bool isValid() const;
private:
ValuePrivate * const d;
};
} // namespace Jolie
Q_DECLARE_METATYPE(Jolie::Value)
#endif

View File

@ -1,43 +0,0 @@
include_directories(${KDE4_INCLUDES} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../includes ${CMAKE_CURRENT_SOURCE_DIR}/../)
include(ECMMarkAsTest)
MACRO(SODEP_UNIT_TESTS)
FOREACH(_testname ${ARGN})
kde4_add_unit_test(${_testname} TESTNAME plasma-sodep-${_testname} NOGUI ${_testname}.cpp)
target_link_libraries(${_testname} ${QT_QTTEST_LIBRARY} ${QT_QTNETWORK_LIBRARY} QtJolie)
ecm_mark_as_test(${_testname})
add_definitions(-DDATA_DIR="\\"${CMAKE_CURRENT_SOURCE_DIR}\\"")
ENDFOREACH(_testname)
ENDMACRO(SODEP_UNIT_TESTS)
MACRO(SODEP_EXECUTABLE_TESTS)
FOREACH(_testname ${ARGN})
add_executable(${_testname} NOGUI ${_testname}.cpp)
target_link_libraries(${_testname} Qt5::Widgets ${QT_QTNETWORK_LIBRARY} QtJolie)
ecm_mark_as_test(${_testname})`
add_definitions(-DDATA_DIR="\\"${CMAKE_CURRENT_SOURCE_DIR}\\"")
ENDFOREACH(_testname)
ENDMACRO(SODEP_EXECUTABLE_TESTS)
SODEP_UNIT_TESTS(
testvalue
testfault
testmessage
testmetaservice
)
SODEP_EXECUTABLE_TESTS(
testprinter
calculatorservice
trivialyahooclient
)
set(visiondriver_SRCS
visiondriver.cpp
)
kde4_add_ui_files(visiondriver_SRCS visiondriverwidget.ui)
kde4_add_executable(visiondriver ${visiondriver_SRCS})
target_link_libraries(visiondriver ${KDE4_KDEUI_LIBS} ${QT_QTNETWORK_LIBRARY} QtJolie)

View File

@ -1,21 +0,0 @@
include "console.iol"
interface CalculatorInterface {
RequestResponse:
add
}
outputPort Calculator {
Location: "socket://localhost:9001/!/Calculator"
Protocol: soap { .debug = 1 }
Interfaces: CalculatorInterface
}
main
{
request.x = 2;
request.y = 3;
add@Calculator( request )( response );
println@Console( response )()
}

View File

@ -1,126 +0,0 @@
/**
* This file is part of the KDE project
* Copyright (C) 2009 Kevin Ottens <ervin@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <QtCore/QTimer>
#include <QApplication>
#include <QBoxLayout>
#include <QTextEdit>
#include <QtNetwork/QTcpSocket>
#include <QtJolie/AbstractAdaptor>
#include <QtJolie/Server>
#include <QtJolie/Message>
#include <QtJolie/MetaService>
#include "testhelpers.h"
using namespace Jolie;
class CalculatorAdaptor : public AbstractAdaptor
{
Q_OBJECT
public:
CalculatorAdaptor(QObject *parent = 0)
: AbstractAdaptor(parent)
{
}
signals:
void added(int a, int b, int result);
private:
void relay(Server *server, int clientId, const Message &message)
{
qint32 x = message.data().children("x").first().toInt();
qint32 y = message.data().children("y").first().toInt();
emit added(x, y, x+y);
sodepDump(message);
Message reply(message.resourcePath(),
message.operationName(),
message.id());
reply.setData(Value(x+y));
server->sendReply(clientId, reply);
}
};
class MainWindow : public QWidget
{
Q_OBJECT
public:
MainWindow()
{
setLayout(new QHBoxLayout());
m_textEdit = new QTextEdit(this);
layout()->addWidget(m_textEdit);
m_meta.start();
QTimer::singleShot(1000, this, SLOT(delayedInit()));
}
~MainWindow()
{
m_meta.stop();
delete m_server;
}
private slots:
void delayedInit()
{
m_server = new Server(8000);
CalculatorAdaptor *adaptor = new CalculatorAdaptor(this);
connect(adaptor, SIGNAL(added(int,int,int)),
this, SLOT(onAdded(int,int,int)));
m_server->registerAdaptor("/", adaptor);
m_meta.addRedirection(QString::fromUtf8("Calculator"),
QString::fromUtf8("socket://localhost:8000/"),
Value("sodep"),
Value("soap"));
}
void onAdded(int a, int b, int result)
{
m_textEdit->append(QString::number(a)
+ QString::fromUtf8(" + ")
+ QString::number(b)
+ QString::fromUtf8(" = ")
+ QString::number(result));
}
private:
MetaService m_meta;
QTextEdit *m_textEdit;
Server *m_server;
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
MainWindow w;
w.show();
return app.exec();
}
#include "calculatorservice.moc"

View File

@ -1,15 +0,0 @@
inputPort MathService {
Location: "local"
Protocol: sodep
RequestResponse:
twice
}
main
{
twice(number)(result) {
result = number * 2
}
}

View File

@ -1,17 +0,0 @@
include "console.iol"
inputPort PrinterService {
Location: "local"
Protocol: sodep
RequestResponse:
printInput
}
main
{
printInput(input)(result) {
println@Console(input)();
result = "success"
}
}

View File

@ -1,102 +0,0 @@
/**
* This file is part of the KDE project
* Copyright (C) 2008 Kevin Ottens <ervin@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <QtCore/QObject>
#include <QtTest/QtTest>
#include <QtJolie/Fault>
#include "testhelpers.h"
using namespace Jolie;
class TestFault : public QObject
{
Q_OBJECT
private slots:
void shouldHandleInvalids()
{
Fault f;
QCOMPARE(f.name(), QByteArray());
QVERIFY(!f.data().isValid());
QVERIFY(!f.isValid());
}
void shouldVerifyInitialState()
{
Fault f1("blup"), f2("blop", Value(42));
QCOMPARE(f1.name(), QByteArray("blup"));
QVERIFY(!f1.data().isValid());
QCOMPARE(f2.name(), QByteArray("blop"));
QVERIFY(f2.data().isValid());
QCOMPARE(f2.data().toInt(), 42);
f1 = f2;
QCOMPARE(f1.name(), QByteArray("blop"));
QVERIFY(f1.data().isValid());
QCOMPARE(f1.data().toInt(), 42);
}
void shouldBeSerializable_data()
{
Value v(42);
QByteArray vSerial = QByteArray::fromHex("020000002A00000000");
QTest::addColumn<Fault>("original");
QTest::addColumn<QByteArray>("serialized");
QTest::newRow("empty fault") << Fault()
<< QByteArray::fromHex("00");
QTest::newRow("no value fault") << Fault("foo")
<< QByteArray::fromHex("0100000003")+QByteArray("foo")
+ QByteArray::fromHex("0000000000");
QTest::newRow("value fault") << Fault("bar", v)
<< QByteArray::fromHex("0100000003")+QByteArray("bar")
+ vSerial;
}
void shouldBeSerializable()
{
QBuffer buffer;
QFETCH(Fault, original);
QFETCH(QByteArray, serialized);
Fault result;
buffer.open(QIODevice::WriteOnly);
sodepWrite(buffer, original);
buffer.close();
buffer.open(QIODevice::ReadOnly);
result = sodepReadFault(buffer);
buffer.close();
sodepCompare(result, original);
QCOMPARE(buffer.data(), serialized);
}
};
QTEST_MAIN(TestFault)
#include "testfault.moc"

View File

@ -1,103 +0,0 @@
/**
* This file is part of the KDE project
* Copyright (C) 2008 Kevin Ottens <ervin@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef SODEPTESTHELPERS_H
#define SODEPTESTHELPERS_H
#include <QtTest/QtTest>
#include <QtJolie/Fault>
#include <QtJolie/Message>
#include <QtJolie/Value>
#include "../qtjolie/sodephelpers_p.h"
inline void sodepDump(const Jolie::Value &value, int level)
{
QByteArray indent;
while (level>0) {
indent+=" ";
level--;
}
qDebug() << (indent+value.toByteArray()) << value.toInt() << value.toDouble();
foreach (const QByteArray &name, value.childrenNames()) {
QList<Jolie::Value> children = value.children(name);
qDebug() << (indent+"Children:") << name;
foreach (const Jolie::Value &child, children) {
sodepDump(child, level+1);
}
}
}
inline void sodepDump(const Jolie::Message &message)
{
qDebug() << "Resource :" << message.resourcePath();
qDebug() << "Operation:" << message.operationName();
qDebug() << "Fault :" << message.fault().name();
sodepDump(message.fault().data(), 1);
qDebug() << "Value :";
sodepDump(message.data(), 1);
}
inline void sodepCompare(const Jolie::Value &v1, const Jolie::Value &v2)
{
QCOMPARE(v1.isValid(), v2.isValid());
QCOMPARE(v1.isByteArray(), v2.isByteArray());
QCOMPARE(v1.isInt(), v2.isInt());
QCOMPARE(v1.isDouble(), v2.isDouble());
QCOMPARE(v1.toByteArray(), v2.toByteArray());
QCOMPARE(v1.toInt(), v2.toInt());
QCOMPARE(v1.toDouble(), v2.toDouble());
QList<QByteArray> v1Names = v1.childrenNames();
QList<QByteArray> v2Names = v2.childrenNames();
QCOMPARE(v1Names, v2Names);
foreach (const QByteArray &name, v1Names) {
QList<Jolie::Value> v1Values = v1.children(name);
QList<Jolie::Value> v2Values = v2.children(name);
QCOMPARE(v1Values.size(), v2Values.size());
for (int i=0; i<v1Values.size(); ++i) {
sodepCompare(v1Values[i], v2Values[i]);
}
}
}
inline void sodepCompare(const Jolie::Fault &f1, const Jolie::Fault &f2)
{
QCOMPARE(f1.isValid(), f2.isValid());
QCOMPARE(f1.name(), f2.name());
sodepCompare(f1.data(), f2.data());
}
inline void sodepCompare(const Jolie::Message &m1, const Jolie::Message &m2)
{
QCOMPARE(m1.resourcePath(), m2.resourcePath());
QCOMPARE(m1.operationName(), m2.operationName());
sodepCompare(m1.fault(), m2.fault());
sodepCompare(m1.data(), m2.data());
}
#endif

View File

@ -1,116 +0,0 @@
/**
* This file is part of the KDE project
* Copyright (C) 2008 Kevin Ottens <ervin@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <QtCore/QObject>
#include <QtTest/QtTest>
#include <QtJolie/Message>
#include "testhelpers.h"
using namespace Jolie;
class TestMessage : public QObject
{
Q_OBJECT
private slots:
void shouldVerifyInitialState()
{
Message m1("/foo", "bar", 1);
Message m2("/pata/pata", "pon", 2);
QCOMPARE(m1.resourcePath(), QByteArray("/foo"));
QCOMPARE(m1.operationName(), QByteArray("bar"));
QCOMPARE(m1.id(), qint64(1));
QCOMPARE(m2.resourcePath(), QByteArray("/pata/pata"));
QCOMPARE(m2.operationName(), QByteArray("pon"));
QCOMPARE(m2.id(), qint64(2));
m1 = m2;
QCOMPARE(m1.resourcePath(), QByteArray("/pata/pata"));
QCOMPARE(m1.operationName(), QByteArray("pon"));
QCOMPARE(m2.id(), qint64(2));
}
void shouldBeSerializable_data()
{
Value v(42);
QByteArray vSerial = QByteArray::fromHex("020000002A00000000");
Fault f("foo");
QByteArray fSerial = QByteArray::fromHex("0100000003")+QByteArray("foo")
+ QByteArray::fromHex("0000000000");
QTest::addColumn<Message>("original");
QTest::addColumn<QByteArray>("serialized");
QTest::newRow("no payload message") << Message("/pata", "pon", 1)
<< QByteArray::fromHex("0000000000000001")
+ QByteArray::fromHex("00000005")+QByteArray("/pata")
+ QByteArray::fromHex("00000003")+QByteArray("pon")
+ QByteArray::fromHex("00")
+ QByteArray::fromHex("0000000000");
Message payload("/pata", "pon", 1);
payload.setFault(f);
payload.setData(v);
QTest::newRow("payload message") << payload
<< QByteArray::fromHex("0000000000000001")
+ QByteArray::fromHex("00000005")+QByteArray("/pata")
+ QByteArray::fromHex("00000003")+QByteArray("pon")
+ fSerial
+ vSerial;
Message payloadId("/pata", "pon", 42);
payloadId.setFault(f);
payloadId.setData(v);
QTest::newRow("payload and id message") << payloadId
<< QByteArray::fromHex("000000000000002A")
+ QByteArray::fromHex("00000005")+QByteArray("/pata")
+ QByteArray::fromHex("00000003")+QByteArray("pon")
+ fSerial
+ vSerial;
}
void shouldBeSerializable()
{
QBuffer buffer;
QFETCH(Message, original);
QFETCH(QByteArray, serialized);
Message result;
buffer.open(QIODevice::WriteOnly);
sodepWrite(buffer, original);
buffer.close();
buffer.open(QIODevice::ReadOnly);
result = sodepReadMessage(buffer);
buffer.close();
sodepCompare(result, original);
QCOMPARE(buffer.data(), serialized);
}
};
QTEST_MAIN(TestMessage)
#include "testmessage.moc"

View File

@ -1,137 +0,0 @@
/**
* This file is part of the KDE project
* Copyright (C) 2008 Kevin Ottens <ervin@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <QtCore/QObject>
#include <QtCore/QProcess>
#include <QtTest/QtTest>
#include <QtJolie/Client>
#include <QtJolie/Message>
#include <QtJolie/MetaService>
#include <QtJolie/PendingCall>
#include "testhelpers.h"
#ifndef DATA_DIR
#error "DATA_DIR is not set. A directory containing test jolie scripts is required for this test"
#endif
using namespace Jolie;
class TestMetaService : public QObject
{
Q_OBJECT
MetaService m_metaService;
Client *m_client;
public:
TestMetaService()
: QObject()
{
}
private slots:
void initTestCase()
{
QVERIFY2(m_metaService.start(), "Looks like you don't have Jolie's metaservice command");
QTest::qWait(1000);
m_client = new Client(QString::fromUtf8("localhost"), 9000);
}
void cleanupTestCase()
{
delete m_client;
QVERIFY(m_metaService.stop());
}
void shouldLoadService_data()
{
QTest::addColumn<QString>("resourcePrefix");
QTest::addColumn<QString>("fileName");
QTest::newRow("printer service") << QString::fromUtf8("Printer") << QString::fromUtf8("printer.ol");
QTest::newRow("math service") << QString::fromUtf8("Math") << QString::fromUtf8("math.ol");
}
void shouldLoadService()
{
QFETCH(QString, resourcePrefix);
QFETCH(QString, fileName);
QCOMPARE(m_metaService.loadService(resourcePrefix, QString::fromUtf8(DATA_DIR"/")+fileName),
resourcePrefix);
}
void shouldListServices()
{
QStringList expected;
expected << QString::fromUtf8("Math") << QString::fromUtf8("Printer");
QCOMPARE(m_metaService.loadedServices(), expected);
}
void shouldPlaceServiceCalls_data()
{
QTest::addColumn<QByteArray>("path");
QTest::addColumn<QByteArray>("method");
QTest::addColumn<Value>("data");
QTest::addColumn<Value>("replyData");
QTest::newRow("printer service") << QByteArray("/Printer") << QByteArray("printInput") << Value("Patapatapon!") << Value("success");
QTest::newRow("math service") << QByteArray("/Math") << QByteArray("twice") << Value(10.5) << Value(21.0);
}
void shouldPlaceServiceCalls()
{
QFETCH(QByteArray, path);
QFETCH(QByteArray, method);
QFETCH(Value, data);
QFETCH(Value, replyData);
Message message(path, method);
message.setData(data);
Message reply = m_client->call(message);
Message expected("/", method);
expected.setData(replyData);
sodepCompare(reply, expected);
}
void shouldUnloadService_data()
{
QTest::addColumn<QString>("serviceName");
QTest::newRow("printer service") << QString::fromUtf8("PrinterService");
QTest::newRow("math service") << QString::fromUtf8("MathService");
}
void shouldUnloadService()
{
QFETCH(QString, serviceName);
m_metaService.unloadService(serviceName);
}
};
QTEST_MAIN(TestMetaService)
#include "testmetaservice.moc"

View File

@ -1,95 +0,0 @@
/**
* This file is part of the KDE project
* Copyright (C) 2008 Kevin Ottens <ervin@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <QtCore/QBuffer>
#include <QApplication>
#include <QBoxLayout>
#include <QLineEdit>
#include <QPushButton>
#include <QtNetwork/QTcpSocket>
#include <QtJolie/Message>
#include <QtJolie/Value>
#include "../qtjolie/sodephelpers_p.h"
using namespace Jolie;
class MainWindow : public QWidget
{
Q_OBJECT
public:
MainWindow()
{
setLayout(new QHBoxLayout());
m_lineEdit = new QLineEdit(this);
layout()->addWidget(m_lineEdit);
QPushButton *button = new QPushButton(this);
button->setText(QString::fromUtf8("SEND"));
layout()->addWidget(button);
connect(button, SIGNAL(clicked()),
this, SLOT(sendMessage()));
m_socket.connectToHost(QString::fromUtf8("localhost"), 10000);
if (!m_socket.waitForConnected(10000)) {
qDebug("Failed to connect!");
return;
}
qDebug("Connected!");
}
private slots:
void sendMessage()
{
Message message("/", "printInput");
message.setData(Value(m_lineEdit->text().toUtf8()));
sodepWrite(m_socket, message);
qDebug("Message sent:");
QBuffer buffer;
buffer.open(QIODevice::WriteOnly);
sodepWrite(buffer, message);
buffer.close();
qDebug("%s", buffer.data().toHex().constData());
qDebug("Message received:");
buffer.setData(QByteArray());
buffer.open(QIODevice::WriteOnly);
message = sodepReadMessage(m_socket);
sodepWrite(buffer, message);
buffer.close();
qDebug("%s", buffer.data().toHex().constData());
}
private:
QLineEdit *m_lineEdit;
QTcpSocket m_socket;
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
MainWindow w;
w.show();
return app.exec();
}
#include "testprinter.moc"

View File

@ -1,176 +0,0 @@
/**
* This file is part of the KDE project
* Copyright (C) 2008 Kevin Ottens <ervin@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <QtCore/QObject>
#include <QtTest/QtTest>
#include <QtJolie/Value>
#include "testhelpers.h"
using namespace Jolie;
class TestValue : public QObject
{
Q_OBJECT
private slots:
void shouldHandleInvalids()
{
Value v;
QCOMPARE(v.toInt(), 0);
QCOMPARE(v.toDouble(), 0.0);
QCOMPARE(v.toByteArray(), QByteArray());
QVERIFY(!v.isValid());
QVERIFY(!v.isByteArray());
QVERIFY(!v.isInt());
QVERIFY(!v.isDouble());
}
void shouldRespectIntValues()
{
Value v1(42), v2;
QCOMPARE(v1.toInt(), 42);
QCOMPARE(v2.toInt(), 0);
QVERIFY(v1.isInt());
QVERIFY(!v2.isInt());
v2 = v1;
QCOMPARE(v2.toInt(), 42);
QVERIFY(v2.isInt());
QCOMPARE(v2.toDouble(), 0.0);
QCOMPARE(v2.toByteArray(), QByteArray());
}
void shouldRespectDoubleValues()
{
Value v1(0.42), v2;
QCOMPARE(v1.toDouble(), 0.42);
QCOMPARE(v2.toDouble(), 0.0);
QVERIFY(v1.isDouble());
QVERIFY(!v2.isDouble());
v2 = v1;
QCOMPARE(v2.toDouble(), 0.42);
QVERIFY(v2.isDouble());
QCOMPARE(v2.toInt(), 0);
QCOMPARE(v2.toByteArray(), QByteArray());
}
void shouldAutoConvertByteArrayValues()
{
Value v1("42"), v2;
QCOMPARE(v1.toByteArray(), QByteArray("42"));
QCOMPARE(v2.toByteArray(), QByteArray());
QVERIFY(v1.isByteArray());
QVERIFY(!v2.isByteArray());
v2 = v1;
QCOMPARE(v2.toByteArray(), QByteArray("42"));
QVERIFY(v2.isByteArray());
QCOMPARE(v2.toInt(), 42);
QCOMPARE(v2.toDouble(), 42.0);
}
void shouldHandleChildren()
{
Value v;
v.children("first") << Value(7) << Value(8);
v.children("second") << Value(42);
QCOMPARE(v.children("second").size(), 1);
QCOMPARE(v.children("second")[0].toInt(), 42);
QCOMPARE(v.children("first").size(), 2);
QCOMPARE(v.children("first")[0].toInt(), 7);
QCOMPARE(v.children("first")[1].toInt(), 8);
QCOMPARE(v.children("bwaaaaah!").size(), 0);
}
void shouldBeSerializable_data()
{
QTest::addColumn<Value>("original");
QTest::addColumn<QByteArray>("serialized");
QTest::newRow("empty value") << Value()
<< QByteArray::fromHex("0000000000");
QTest::newRow("double value") << Value(0.42)
<< QByteArray::fromHex("033FDAE147AE147AE100000000");
QTest::newRow("int value") << Value(42)
<< QByteArray::fromHex("020000002A00000000");
QTest::newRow("string value") << Value("foo")
<< QByteArray::fromHex("0100000003")+QByteArray("foo")
+ QByteArray::fromHex("00000000");
Value complex("complex");
complex.children("foo") << Value(42);
complex.children("bar") << Value(0.42);
QTest::newRow("complex value") << complex
<< QByteArray::fromHex("0100000007")+QByteArray("complex")
+ QByteArray::fromHex("00000002") // two children
+ QByteArray::fromHex("00000003")+QByteArray("bar")
+ QByteArray::fromHex("00000001") // one value
+ QByteArray::fromHex("033FDAE147AE147AE100000000")
+ QByteArray::fromHex("00000003")+QByteArray("foo")
+ QByteArray::fromHex("00000001") // one value
+ QByteArray::fromHex("020000002A00000000");
}
void shouldBeSerializable()
{
QBuffer buffer;
QFETCH(Value, original);
QFETCH(QByteArray, serialized);
Value result;
buffer.open(QIODevice::WriteOnly);
sodepWrite(buffer, original);
buffer.close();
buffer.open(QIODevice::ReadOnly);
result = sodepReadValue(buffer);
buffer.close();
sodepCompare(result, original);
QCOMPARE(buffer.data(), serialized);
}
};
QTEST_MAIN(TestValue)
#include "testvalue.moc"

View File

@ -1,133 +0,0 @@
/**
* This file is part of the KDE project
* Copyright (C) 2009 Kevin Ottens <ervin@kde.org>
* Copyright (C) 2009 Fabrizio Montesi <famontesi@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <QtCore/QDebug>
#include <QtCore/QTimer>
#include <QApplication>
#include <QBoxLayout>
#include <QLineEdit>
#include <QTextBrowser>
#include <QtJolie/Client>
#include <QtJolie/Message>
#include <QtJolie/MetaService>
using namespace Jolie;
class MainWindow : public QWidget
{
Q_OBJECT
public:
MainWindow()
{
setEnabled(false);
setLayout(new QVBoxLayout());
m_lineEdit = new QLineEdit(this);
m_browser = new QTextBrowser(this);
m_browser->setOpenExternalLinks(true);
layout()->addWidget(m_lineEdit);
layout()->addWidget(m_browser);
m_meta.start();
QTimer::singleShot(1000, this, SLOT(delayedInit()));
}
~MainWindow()
{
m_meta.stop();
delete m_client;
}
private slots:
void delayedInit()
{
Value aliases;
aliases.children("webSearch") << Value("webSearch?appid=%{applicationId}&query=%{query}");
Value inProtocol("http");
inProtocol.children("format") << Value("rest");
inProtocol.children("aliases") << aliases;
Value outProtocol("sodep");
m_resourcePath = m_meta.addRedirection(
QString::fromUtf8("YahooWebSearch"),
QString::fromUtf8("socket://search.yahooapis.com:80/WebSearchService/V1/"),
inProtocol,
outProtocol
);
m_client = new Client(QString::fromUtf8("localhost"), 9000);
connect(m_lineEdit, SIGNAL(returnPressed()),
this, SLOT(onReturnPressed()));
setEnabled(true);
m_lineEdit->setFocus();
}
void onReturnPressed()
{
Message request((QString::fromUtf8("/")+m_resourcePath).toUtf8(), "webSearch");
Value requestData;
requestData.children("applicationId") << Value("UrlfFCDV34F.d8xYpsswjaA7P.unhHJ6ELvrhhIb.ybJeUHh.POHIkSf_YO0Fw--");
requestData.children("query") << Value(m_lineEdit->text().toUtf8());
request.setData(requestData);
Message response = m_client->call(request);
m_browser->clear();
QString html = QString::fromUtf8("<html><body>");
foreach (const Value &value, response.data().children("Result")) {
QString url = QString::fromUtf8(value.children("Url").first().toByteArray());
QString title = QString::fromUtf8(value.children("Title").first().toByteArray());
QString summary = QString::fromUtf8(value.children("Summary").first().toByteArray());
html+= QString::fromUtf8(
"<div><a href=\"%1\"><b>%2</b></a></div>"
"<div>%3</div><br/>"
).arg(url).arg(title).arg(summary);
}
html+= QString::fromUtf8("</body></html>");
m_browser->setHtml(html);
}
private:
MetaService m_meta;
QLineEdit *m_lineEdit;
QTextBrowser *m_browser;
Client *m_client;
QString m_resourcePath;
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
MainWindow w;
w.show();
return app.exec();
}
#include "trivialyahooclient.moc"

View File

@ -1,214 +0,0 @@
/**
* This file is part of the KDE project
* Copyright (C) 2009 Kevin Ottens <ervin@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <QtCore/QDebug>
#include <QtCore/QTimer>
#include <QApplication>
#include <QBoxLayout>
#include <QLineEdit>
#include <QTextBrowser>
#include <QtJolie/AbstractAdaptor>
#include <QtJolie/Client>
#include <QtJolie/Message>
#include <QtJolie/Server>
#include <unistd.h>
#include "ui_visiondriverwidget.h"
using namespace Jolie;
class MainWindow;
class PresenterAdaptor : public AbstractAdaptor
{
Q_OBJECT
public:
PresenterAdaptor(MainWindow *parent);
private:
void relay(Server *server, int clientId, const Message &message);
MainWindow *m_window;
};
class MainWindow : public QWidget
{
Q_OBJECT
public:
MainWindow()
: m_client(0), m_server(0), m_sessionId(-1)
{
ui.setupUi(this);
m_server = new Server(9002);
PresenterAdaptor *adaptor = new PresenterAdaptor(this);
m_server->registerAdaptor("/", adaptor);
sleep(2);
connect(ui.connectButton, SIGNAL(clicked()), SLOT(onConnect()));
connect(ui.previousButton, SIGNAL(clicked()), SLOT(onPrevious()));
connect(ui.nextButton, SIGNAL(clicked()), SLOT(onNext()));
}
~MainWindow()
{
if (m_sessionId>=0) {
Message m("/", "closeClientSession");
m.setData(Value(m_sessionId));
m_client->callNoReply(m);
sleep(2);
}
delete m_client;
delete m_server;
}
void pageChanged(int pageNumber)
{
qDebug() << "New page is:" << pageNumber;
m_currentPage = pageNumber;
updateTextContent();
}
void documentChanged(const QString &url)
{
qDebug() << "New document is:" << url;
m_currentDocument = url;
updateTextContent();
}
private slots:
void onConnect()
{
if (m_sessionId>=0) {
Message m("/", "closeClientSession");
m.setData(Value(m_sessionId));
m_client->callNoReply(m);
sleep(2);
}
m_sessionId = -1;
delete m_client;
m_client = new Client(ui.visionHostname->text(),
ui.visionPort->value());
QString location = QString::fromUtf8("socket://%1:%2")
.arg(ui.driverHostname->text())
.arg(ui.driverPort->value());
Value data;
data.children("location") << Value(location.toUtf8());
Message request("/", "startClientSession");
request.setData(data);
Message reply = m_client->call(request);
data = reply.data();
m_sessionId = data.children("sid").first().toInt();
qDebug() << "Got session ID:" << m_sessionId;
}
void onPrevious()
{
requestNewPage(m_currentPage-1);
}
void onNext()
{
requestNewPage(m_currentPage+1);
}
private:
void updateTextContent()
{
ui.textContent->setHtml(
QString::fromUtf8(
"<div>%1</div><br/><br/>"
"<div align=\"center\"><h1>%2</h1></div><br/><br/>"
).arg(m_currentDocument).arg(m_currentPage)
);
}
void requestNewPage(int page)
{
Value data;
data.children("pageNumber") << Value(page);
data.children("local") << Value(0);
Message request("/", "goToPage");
request.setData(data);
m_client->call(request);
}
Ui::VisionDriverWidget ui;
Client *m_client;
Server *m_server;
int m_sessionId;
int m_currentPage;
QString m_currentDocument;
};
PresenterAdaptor::PresenterAdaptor(MainWindow *parent)
: AbstractAdaptor(parent), m_window(parent)
{
}
void PresenterAdaptor::relay(Server *server, int clientId, const Message &message)
{
if ((message.resourcePath()=="/") && (message.operationName()=="goToPage")) {
int pageNumber = 0;
if (message.data().isValid()) {
pageNumber = message.data().toInt();
} else {
pageNumber = message.data().children("pageNumber").first().toInt();
}
m_window->pageChanged(pageNumber);
} else if ((message.resourcePath()=="/") && (message.operationName()=="openDocument")) {
QString url;
if (message.data().isValid()) {
url = QString::fromUtf8(message.data().toByteArray());
} else {
url = QString::fromUtf8(message.data().children("documentUrl").first().toByteArray());
}
m_window->documentChanged(url);
} else {
qDebug() << "Got an unknown message:" << message.resourcePath()
<< message.operationName();
}
server->sendReply(clientId, Message());
}
int main(int argc, char **argv)
{
QApplication app(argc, argv);
MainWindow w;
w.show();
return app.exec();
}
#include "visiondriver.moc"

View File

@ -1,115 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>VisionDriverWidget</class>
<widget class="QWidget" name="VisionDriverWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>729</width>
<height>396</height>
</rect>
</property>
<property name="windowTitle">
<string>Vision Driver</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QPushButton" name="previousButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Previous</string>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLineEdit" name="visionHostname">
<property name="text">
<string notr="true">localhost</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="visionPort">
<property name="maximum">
<number>65535</number>
</property>
<property name="value">
<number>9001</number>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="connectButton">
<property name="text">
<string>Connect</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QTextBrowser" name="textContent"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="driverHostname">
<property name="text">
<string notr="true">localhost</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="driverPort">
<property name="maximum">
<number>65535</number>
</property>
<property name="value">
<number>9002</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="QPushButton" name="nextButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Next</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -1,248 +0,0 @@
/*
* Copyright © 2009 Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2 as
* published by the Free Software Foundation
*
* 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "remotedataengine_p.h"
#include "remoteservice_p.h"
#include "../remote/accessmanager.h"
#include "../remote/serviceaccessjob.h"
#include "../service.h"
#include "../servicejob.h"
#include <QTimer>
#include <QUuid>
#include <qurl.h>
#include <qurlpathinfo.h>
namespace Plasma
{
RemoteDataEngine::RemoteDataEngine(const QUrl &location, QObject* parent, const QVariantList& args)
: Plasma::DataEngine(parent, args),
m_service(0),
m_location(location),
m_uuid("")
{
if (!location.isEmpty()) {
setLocation(location);
} else {
#ifndef NDEBUG
kDebug() << "LOCATION IS EMPTY";
#endif
}
}
RemoteDataEngine::~RemoteDataEngine()
{
}
void RemoteDataEngine::setLocation(const QUrl &location)
{
m_location = location;
setMinimumPollingInterval(1000);
setPollingInterval(5000);
m_uuid = QUuid::createUuid().toString();
Service *service = Service::access(location);
connect(service, SIGNAL(serviceReady(Plasma::Service*)),
this, SLOT(serviceReady(Plasma::Service*)));
}
Plasma::Service* RemoteDataEngine::serviceForSource(const QString& source)
{
if (m_serviceForSource.contains(source)) {
return m_serviceForSource[source];
} else {
RemoteService *service = new RemoteService(this);
initRemoteService(source, service);
return service;
}
}
void RemoteDataEngine::initRemoteService(const QString &source, RemoteService *service)
{
if (m_service) {
KConfigGroup op = m_service->operationDescription("ServiceForSource");
op.writeEntry("SourceName", source);
m_service->startOperationCall(op);
m_serviceForSource[source] = service;
} else {
m_pendingServices[source] = service;
}
}
void RemoteDataEngine::serviceReady(Plasma::Service *service)
{
m_service = service;
KConfigGroup op = m_service->operationDescription("GetSourceNames");
m_service->startOperationCall(op);
connect(m_service, SIGNAL(finished(Plasma::ServiceJob*)),
this, SLOT(remoteCallFinished(Plasma::ServiceJob*)));
//FIXME: every 5s? this MUST become push rather than pull
QTimer *timer = new QTimer(this);
timer->setInterval(5000);
connect(timer, SIGNAL(timeout()), this, SLOT(updateSources()));
timer->start();
}
QStringList RemoteDataEngine::sources() const
{
return m_sources.toList();
}
void RemoteDataEngine::remoteCallFinished(Plasma::ServiceJob *job)
{
if (job->operationName() == "GetSourceNames") {
#ifndef NDEBUG
kDebug() << "get source names";
#endif
const QSet<QString> oldsources = m_sources;
m_sources = QSet<QString>::fromList(job->result().toStringList());
//first check if there are sources that have to be removed:
foreach (const QString &source, oldsources) {
if (!m_sources.contains(source)) {
#ifndef NDEBUG
kDebug() << "source no longer exists... remove that data.";
#endif
removeSource(source);
emit sourceRemoved(source);
}
}
//are there sources that have to be added?
{
// we have to check the current container dict, because we may have added
// an empty data set in a call to sourceRequestEvent before the service was
// ready; in this case, it will already exist in the engine's container
// collection and be listed in pendingSources.
// we also have to check oldSources since it may be in there, but never
// actually connected to from the local side
const SourceDict s = containerDict();
foreach (const QString &source, m_sources) {
if (!oldsources.contains(source) && !s.contains(source)) {
#ifndef NDEBUG
kDebug() << "new source = " << source;
#endif
emit sourceAdded(source);
}
}
}
//and now check and update any pending resources
foreach (const QString &pendingSource, m_pendingSources) {
createSource(pendingSource);
}
m_pendingSources.clear();
} else if (job->operationName() == "GetSource") {
QString source = job->parameters().value("SourceName").toString();
#ifndef NDEBUG
kDebug() << "setting data for " << source;
#endif
bool newSource = !m_sources.contains(source);
if (job->result().type() == QVariant::Bool && job->result().toBool() == false) {
#ifndef NDEBUG
kDebug() << "there is no update";
#endif
if (newSource) {
// the source doesn't exist on the remote side!
removeSource(source);
emit sourceRemoved(source);
m_pendingServices.remove(source);
}
} else {
if (newSource) {
m_sources.insert(source);
emit sourceAdded(source);
RemoteService *rs = m_pendingServices.value(source);
if (rs) {
m_pendingServices.remove(source);
initRemoteService(source, rs);
}
}
setData(source, static_cast<Plasma::DataEngine::Data>(job->result().toHash()));
}
} else {
QString source = job->parameters().value("SourceName").toString();
#ifndef NDEBUG
kDebug() << "setting serviceForSource for " << source;
#endif
QString resource = job->result().toString();
QUrlPathInfo loc(m_location);
loc.setFileName(resource);
RemoteService *rs = m_serviceForSource.value(source);
if (rs) {
rs->setLocation(loc.url());
} else {
#ifndef NDEBUG
kDebug() << "no such service?" << source;
#endif
}
}
}
bool RemoteDataEngine::updateSourceEvent(const QString &source)
{
if (!m_service) {
return false;
}
KConfigGroup op = m_service->operationDescription("GetSource");
op.writeEntry("SourceName", source);
op.writeEntry("UUID", m_uuid);
m_service->startOperationCall(op);
return false;
}
bool RemoteDataEngine::sourceRequestEvent(const QString &source)
{
setData(source, Data());
if (m_service) {
createSource(source);
} else {
m_pendingSources.append(source);
}
return true;
}
void RemoteDataEngine::createSource(const QString &source)
{
KConfigGroup op = m_service->operationDescription("GetSource");
op.writeEntry("SourceName", source);
op.writeEntry("UUID", m_uuid);
m_service->startOperationCall(op);
}
void RemoteDataEngine::updateSources()
{
if (m_service) {
KConfigGroup op = m_service->operationDescription("GetSourceNames");
m_service->startOperationCall(op);
}
}
}
#include "moc_remotedataengine_p.cpp"

View File

@ -1,68 +0,0 @@
/*
* Copyright © 2008 Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2 as
* published by the Free Software Foundation
*
* 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef REMOTEDATAENGINE_H
#define REMOTEDATAENGINE_H
#include "../dataengine.h"
#include "remoteservice_p.h"
#include <QtCore/QSet>
class JobView;
namespace Plasma
{
class Service;
class ServiceAccessJob;
class RemoteDataEngine : public Plasma::DataEngine
{
Q_OBJECT
public:
RemoteDataEngine(const QUrl &location, QObject* parent = 0, const QVariantList &args = QVariantList());
~RemoteDataEngine();
Plasma::Service* serviceForSource(const QString& source);
void setLocation(const QUrl &location);
protected:
QStringList sources() const;
bool updateSourceEvent(const QString &source);
bool sourceRequestEvent(const QString &source);
private Q_SLOTS:
void serviceReady(Plasma::Service *service);
void remoteCallFinished(Plasma::ServiceJob *job);
void updateSources();
void createSource(const QString &source);
void initRemoteService(const QString &source, RemoteService *service);
private:
Service *m_service;
QSet<QString> m_sources;
QHash<QString, RemoteService *> m_serviceForSource;
QHash<QString, RemoteService *> m_pendingServices;
QStringList m_pendingSources;
QUrl m_location;
QString m_uuid;
};
} // namespace Plasma
#endif

View File

@ -1,313 +0,0 @@
/*
* Copyright © 2009 Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2 as
* published by the Free Software Foundation
*
* 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "remoteservice_p.h"
#include "../remote/accessmanager.h"
#include "../remote/authorizationinterface.h"
#include "../remote/authorizationmanager.h"
#include "../remote/clientpinrequest.h"
#include "../service.h"
#include "authorizationmanager_p.h"
#include "joliemessagehelper_p.h"
#include "remoteservicejob_p.h"
#include "service_p.h"
#include <QtCore/QBuffer>
#include <QtCore/QObject>
#include <QtCore/QTimer>
#include <QtCore/QUuid>
#include <QtJolie/Client>
#include <QtJolie/Message>
#include <QtJolie/PendingReply>
#include <QtJolie/PendingCall>
#include <QtJolie/PendingCallWatcher>
#include <QtJolie/Value>
#include <kdebug.h>
#include <qurl.h>
#include <qurlpathinfo.h>
namespace Plasma
{
RemoteService::RemoteService(QObject* parent)
: Service(parent),
m_client(0),
m_ready(false),
m_busy(false)
{
}
RemoteService::RemoteService(QObject* parent, const QUrl &location)
: Service(parent),
m_location(location),
m_client(0),
m_ready(false),
m_busy(false)
{
if (AuthorizationManager::self()->d->myCredentials.isValid()) {
setLocation(location);
} else {
connect(AuthorizationManager::self(), SIGNAL(readyForRemoteAccess()),
this, SLOT(slotReadyForRemoteAccess()));
}
}
RemoteService::~RemoteService()
{
delete m_client;
}
void RemoteService::slotReadyForRemoteAccess()
{
#ifndef NDEBUG
kDebug() << "AuthorizationManager is now ready for remote access!";
#endif
setLocation(m_location);
}
static QByteArray resourcePathFromUrl(const QUrl& location)
{
QUrlPathInfo pi(location);
return pi.path(QUrlPathInfo::StripTrailingSlash).remove(0, 1).toUtf8();
}
void RemoteService::setLocation(const QUrl &location)
{
#ifndef NDEBUG
kDebug() << "Setting RemoteService location to " << location;
#endif
m_uuid = QUuid::createUuid().toString();
Credentials identity = AuthorizationManager::self()->d->myCredentials;
if (!identity.canSign()) {
#ifndef NDEBUG
kDebug() << "we can't sign? how did we get here?";
#endif
return;
}
if (m_client && (m_location != location)) {
delete m_client;
m_client = new Jolie::Client(location.host(), location.port());
}
if (!m_client) {
m_client = new Jolie::Client(location.host(), location.port());
}
m_location = location;
QByteArray identityByteArray;
QDataStream stream(&identityByteArray, QIODevice::WriteOnly);
stream << identity.toPublicCredentials();
Jolie::Message getOpDesc(resourcePathFromUrl(location), "startConnection");
Jolie::Value data;
data.children(JolieMessage::Field::IDENTITY) << Jolie::Value(identityByteArray);
data.children(JolieMessage::Field::UUID) << Jolie::Value(m_uuid.toLatin1());
getOpDesc.setData(data);
Jolie::PendingCall pendingReply = m_client->asyncCall(getOpDesc);
Jolie::PendingCallWatcher *watcher = new Jolie::PendingCallWatcher(pendingReply, this);
connect(watcher, SIGNAL(finished(Jolie::PendingCallWatcher*)),
this, SLOT(callCompleted(Jolie::PendingCallWatcher*)));
}
QString RemoteService::location() const
{
return m_location.toDisplayString();
}
bool RemoteService::isReady() const
{
return m_ready;
}
bool RemoteService::isBusy() const
{
return m_busy;
}
void RemoteService::callCompleted(Jolie::PendingCallWatcher *watcher)
{
Jolie::PendingReply reply = *watcher;
Jolie::Message response = reply.reply();
if (response.operationName() == "startConnection") {
#ifndef NDEBUG
kDebug() << "Started connection: fetching .operations";
#endif
m_token = JolieMessage::field(JolieMessage::Field::TOKEN, response);
Jolie::Message getOpDesc(resourcePathFromUrl(m_location), "getOperations");
//TODO: async
Jolie::PendingCall pendingReply = m_client->asyncCall(signMessage(getOpDesc));
Jolie::PendingCallWatcher *watcher = new Jolie::PendingCallWatcher(pendingReply, this);
connect(watcher, SIGNAL(finished(Jolie::PendingCallWatcher*)),
this, SLOT(callCompleted(Jolie::PendingCallWatcher*)));
} else if (response.operationName() == "getOperations") {
if (response.fault().name() == JolieMessage::Error::REQUIREPIN) {
#ifndef NDEBUG
kDebug() << "pin required, request auth interface";
#endif
ClientPinRequest *request = new ClientPinRequest(this);
connect(request, SIGNAL(changed(Plasma::ClientPinRequest*)),
this, SLOT(slotGotPin(Plasma::ClientPinRequest*)));
AuthorizationManager::self()->d->authorizationInterface->clientPinRequest(*request);
} else {
#ifndef NDEBUG
kDebug() << "RemoteService is now ready for use!";
#endif
m_operationsScheme = JolieMessage::field(JolieMessage::Field::OPERATIONSDESCRIPTION, response);
m_token = JolieMessage::field(JolieMessage::Field::TOKEN, response);
m_ready = true;
setName(location());
//if there's stuff in the queue, let it continue.
slotFinished();
}
} else if (response.operationName() == "getEnabledOperations") {
//TODO: optimize.
m_token = JolieMessage::field(JolieMessage::Field::TOKEN, response);
QByteArray enabledOperations = JolieMessage::field(JolieMessage::Field::ENABLEDOPERATIONS, response);
QDataStream in(&enabledOperations, QIODevice::ReadOnly);
QStringList enabledOperationsList;
in >> enabledOperationsList;
foreach (const QString &operation, operationNames()) {
if (enabledOperationsList.contains(operation) && !isOperationEnabled(operation)) {
#ifndef NDEBUG
kDebug() << "yeah, we're enabling the operation with the name " << operation;
#endif
setOperationEnabled(operation, true);
} else if (!enabledOperationsList.contains(operation) && isOperationEnabled(operation)) {
#ifndef NDEBUG
kDebug() << "we're disabling the operation with the name " << operation;
#endif
setOperationEnabled(operation, false);
}
}
//if there's stuff in the queue, let it continue.
m_busy = false;
slotFinished();
} else {
#ifndef NDEBUG
kDebug() << "How did we end up here?";
#endif
}
}
void RemoteService::slotGotPin(Plasma::ClientPinRequest *request)
{
Jolie::Message getOpDesc(resourcePathFromUrl(m_location), "getOperations");
Jolie::Value value;
value.children(JolieMessage::Field::PARAMETERS) << Jolie::Value(QByteArray());
if (!request->pin().isEmpty()) {
value.children(JolieMessage::Field::PIN) << Jolie::Value(request->pin().toLatin1());
}
getOpDesc.setData(value);
//TODO: async
Jolie::PendingCall pendingReply = m_client->asyncCall(signMessage(getOpDesc));
Jolie::PendingCallWatcher *watcher = new Jolie::PendingCallWatcher(pendingReply, this);
connect(watcher, SIGNAL(finished(Jolie::PendingCallWatcher*)),
this, SLOT(callCompleted(Jolie::PendingCallWatcher*)));
}
void RemoteService::registerOperationsScheme()
{
QBuffer buffer(&m_operationsScheme);
buffer.open(QBuffer::ReadWrite);
setOperationsScheme(&buffer);
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(slotUpdateEnabledOperations()));
//FIXME: get some sensible interval depending on the connection speed. This is kind of stupid.
timer->start(2000);
}
void RemoteService::slotUpdateEnabledOperations()
{
//TODO: maybe push the get enabled operations also on the queue?
if (!m_busy) {
m_busy = true;
Jolie::Message getOpDesc(resourcePathFromUrl(m_location), "getEnabledOperations");
Jolie::PendingCall pendingReply = m_client->asyncCall(signMessage(getOpDesc));
Jolie::PendingCallWatcher *watcher = new Jolie::PendingCallWatcher(pendingReply, this);
connect(watcher, SIGNAL(finished(Jolie::PendingCallWatcher*)),
this, SLOT(callCompleted(Jolie::PendingCallWatcher*)));
} else {
#ifndef NDEBUG
kDebug() << "We would like to update enabled operations, but are still busy so let's wait for now.";
#endif
}
}
ServiceJob* RemoteService::createJob(const QString& operation,
QHash<QString,QVariant>& parameters)
{
if (!m_ready) {
#ifndef NDEBUG
kDebug() << "Use of this service hasn't checked for the serviceReady signal, which it should.";
#endif
}
ServiceJob *job = new RemoteServiceJob(m_location, destination(), operation, parameters, m_token, this);
connect(job, SIGNAL(finished(KJob*)), this, SLOT(slotFinished()));
return job;
}
void RemoteService::slotFinished()
{
if (!m_queue.isEmpty()) {
#ifndef NDEBUG
kDebug() << "Job finished, there are still service jobs in queue, starting next in queue.";
#endif
ServiceJob *job = m_queue.dequeue();
QTimer::singleShot(0, job, SLOT(slotStart()));
}
}
Jolie::Message RemoteService::signMessage(const Jolie::Message &message) const
{
Jolie::Message response(message);
Credentials identity = AuthorizationManager::self()->d->myCredentials;
if (!identity.isValid()) {
#ifndef NDEBUG
kDebug() << "We don't have our identity yet, just drop this message";
#endif
return response;
}
Jolie::Value data = response.data();
data.children(JolieMessage::Field::IDENTITYID) << Jolie::Value(identity.id().toLatin1());
data.children(JolieMessage::Field::TOKEN) << Jolie::Value(m_token);
data.children(JolieMessage::Field::UUID) << Jolie::Value(m_uuid.toLatin1());
response.setData(data);
data.children(JolieMessage::Field::SIGNATURE) <<
Jolie::Value(identity.signMessage(JolieMessage::payload(response)));
response.setData(data);
return response;
}
} //namespace Plasma
#include "moc_remoteservice_p.cpp"

View File

@ -1,87 +0,0 @@
/*
* Copyright © 2008 Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2 as
* published by the Free Software Foundation
*
* 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef PLASMA_REMOTESERVICE_P_H
#define PLASMA_REMOTESERVICE_P_H
#include <QtCore/QQueue>
#include <QtJolie/Message>
#include <QtCore/QUrl>
#include "../service.h"
namespace Jolie
{
class Client;
class PendingCallWatcher;
}
namespace Plasma
{
class ClientPinRequest;
class RemoteServiceJob;
class RemoteService : public Plasma::Service
{
Q_OBJECT
public:
RemoteService(QObject* parent);
RemoteService(QObject* parent, const QUrl &location);
~RemoteService();
void setLocation(const QUrl &location);
QString location() const;
bool isReady() const;
bool isBusy() const;
protected:
ServiceJob* createJob(const QString& operation,
QHash<QString,QVariant>& parameters);
void registerOperationsScheme();
private Q_SLOTS:
void callCompleted(Jolie::PendingCallWatcher *watcher);
void slotFinished();
void slotGotPin(Plasma::ClientPinRequest *request);
void slotUpdateEnabledOperations();
void slotReadyForRemoteAccess();
private:
Jolie::Message signMessage(const Jolie::Message &message) const;
private:
QUrl m_location;
Jolie::Client *m_client;
QByteArray m_token;
QByteArray m_operationsScheme;
bool m_ready;
QQueue<RemoteServiceJob*> m_queue;
bool m_busy;
QString m_pin;
QString m_uuid;
friend class RemoteServiceJob;
};
} //namespace Plasma
#endif // PLASMA_REMOTESERVICE_P_H

View File

@ -1,183 +0,0 @@
/*
* Copyright © 2009 Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2 as
* published by the Free Software Foundation
*
* 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "remoteservicejob_p.h"
#include <kconfiggroup.h>
#include <kurl.h>
#include <QtCore/QBuffer>
#include <QtJolie/Client>
#include <QtJolie/Message>
#include <QtJolie/PendingCallWatcher>
#include <QtJolie/PendingReply>
#include "../servicejob.h"
#include "../remote/accessmanager.h"
#include "../remote/authorizationmanager.h"
#include "authorizationmanager_p.h"
#include "remoteservice_p.h"
#include "servicejob_p.h"
#include "joliemessagehelper_p.h"
#include <qtimer.h>
namespace Plasma
{
RemoteServiceJob::RemoteServiceJob(KUrl location,
const QString& destination,
const QString& operation,
QHash<QString,QVariant>& parameters,
QByteArray initialToken,
RemoteService* parent)
: ServiceJob(destination, operation, parameters, parent),
m_token(initialToken),
m_location(location),
m_service(parent),
m_delayedDesc(0)
{
}
RemoteServiceJob::~RemoteServiceJob()
{
delete m_delayedDesc;
m_delayedDesc = 0;
}
void RemoteServiceJob::start()
{
QTimer::singleShot(30000, this, SLOT(timeout()));
if (m_service->m_busy || !m_service->m_ready) {
//enqueue and wait
m_service->m_queue.enqueue(this);
#ifndef NDEBUG
kDebug() << "already busy... enqueue, queue contains " << m_service->m_queue.count();
#endif
return;
}
// the service is now busy ... with us!
m_service->m_busy = true;
// while waiting in the queue, our validity may have changed; it's all async
// so don't assume anything
checkValidity();
if (error()) {
emitResult();
return;
}
//serialize the parameters
QByteArray params;
QBuffer buffer(&params);
buffer.open(QIODevice::WriteOnly);
QDataStream out(&buffer);
out << parameters();
Jolie::Message message(m_location.path(KUrl::RemoveTrailingSlash).remove(0, 1).toUtf8(),
"startOperationCall");
Jolie::Value data;
data.children(JolieMessage::Field::OPERATION) << (Jolie::Value(operationName().toLatin1()));
data.children(JolieMessage::Field::PARAMETERS) << Jolie::Value(params);
data.children(JolieMessage::Field::DESTINATION) << Jolie::Value(destination().toLatin1());
message.setData(data);
Jolie::Client *client = m_service->m_client;
Jolie::PendingCall pendingReply = client->asyncCall(m_service->signMessage(message));
Jolie::PendingCallWatcher *watcher = new Jolie::PendingCallWatcher(pendingReply, this);
connect(watcher, SIGNAL(finished(Jolie::PendingCallWatcher*)),
this, SLOT(callCompleted(Jolie::PendingCallWatcher*)));
}
void RemoteServiceJob::setDelayedDescription(const KConfigGroup &desc)
{
if (!m_delayedDesc) {
m_delayedDesc = new KConfigGroup(desc);
} else {
*m_delayedDesc = desc;
}
}
void RemoteServiceJob::checkValidity()
{
if (!m_service->isOperationEnabled(operationName())) {
setError(-1);
setErrorText(i18n("Job no longer valid, operation is not enabled."));
} else if (m_delayedDesc) {
d->parameters = m_service->parametersFromDescription(*m_delayedDesc);
} else {
KConfigGroup description = m_service->operationDescription(operationName());
QHashIterator<QString, QVariant> param(parameters());
while (param.hasNext()) {
param.next();
if (!description.hasKey(param.key())) {
setError(-1);
setErrorText(i18n("Job no longer valid, invalid parameters."));
break;
}
}
}
delete m_delayedDesc;
m_delayedDesc = 0;
}
void RemoteServiceJob::callCompleted(Jolie::PendingCallWatcher *watcher)
{
m_service->m_busy = false;
Jolie::PendingReply reply = *watcher;
Jolie::Message response = reply.reply();
//TODO:async
if (response.fault().isValid()) {
#ifndef NDEBUG
kDebug() << "fault: " << response.fault().name();
#endif
setError(-1);
setErrorText(JolieMessage::errorMessage(response.fault().name()));
emitResult();
return;
}
m_service->m_token = JolieMessage::field(JolieMessage::Field::TOKEN, response);
QVariant variantResult;
QByteArray byteArrayResult = JolieMessage::field(JolieMessage::Field::RESULT, response);
QBuffer buffer(&byteArrayResult);
buffer.open(QIODevice::ReadOnly);
QDataStream in(&buffer);
in >> variantResult;
setResult(variantResult);
}
void RemoteServiceJob::timeout()
{
m_service->m_busy = false;
#ifndef NDEBUG
kDebug() << "Service job timed out.";
#endif
setError(-1);
setErrorText(i18n("Timeout."));
m_service->m_queue.removeAll(this);
emitResult();
}
} // namespace Plasma

View File

@ -1,70 +0,0 @@
/*
* Copyright © 2009 Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2 as
* published by the Free Software Foundation
*
* 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef PLASMA_REMOTESERVICEJOB_P_H
#define PLASMA_REMOTESERVICEJOB_P_H
#include <QtCore/QByteArray>
#include <kurl.h>
#include "../servicejob.h"
class KConfigGroup;
namespace Jolie
{
class PendingCallWatcher;
}
namespace Plasma
{
class RemoteService;
class RemoteServiceJob : public Plasma::ServiceJob
{
Q_OBJECT
public:
RemoteServiceJob(KUrl location,
const QString& destination,
const QString& operation,
QHash<QString,QVariant>& parameters,
QByteArray initialToken,
RemoteService *parent);
~RemoteServiceJob();
void start();
void setDelayedDescription(const KConfigGroup &desc);
private Q_SLOTS:
void callCompleted(Jolie::PendingCallWatcher *watcher);
void timeout();
private:
void checkValidity();
QByteArray m_token;
KUrl m_location;
RemoteService *m_service;
KConfigGroup *m_delayedDesc;
};
} // namespace Plasma
#endif // PLASMA_REMOTESERVICEJOB_P_H

View File

@ -35,13 +35,11 @@
#include <dnssd/servicebrowser.h>
#include "plasma/configloader.h"
#include "accessmanager_p.h"
namespace Plasma
{
class ConfigLoader;
class ServiceProvider;
class NullServiceJob : public ServiceJob
{
@ -81,8 +79,7 @@ public:
: q(service),
config(0),
dummyConfig(0),
publicService(0),
serviceProvider(0)
publicService(0)
{
}
@ -96,13 +93,6 @@ public:
void associatedItemDestroyed(QObject *obj);
void publish(AnnouncementMethods methods, const QString &name,
const KPluginInfo &metadata = KPluginInfo());
void unpublish();
bool isPublished() const;
KConfigGroup dummyGroup();
Service *q;
@ -112,7 +102,6 @@ public:
ConfigLoader *config;
KConfig *dummyConfig;
DNSSD::PublicService *publicService;
ServiceProvider *serviceProvider;
QMultiHash<QWidget *, QString> associatedWidgets;
QMultiHash<QGraphicsObject *, QString> associatedItems;
QSet<QString> disabledOperations;

View File

@ -19,7 +19,6 @@
#ifndef SERVICEJOB_P_H
#define SERVICEJOB_P_H
#include "../remote/credentials.h"
#include "../servicejob.h"
#include <QString>
@ -45,7 +44,6 @@ public:
QString operation;
QHash<QString, QVariant> parameters;
QVariant result;
Credentials identity;
bool m_allowAutoStart;
};

View File

@ -1,534 +0,0 @@
/*
* Copyright © 2009 Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2 as
* published by the Free Software Foundation
*
* 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "serviceprovider_p.h"
#include <QtCore/QBuffer>
#include <QtCore/QFile>
#include <QtCore/QUuid>
#include "authorizationrule_p.h"
#include "authorizationmanager_p.h"
#include "joliemessagehelper_p.h"
#include "config-plasma.h"
#include <plasma/remote/authorizationinterface.h>
#include <plasma/remote/authorizationmanager.h>
#include <plasma/remote/authorizationrule.h>
#include <plasma/remote/credentials.h>
#include <plasma/service.h>
#include <plasma/servicejob.h>
#include <plasma/private/servicejob_p.h>
#include <QtJolie/Server>
#if ENABLE_REMOTE_WIDGETS
#include <QtCrypto>
#endif
#include <kdebug.h>
#include <qstandardpaths.h>
namespace Plasma
{
ServiceProvider::ServiceProvider(const QString &name, Service *service)
: Jolie::AbstractAdaptor(service),
m_service(service)
{
connect(service, SIGNAL(finished(Plasma::ServiceJob*)),
this, SLOT(operationCompleted(Plasma::ServiceJob*)));
m_providerName = name;
AuthorizationManager::self()->d->server->registerAdaptor(m_providerName.toUtf8(), this);
#ifndef NDEBUG
kDebug() << "registered service provider " << m_providerName;
#endif
}
ServiceProvider::~ServiceProvider()
{
AuthorizationManager::self()->d->server->unregisterAdaptor(m_providerName.toUtf8());
}
void ServiceProvider::startOperationCall(Jolie::Message message)
{
#ifndef NDEBUG
kDebug() << "starting operation call";
#endif
KConfigGroup description =
m_service->operationDescription(QString(JolieMessage::field(JolieMessage::Field::OPERATION, message)));
//deserialize the parameters
QByteArray parametersByteArray;
parametersByteArray = JolieMessage::field(JolieMessage::Field::PARAMETERS, message);
#ifndef NDEBUG
kDebug() << "parameters byte array: " << parametersByteArray.toBase64();
#endif
QBuffer buffer(&parametersByteArray);
buffer.open(QIODevice::ReadOnly);
QDataStream in(&buffer);
QMap<QString, QVariant> parameters;
in >> parameters;
if (!description.isValid()) {
#ifndef NDEBUG
kDebug() << "invalid description.";
#endif
}
#ifndef NDEBUG
kDebug() << "====PARAMETERS====";
#endif
//write the parameters into the operation description
QMap<QString, QVariant>::const_iterator it = parameters.constBegin();
QMap<QString, QVariant>::const_iterator itEnd = parameters.constEnd();
for ( ; it != itEnd; ++it) {
const QString key = it.key();
const QVariant value = it.value();
#ifndef NDEBUG
kDebug() << "key = " << key << ", value = " << value;
#endif
description.writeEntry(key, value);
}
m_service->setDestination(JolieMessage::field(JolieMessage::Field::DESTINATION, message));
ServiceJob *job = m_service->startOperationCall(description);
QString identityID = JolieMessage::field(JolieMessage::Field::IDENTITYID, message);
job->d->identity = AuthorizationManager::self()->d->getCredentials(identityID);
#ifndef NDEBUG
kDebug() << "adding into messagemap:" << ((QObject*)job);
#endif
m_messageMap[job] = message;
}
void ServiceProvider::sendOperations(Jolie::Message message)
{
#ifndef NDEBUG
kDebug() << "send operations.";
#endif
//kDebug() << printJolieMessage(message);
Jolie::Message response(message.resourcePath(), message.operationName(), message.id());
//FIXME: this is duplicated from Plasma::Service
QString path = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "plasma/services/" + m_service->name() +
".operations");
if (path.isEmpty()) {
#ifndef NDEBUG
kDebug() << "Cannot find operations description:" << m_service->name() << ".operations";
#endif
response.setFault(Jolie::Fault("NoOperationsDescription"));
} else {
#ifndef NDEBUG
kDebug() << "file = " << path;
#endif
QFile file(path);
file.open(QIODevice::ReadOnly);
Jolie::Value value;
value.children(JolieMessage::Field::OPERATIONSDESCRIPTION) << Jolie::Value(file.readAll());
file.close();
response.setData(value);
}
QByteArray id = JolieMessage::field(JolieMessage::Field::IDENTITYID, message);
QByteArray uuid = JolieMessage::field(JolieMessage::Field::UUID, message);
response = appendToken(response, id, uuid);
#ifndef NDEBUG
kDebug() << "caller = " << id.toBase64();
#endif
//hack around the not yet async service adaptor api in qtjolie
if (m_descriptorMap.contains(id + uuid)) {
#ifndef NDEBUG
kDebug() << "descriptor found, sending message";
#endif
AuthorizationManager::self()->d->server->sendReply(
m_descriptorMap.value(id + uuid), response);
} else {
#ifndef NDEBUG
kDebug() << "no valid entry in descriptormap.";
#endif
}
}
void ServiceProvider::sendEnabledOperations(Jolie::Message message)
{
#ifndef NDEBUG
kDebug() << "send enabled operations.";
#endif
Jolie::Message response(message.resourcePath(), message.operationName(), message.id());
QStringList enabledOperationsList;
foreach (const QString &operation, m_service->operationNames()) {
if (m_service->isOperationEnabled(operation)) {
enabledOperationsList << operation;
}
}
#ifndef NDEBUG
kDebug() << "enabled operations: " << enabledOperationsList;
#endif
QByteArray enabledOperationsArray;
QDataStream out(&enabledOperationsArray, QIODevice::WriteOnly);
out << enabledOperationsList;
Jolie::Value value;
value.children(JolieMessage::Field::ENABLEDOPERATIONS) << Jolie::Value(enabledOperationsArray);
response.setData(value);
QByteArray id = JolieMessage::field(JolieMessage::Field::IDENTITYID, message);
QByteArray uuid = JolieMessage::field(JolieMessage::Field::UUID, message);
response = appendToken(response, id, uuid);
#ifndef NDEBUG
kDebug() << "caller = " << id.toBase64();
#endif
//hack around the not yet async service adaptor api in qtjolie
if (m_descriptorMap.contains(id + uuid)) {
#ifndef NDEBUG
kDebug() << "descriptor found, sending message";
#endif
AuthorizationManager::self()->d->server->sendReply(
m_descriptorMap.value(id + uuid), response);
} else {
#ifndef NDEBUG
kDebug() << "no valid entry in descriptormap.";
#endif
}
}
QString ServiceProvider::resourceName() const
{
return m_providerName;
}
void ServiceProvider::relay(Jolie::Server *server, int descriptor,
const Jolie::Message &message)
{
Q_UNUSED(server)
if (message.operationName() == "startConnection") {
#ifndef NDEBUG
kDebug() << "reset token";
#endif
//add the identity
Credentials identity;
QByteArray identityByteArray = JolieMessage::field(JolieMessage::Field::IDENTITY, message);
QDataStream stream(&identityByteArray, QIODevice::ReadOnly);
stream >> identity;
AuthorizationManager::self()->d->addCredentials(identity);
Jolie::Message response(message.resourcePath(), message.operationName(), message.id());
QByteArray uuid = JolieMessage::field(JolieMessage::Field::UUID, message);
response = appendToken(response, identity.id().toLatin1(), uuid);
AuthorizationManager::self()->d->server->sendReply(descriptor, response);
return;
}
if (JolieMessage::field(JolieMessage::Field::TOKEN, message).isEmpty()) {
Jolie::Message response(message.resourcePath(), message.operationName(), message.id());
response.setFault(Jolie::Fault(JolieMessage::Error::INVALIDTOKEN));
AuthorizationManager::self()->d->server->sendReply(descriptor, response);
return;
}
//m_descriptor = descriptor;
QByteArray id = JolieMessage::field(JolieMessage::Field::IDENTITYID, message);
QByteArray uuid = JolieMessage::field(JolieMessage::Field::UUID, message);
m_descriptorMap[id + uuid] = descriptor;
authorize(message, m_tokens[id + uuid]);
}
void ServiceProvider::operationCompleted(Plasma::ServiceJob *job)
{
#ifndef NDEBUG
kDebug() << "operation completed.";
#endif
if (!m_messageMap.contains(job)) {
#ifndef NDEBUG
kDebug() << "service not in map!";
#endif
return;
}
#ifndef NDEBUG
kDebug() << "found message in message map!";
#endif
Jolie::Message message = m_messageMap.take(job);
Jolie::Message response(message.resourcePath(), message.operationName(), message.id());
QVariant variantResult = job->result();
#ifndef NDEBUG
kDebug() << "got a result: " << variantResult;
#endif
QByteArray byteArrayResult;
QBuffer buffer(&byteArrayResult);
buffer.open(QIODevice::WriteOnly);
QDataStream out(&buffer);
out << variantResult;
Jolie::Value data;
data.children(JolieMessage::Field::RESULT) << Jolie::Value(byteArrayResult);
response.setData(data);
if (job->error()) {
response.setFault(Jolie::Fault(job->errorString().toLatin1()));
}
QByteArray id = JolieMessage::field(JolieMessage::Field::IDENTITYID, message);
QByteArray uuid = JolieMessage::field(JolieMessage::Field::UUID, message);
response = appendToken(response, id, uuid);
//hack around the not yet async service adaptor api in qtjolie
if (m_descriptorMap.contains(id + uuid)) {
#ifndef NDEBUG
kDebug() << "descriptor found, sending message";
#endif
AuthorizationManager::self()->d->server->sendReply(
m_descriptorMap.value(id + uuid), response);
} else {
#ifndef NDEBUG
kDebug() << "no valid entry in descriptormap.";
#endif
}
}
void ServiceProvider::ruleChanged(Plasma::AuthorizationRule *rule)
{
int i = 0;
foreach (const Jolie::Message &message, m_messagesPendingAuthorization) {
QByteArray id = JolieMessage::field(JolieMessage::Field::IDENTITYID, message);
//Credentials identity = AuthorizationManager::self()->d->getCredentials(id);
bool matches = rule->d->matches(message.resourcePath(), id);
if (matches && rule->policy() == AuthorizationRule::PinRequired &&
JolieMessage::field(JolieMessage::Field::PIN, message) != rule->pin()) {
#ifndef NDEBUG
kDebug() << "we need a pin";
#endif
authorizationFailed(message, JolieMessage::Error::REQUIREPIN);
m_messagesPendingAuthorization.removeAt(i);
return;
/**
} else if (matches && rule->policy() == AuthorizationRule::PinRequired) {
#ifndef NDEBUG
kDebug() << "AUTHORIZATION: Service is freely accessable for verified caller.";
#endif
rule->setPolicy(AuthorizationRule::Allow);
authorizationSuccess(message);
//TODO: it might be nicer to do a removeAll once Jolie::Message implements ==
m_messagesPendingAuthorization.removeAt(i);
return;
*/
} else if (matches && rule->policy() == AuthorizationRule::Allow) {
#ifndef NDEBUG
kDebug() << "AUTHORIZATION: Service is freely accessable for verified caller.";
#endif
authorizationSuccess(message);
//TODO: it might be nicer to do a removeAll once Jolie::Message implements ==
m_messagesPendingAuthorization.removeAt(i);
return;
} else if (matches && rule->policy() == AuthorizationRule::Deny) {
#ifndef NDEBUG
kDebug() << "AUTHORIZATION: Service is never accessable for verified caller.";
#endif
authorizationFailed(message, JolieMessage::Error::ACCESSDENIED);
m_messagesPendingAuthorization.removeAt(i);
return;
} else {
i++;
}
}
}
Jolie::Message ServiceProvider::appendToken(Jolie::Message message,
const QByteArray &caller,
const QByteArray &uuid)
{
m_tokens[caller + uuid] = QUuid::createUuid().toString().toLatin1();
//kDebug() << "setting token: " << m_tokens[caller + uuid].toBase64()
//<< " for caller: " << caller.toBase64()
//<< " with uuid caller: " << uuid.toBase64();
Jolie::Value data = message.data();
data.children(JolieMessage::Field::TOKEN) << Jolie::Value(m_tokens[caller + uuid]);
message.setData(data);
return message;
}
void ServiceProvider::authorize(const Jolie::Message &message, const QByteArray &validToken)
{
#ifndef NDEBUG
kDebug() << "VALIDATING MESSAGE:";
#endif
//kDebug() << JolieMessage::print(message);
//Authorization step 1: is the service accessable to all callers? In that case we can skip the
//verification of the signature
#ifndef NDEBUG
kDebug() << "STEP1";
#endif
AuthorizationRule *rule =
AuthorizationManager::self()->d->matchingRule(message.resourcePath(), Credentials());
if (rule && rule->policy() == AuthorizationRule::Allow) {
#ifndef NDEBUG
kDebug() << "AUTHORIZATION: Service is freely accessable.";
#endif
authorizationSuccess(message);
return;
} else if (rule && rule->policy() == AuthorizationRule::Deny) {
#ifndef NDEBUG
kDebug() << "AUTHORIZATION: Service is never accessable.";
#endif
authorizationFailed(message, JolieMessage::Error::ACCESSDENIED);
return;
}
//Authorization step 2: see if the token matches. If it doesn't we can't safely identify the
//caller and are finished.
#ifndef NDEBUG
kDebug() << "STEP2";
#endif
if (JolieMessage::field(JolieMessage::Field::TOKEN, message) != validToken && !validToken.isEmpty()) {
#ifndef NDEBUG
kDebug() << "AUTHORIZATION: Message token doesn't match.";
#endif
#ifndef NDEBUG
kDebug() << "expected: " << validToken.toBase64();
#endif
authorizationFailed(message, JolieMessage::Error::INVALIDTOKEN);
return;
}
QByteArray payload = JolieMessage::payload(message);
QByteArray signature = JolieMessage::field(JolieMessage::Field::SIGNATURE, message);
Credentials identity = AuthorizationManager::self()->d->getCredentials(
JolieMessage::field(JolieMessage::Field::IDENTITYID, message));
if (!identity.isValid()) {
#ifndef NDEBUG
kDebug() << "no identity";
#endif
authorizationFailed(message, JolieMessage::Error::INVALIDTOKEN);
return;
}
#ifndef NDEBUG
kDebug() << "STEP3";
#endif
//Authorization step 3: see if we have the key and can validate the signature. If we can't,
//either the public key has changed, or somebody is doing something nasty, and we're finished.
if ((!identity.isValidSignature(signature, payload))) {
#ifndef NDEBUG
kDebug() << "AUTHORIZATION: signature invalid.";
#endif
authorizationFailed(message, JolieMessage::Error::ACCESSDENIED);
return;
}
#ifndef NDEBUG
kDebug() << "STEP4";
#endif
//Authorization step 4: if we have a valid signature, see if we've got a matching rule
rule = AuthorizationManager::self()->d->matchingRule(message.resourcePath(), identity);
if (rule && rule->policy() == AuthorizationRule::PinRequired) {
#ifndef NDEBUG
kDebug() << "we expect a pin!";
#endif
QByteArray pin = JolieMessage::field(JolieMessage::Field::PIN, message);
if (rule->pin() == QString(pin)) {
authorizationSuccess(message);
rule->setPolicy(AuthorizationRule::Allow);
} else {
authorizationFailed(message, JolieMessage::Error::ACCESSDENIED);
AuthorizationManager::self()->d->rules.removeAll(rule);
delete rule;
}
} else if (rule && rule->policy() == AuthorizationRule::Allow) {
#ifndef NDEBUG
kDebug() << "AUTHORIZATION: Service is freely accessable for validated sender.";
#endif
authorizationSuccess(message);
return;
} else if (rule && rule->policy() == AuthorizationRule::Deny) {
#ifndef NDEBUG
kDebug() << "AUTHORIZATION: Service is not accessable for validated sender.";
#endif
authorizationFailed(message, JolieMessage::Error::ACCESSDENIED);
return;
} else {
//- let the shell set the rule matching this request:
#ifndef NDEBUG
kDebug() << "STEP6";
#endif
#ifndef NDEBUG
kDebug() << "leave it up to the authorization interface";
#endif
m_messagesPendingAuthorization << message;
AuthorizationRule *newRule =
new AuthorizationRule(QString(message.resourcePath()), identity.id());
connect(newRule, SIGNAL(changed(Plasma::AuthorizationRule*)), this,
SLOT(ruleChanged(Plasma::AuthorizationRule*)));
AuthorizationManager::self()->d->rules.append(newRule);
AuthorizationManager::self()->d->authorizationInterface->authorizationRequest(*newRule);
}
}
void ServiceProvider::authorizationSuccess(const Jolie::Message &message)
{
#ifndef NDEBUG
kDebug() << "message with operationName " << message.operationName() << " allowed!";
#endif
//would be lovely if this kind of stuff could be autogenerated code from xml like in dbus
//adaptors
if (message.operationName() == "getOperations") {
sendOperations(message);
} else if (message.operationName() == "getEnabledOperations") {
sendEnabledOperations(message);
} else if (message.operationName() == "startOperationCall") {
startOperationCall(message);
}
}
void ServiceProvider::authorizationFailed(const Jolie::Message &message, const QByteArray &error)
{
#ifndef NDEBUG
kDebug() << "message with operationName " << message.operationName() << " NOT allowed!";
#endif
Jolie::Message response(message.resourcePath(), message.operationName(), message.id());
response.setFault(Jolie::Fault(error));
QByteArray id = JolieMessage::field(JolieMessage::Field::IDENTITYID, message);
QByteArray uuid = JolieMessage::field(JolieMessage::Field::UUID, message);
AuthorizationManager::self()->d->server->sendReply(
m_descriptorMap.value(id + uuid), response);
return;
}
} //namespace Plasma
#include "moc_serviceprovider_p.cpp"

View File

@ -1,76 +0,0 @@
/*
* Copyright © 2009 Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2 as
* published by the Free Software Foundation
*
* 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef PLASMA_SERVICEPROVIDER_P_H
#define PLASMA_SERVICEPROVIDER_P_H
#include <QtCore/QMap>
#include <QtJolie/AbstractAdaptor>
#include <QtJolie/Message>
class QSignalMapper;
namespace Plasma
{
class AuthorizationRule;
class Service;
class ServiceJob;
class ServiceProvider : public Jolie::AbstractAdaptor
{
Q_OBJECT
public:
ServiceProvider(const QString &name, Service *service);
~ServiceProvider();
void startOperationCall(Jolie::Message message);
void sendOperations(Jolie::Message message);
void sendEnabledOperations(Jolie::Message message);
QString resourceName() const;
protected:
void relay(Jolie::Server *server, int descriptor, const Jolie::Message &message);
private Q_SLOTS:
void operationCompleted(Plasma::ServiceJob *job);
void ruleChanged(Plasma::AuthorizationRule *rule);
private:
Jolie::Message appendToken(Jolie::Message message, const QByteArray &caller,
const QByteArray &uuid);
void authorize(const Jolie::Message &message, const QByteArray &validToken);
void authorizationSuccess(const Jolie::Message &message);
void authorizationFailed(const Jolie::Message &message, const QByteArray &error);
Service *m_service;
int m_descriptor;
QString m_providerName;
QMap<ServiceJob*, Jolie::Message> m_messageMap;
QMap<QByteArray, QByteArray> m_tokens;
QMap<QByteArray, int> m_descriptorMap;
QList<Jolie::Message> m_messagesPendingAuthorization;
};
} //namespace Plasma
#endif //PLASMA_SERVICEPROVIDER_P_H

View File

@ -1,214 +0,0 @@
/*
* Copyright 2009 Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, or
* (at your option) any later version.
*
* 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "accessappletjob.h"
#include <QPushButton>
#include <qtimer.h>
#include <qtemporarydir.h>
#include <kdebug.h>
#include <kdesktopfile.h>
#include <kiconloader.h>
#include <kmessagebox.h>
#include <kzip.h>
#include "config-plasma.h"
#include "applet.h"
#include "package.h"
#include "pluginloader.h"
#include "private/applet_p.h"
#include "service.h"
#include "servicejob.h"
namespace Plasma
{
class AccessAppletJobPrivate
{
public:
AccessAppletJobPrivate(const QUrl &location, AccessAppletJob *owner)
: q(owner),
location(location),
applet(0)
{
}
void slotStart()
{
q->start();
}
void slotServiceReady(Plasma::Service *service)
{
KConfigGroup op = service->operationDescription("GetPackage");
service->startOperationCall(op);
q->connect(service, SIGNAL(finished(Plasma::ServiceJob*)),
q, SLOT(slotPackageDownloaded(Plasma::ServiceJob*)));
}
void slotPackageDownloaded(Plasma::ServiceJob *job)
{
if (job->error()) {
#ifndef NDEBUG
kDebug() << "Plasmoid Access Job triggers an error.";
#endif
q->setError(job->error());
q->setErrorText(job->errorText());
}
//TODO: there's some duplication with installPackage, but we don't want to actually install
//the fetched package. Just extract the archive somewhere in a temp directory.
if (job->result().type() == QVariant::String) {
QString pluginName = job->result().toString();
#ifndef NDEBUG
kDebug() << "Server responded with a pluginname, trying to load: " << pluginName;
#endif
applet = PluginLoader::self()->loadApplet(pluginName);
if (applet) {
applet->d->remoteLocation = location;
} else {
q->setError(-1);
q->setErrorText(i18n("The \"%1\" widget is not installed.", pluginName));
}
q->emitResult();
} else {
#ifndef NDEBUG
kDebug() << "Server responded with a plasmoid package";
#endif
//read, and extract the plasmoid package to a temporary directory
QByteArray package = job->result().toByteArray();
QDataStream stream(&package, QIODevice::ReadOnly);
KZip archive(stream.device());
if (!archive.open(QIODevice::ReadOnly)) {
kWarning() << "Could not open package file";
q->setError(-1);
q->setErrorText(i18n("Server sent an invalid plasmoid package."));
q->emitResult();
return;
}
const KArchiveDirectory *source = archive.directory();
QTemporaryDir tempDir;
tempDir.setAutoRemove(false);
QString path = tempDir.path() + '/';
source->copyTo(path);
KDesktopFile metadata(path + "/metadata.desktop");
KConfigGroup group = metadata.desktopGroup();
QString iconName = group.readEntry("Icon");
QString message = i18n("You are about to open a remote widget on your system.<br>");
message+= i18n("<table width=\"100%\">");
message+= i18n("<tr><td align=\"right\"><b>Name:</b></td><td>&nbsp; %1</td></tr>", group.readEntry("Name"));
message+= i18n("<tr><td align=\"right\"><b>Description:</b></td><td>&nbsp; %1</td></tr>", group.readEntry("Comment"));
message+= i18n("<tr><td align=\"right\"><b>Author:</b></td><td>&nbsp; %1 &lt;%2&gt;</td></tr>",
group.readEntry("X-KDE-PluginInfo-Author"),
group.readEntry("X-KDE-PluginInfo-Email"));
message+= i18n("<tr><td align=\"right\"><b>Server:</b></td><td>&nbsp; %1</td></tr>", location.host());
message+= i18n("</table>");
message+= i18n("<br><br>Are you sure you want to open this widget on your system?");
QDialog *dialog = new QDialog;
dialog->setWindowTitle(i18n("Remote Widget"));
QDialogButtonBox *buttonBox = new QDialogButtonBox;
buttonBox->setStandardButtons(QDialogButtonBox::Yes | QDialogButtonBox::No);
buttonBox->button(QDialogButtonBox::Yes)->setText(i18n("Open Widget"));
buttonBox->button(QDialogButtonBox::No)->setText(i18n("Reject Widget"));
int answer = KMessageBox::createKMessageBox(dialog, buttonBox, KDE::icon(iconName), message,
QStringList(), QString(), 0,
KMessageBox::Dangerous);
if (answer!=QDialogButtonBox::Yes) {
q->setError(-1);
q->setErrorText(i18nc("A remote widget was rejected by the user.", "User rejected"));
q->emitResult();
return;
}
applet = Applet::loadPlasmoid(path);
if (applet) {
applet->d->remoteLocation = location;
} else {
q->setError(-1);
}
q->emitResult();
}
}
void slotTimeout()
{
kWarning() << "Plasmoid access job timed out";
q->setError(-1);
q->setErrorText(i18n("Timeout"));
q->emitResult();
}
AccessAppletJob *q;
QUrl location;
Applet *applet;
};
AccessAppletJob::AccessAppletJob(const QUrl &location, QObject *parent)
: KJob(parent),
d(new AccessAppletJobPrivate(location, this))
{
QTimer::singleShot(30000, this, SLOT(slotTimeout()));
}
AccessAppletJob::~AccessAppletJob()
{
delete d;
}
Applet *AccessAppletJob::applet() const
{
return d->applet;
}
void AccessAppletJob::start()
{
#if ENABLE_REMOTE_WIDGETS
#ifndef NDEBUG
kDebug() << "fetching a plasmoid from location = " << d->location;
#endif
Service *service = Service::access(d->location);
connect(service, SIGNAL(serviceReady(Plasma::Service*)),
this, SLOT(slotServiceReady(Plasma::Service*)));
#else
kWarning() << "libplasma was compiled without support for remote services. Accessing remote applet failed because of that.";
setError(-1);
setErrorText(i18n("Your system does not provide support for the 'remote widgets' feature. Access Failed."));
emitResult();
#endif
}
} // namespace Plasma
#include "moc_accessappletjob.cpp"

View File

@ -1,80 +0,0 @@
/*
* Copyright 2009 Rob Scheepmaker <r.scheepmaker@student.utwente.nl
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, or
* (at your option) any later version.
*
* 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef PLASMA_ACCESSAPPLETJOB_H
#define PLASMA_ACCESSAPPLETJOB_H
#include <kjob.h>
#include <plasma/plasma_export.h>
class QUrl;
namespace Plasma
{
class Applet;
class AccessAppletJobPrivate;
/**
* @class AccessAppletJob plasma/accessappletjob.h <Plasma/AccessAppletJob>
*
* @short This class is used for asynchronously accessing an applet published on a remote system.
* After calling AccessManager::accessApplet, monitor this job to track when the remote applet
* is ready to be used, and to obtain the service when finished.
*/
class PLASMA_EXPORT AccessAppletJob : public KJob
{
Q_OBJECT
public:
~AccessAppletJob();
Applet *applet() const;
protected:
/**
* Default constructor
*
* @param location the location of the service
* @param parent the parent object for this service
*/
AccessAppletJob(const QUrl &location, QObject *parent = 0);
void start();
private:
AccessAppletJob();
Q_PRIVATE_SLOT(d, void slotPackageDownloaded(Plasma::ServiceJob*))
Q_PRIVATE_SLOT(d, void slotStart())
Q_PRIVATE_SLOT(d, void slotServiceReady(Plasma::Service*))
Q_PRIVATE_SLOT(d, void slotTimeout())
AccessAppletJobPrivate * const d;
friend class AccessManager;
friend class AccessManagerPrivate;
friend class AccessAppletJobPrivate;
};
} // namespace Plasma
#endif // PLASMA_ACCESSAPPLETJOB_H

View File

@ -1,275 +0,0 @@
/*
* Copyright 2009 by Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
*
* This library 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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 library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#include "accessmanager.h"
#include "private/accessmanager_p.h"
#include "authorizationmanager.h"
#include "authorizationmanager_p.h"
#include "service.h"
#include "serviceaccessjob.h"
#include "config-plasma.h"
#include <QtCore/QMap>
#include <QtCore/QTimer>
#include <dnssd/remoteservice.h>
#include <dnssd/servicebrowser.h>
#include <kdebug.h>
#include <kglobal.h>
#include <kstandarddirs.h>
#include <qurl.h>
#include <QtJolie/Message>
namespace Plasma
{
class RemoteObjectDescription::Private
{
public:
QString name;
QString description;
QString icon;
QUrl url;
};
RemoteObjectDescription::RemoteObjectDescription()
: d(new Private)
{
}
RemoteObjectDescription::RemoteObjectDescription(const RemoteObjectDescription &other)
: d(new Private(*other.d))
{
}
RemoteObjectDescription &RemoteObjectDescription::operator=(const RemoteObjectDescription &other)
{
*d = *other.d;
return *this;
}
void RemoteObjectDescription::setName(const QString &name)
{
d->name = name;
}
QString RemoteObjectDescription::name() const
{
return d->name;
}
void RemoteObjectDescription::setUrl(const QUrl &url)
{
d->url = url;
}
QUrl RemoteObjectDescription::url() const
{
return d->url;
}
void RemoteObjectDescription::setDescription(const QString &description)
{
d->description = description;
}
QString RemoteObjectDescription::description() const
{
return d->description;
}
void RemoteObjectDescription::setIcon(const QString &icon)
{
d->icon = icon;
}
QString RemoteObjectDescription::icon() const
{
return d->icon;
}
class AccessManagerSingleton
{
public:
AccessManager self;
};
Q_GLOBAL_STATIC(AccessManagerSingleton, privateAccessManagerSelf)
AccessManager *AccessManager::self()
{
return &privateAccessManagerSelf()->self;
}
AccessManager::AccessManager()
: QObject(),
d(new AccessManagerPrivate(this))
{
KGlobal::dirs()->addResourceType("trustedkeys", "config", "trustedkeys/");
}
AccessManager::~AccessManager()
{
delete d;
}
AccessAppletJob *AccessManager::accessRemoteApplet(const QUrl &location) const
{
AuthorizationManager::self()->d->prepareForServiceAccess();
QUrl resolvedLocation;
if (location.scheme() == "plasma+zeroconf") {
if (d->zeroconfServices.contains(location.host())) {
resolvedLocation = d->services[location.host()].url();
} else {
#ifndef NDEBUG
kDebug() << "There's no zeroconf service with this name.";
#endif
}
} else {
resolvedLocation = location;
}
AccessAppletJob *job = new AccessAppletJob(resolvedLocation);
connect(job, SIGNAL(finished(KJob*)), this, SLOT(slotJobFinished(KJob*)));
QTimer::singleShot(0, job, SLOT(slotStart()));
return job;
}
QList<RemoteObjectDescription> AccessManager::remoteApplets() const
{
return d->services.values();
}
QStringList AccessManager::supportedProtocols()
{
QStringList list;
list << "plasma" << "plasma+zeroconf";
return list;
}
AccessManagerPrivate::AccessManagerPrivate(AccessManager *manager)
: q(manager),
browser(new DNSSD::ServiceBrowser("_plasma._tcp"))
{
#if ENABLE_REMOTE_WIDGETS
q->connect(browser, SIGNAL(serviceAdded(DNSSD::RemoteService::Ptr)),
q, SLOT(slotAddService(DNSSD::RemoteService::Ptr)));
q->connect(browser, SIGNAL(serviceRemoved(DNSSD::RemoteService::Ptr)),
q, SLOT(slotRemoveService(DNSSD::RemoteService::Ptr)));
browser->startBrowse();
#else
kWarning() << "libplasma is compiled without support for remote widgets. not monitoring remote widgets on the network";
#endif
}
AccessManagerPrivate::~AccessManagerPrivate()
{
delete browser;
}
void AccessManagerPrivate::slotJobFinished(KJob *job)
{
emit q->finished(static_cast<AccessAppletJob*>(job));
}
void AccessManagerPrivate::slotAddService(DNSSD::RemoteService::Ptr service)
{
#ifndef NDEBUG
kDebug();
#endif
if (!service->resolve()) {
#ifndef NDEBUG
kDebug() << "Zeroconf service can't be resolved";
#endif
return;
}
if (!services.contains(service->serviceName())) {
RemoteObjectDescription metadata;
#ifndef NDEBUG
kDebug() << "textdata = " << service->textData();
#endif
#ifndef NDEBUG
kDebug() << "hostname: " << service->hostName();
#endif
QHostAddress address = DNSSD::ServiceBrowser::resolveHostName(service->hostName());
QString ip = address.toString();
#ifndef NDEBUG
kDebug() << "result for resolve = " << ip;
#endif
QUrl url(QString("plasma://%1:%2/%3").arg(ip)
.arg(service->port())
.arg(service->serviceName()));
if (service->textData().isEmpty()) {
#ifndef NDEBUG
kDebug() << "no textdata?";
#endif
metadata.setName(service->serviceName());
metadata.setUrl(url);
} else {
#ifndef NDEBUG
kDebug() << "service has got textdata";
#endif
QMap<QString, QByteArray> textData = service->textData();
metadata.setName(textData["name"]);
metadata.setDescription(textData["description"]);
metadata.setIcon(textData["icon"]);
metadata.setUrl(url);
}
#ifndef NDEBUG
kDebug() << "location = " << metadata.url();
#endif
#ifndef NDEBUG
kDebug() << "name = " << metadata.name();
#endif
#ifndef NDEBUG
kDebug() << "description = " << metadata.name();
#endif
services[service->serviceName()] = metadata;
zeroconfServices[service->serviceName()] = service;
emit q->remoteAppletAnnounced(metadata);
}
}
void AccessManagerPrivate::slotRemoveService(DNSSD::RemoteService::Ptr service)
{
#ifndef NDEBUG
kDebug();
#endif
emit q->remoteAppletUnannounced(services[service->serviceName()]);
services.remove(service->serviceName());
zeroconfServices.remove(service->serviceName());
}
} // Plasma namespace
#include "moc_accessmanager.cpp"

View File

@ -1,140 +0,0 @@
/*
* Copyright 2009 by Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
*
* This library 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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 library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#ifndef PLASMA_ACCESSMANAGER_H
#define PLASMA_ACCESSMANAGER_H
#include "accessappletjob.h"
#include "plasma_export.h"
#include <QtCore/QList>
#include <QtCore/QObject>
#include <QtCore/QString>
#include <kdebug.h>
class QString;
class QUrl;
namespace Plasma
{
class AccessManagerPrivate;
class ServiceAccessJob;
/**
* @class AccessManager plasma/accessmanager.h <Plasma/AccessManager>
*
* @short Allows access to remote Plasma::Applet classes.
*
* This manager provides a way to access an applet (either a binary or packaged one) that is hosted
* on another machine. It also provides a mechanism to discover services announced to the network
* through zeroconf.
*
* @since 4.4
*/
class PLASMA_EXPORT RemoteObjectDescription
{
public:
RemoteObjectDescription();
RemoteObjectDescription(const RemoteObjectDescription &other);
RemoteObjectDescription &operator=(const RemoteObjectDescription &other);
void setName(const QString &name);
QString name() const;
void setUrl(const QUrl &url);
QUrl url() const;
void setDescription(const QString &description);
QString description() const;
void setIcon(const QString &icon);
QString icon() const;
private:
class Private;
Private *d;
};
class PLASMA_EXPORT AccessManager : public QObject
{
Q_OBJECT
public:
/**
* Singleton pattern accessor.
*/
static AccessManager *self();
/**
* Access a native plasmoid hosted on another machine.
* @param location the location of the remote plasmoids. Exmples of valid urls:
* plasma://ip:port/resourceName
* zeroconf://PlasmoidName
* @returns a job that can be used to track when a remote plasmoid is ready for use, and to
* obtain the applet when the package is sent over.
*/
AccessAppletJob *accessRemoteApplet(const QUrl &location) const;
/**
* @returns a list of applets that are announced on the network through zeroconf. Use the
* url() function in RemoteObjectDescription to obtain an url to pass to
* accessRemoteApplet in AccessManager if you want to access one of these applets.
*/
QList<RemoteObjectDescription> remoteApplets() const;
/**
* @returns a list of supported protocols of urls that can be passed to accessRemoteApplet.
*/
static QStringList supportedProtocols();
Q_SIGNALS:
/**
* fires when an AccessAppletJob is finished.
*/
void finished(Plasma::AccessAppletJob *);
/**
* fires when a new applet is announced on the network.
*/
void remoteAppletAnnounced(const Plasma::RemoteObjectDescription &metadata);
/**
* fires when an announced applet disappears from the network.
*/
void remoteAppletUnannounced(const Plasma::RemoteObjectDescription &metadata);
private:
AccessManager();
~AccessManager();
AccessManagerPrivate * const d;
Q_PRIVATE_SLOT(d, void slotJobFinished(KJob*))
Q_PRIVATE_SLOT(d, void slotAddService(DNSSD::RemoteService::Ptr service))
Q_PRIVATE_SLOT(d, void slotRemoveService(DNSSD::RemoteService::Ptr service))
friend class AccessManagerPrivate;
friend class AccessManagerSingleton;
};
} // Plasma namespace
#endif

View File

@ -1,37 +0,0 @@
/*
* Copyright 2009 by Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
*
* This library 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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 library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#include "authorizationinterface.h"
#include "authorizationrule.h"
namespace Plasma
{
AuthorizationInterface::AuthorizationInterface()
{
}
AuthorizationInterface::~AuthorizationInterface()
{
}
} // Plasma namespace

View File

@ -1,78 +0,0 @@
/*
* Copyright 2009 by Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
*
* This library 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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 library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#ifndef PLASMA_AUTHORIZATIONINTERFACE_H
#define PLASMA_AUTHORIZATIONINTERFACE_H
#include "plasma_export.h"
#include <QtCore/QObject>
class QString;
namespace Plasma
{
class AuthorizationRule;
class ClientPinRequest;
/**
* @class AuthorizationInterface plasma/authorizationinterface.h <Plasma/AuthorizationInterface>
*
* @short Allows authorization of access to plasma services.
*
* This class is only needed when you create a plasma shell. When you implement it and register it
* with the AuthorizationManager class, it allows you to respond to incoming service access
* attempts. Whenever a message is received that does not match any of the AuthorizationRules,
* AuthorizationManager creates a new rule matching it, and passes it to the authorize function.
* Change the rule from Unspecified to something else like Allow or Deny to continue processing the
* message.
* It also allows you to outgoing access attempts that require pin pairing, to allow your shell to
* show a dialog to ask the user for a password.
*
* @since 4.4
*/
class PLASMA_EXPORT AuthorizationInterface
{
public:
virtual ~AuthorizationInterface();
/**
* implement this function to respond to an incoming request that doesn't match any rule.
* @param rule a new AuthorizationRule matching an incoming operation. Call setRules on this
* rule to allow/deny the operation.
*/
virtual void authorizationRequest(AuthorizationRule &rule) = 0;
/**
* Implement this function to respond to an outgoing connection that needs a password to
* connect successfully. As a response to this you'll probably want to show a dialog.
* @param request a ClientPinRequest where you can call setPin on to set the pin for the
* outgoing connection.
*/
virtual void clientPinRequest(ClientPinRequest &request) = 0;
protected:
AuthorizationInterface();
};
} // Plasma namespace
#endif

View File

@ -1,319 +0,0 @@
/*
* Copyright 2009 by Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
*
* This library 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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 library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#include "authorizationmanager.h"
#include "authorizationmanager_p.h"
#include "authorizationinterface.h"
#include "authorizationrule.h"
#include "authorizationrule_p.h"
#include "denyallauthorization_p.h"
#include "credentials.h"
#include "pinpairingauthorization_p.h"
#include "service.h"
#include "servicejob.h"
#include "trustedonlyauthorization_p.h"
#include "private/joliemessagehelper_p.h"
#include <QtCore/QBuffer>
#include <QtCore/QMap>
#include <QtCore/QMetaType>
#include <QtCore/QTimer>
#include <qtemporaryfile.h>
#include <QtNetwork/QHostInfo>
#include <QtJolie/Message>
#include <QtJolie/Server>
#include <kauthaction.h>
#include <kauthexecutejob.h>
#include <kconfiggroup.h>
#include <kdebug.h>
#include <kurl.h>
#include <kwallet.h>
namespace Plasma
{
class AuthorizationManagerSingleton
{
public:
AuthorizationManager self;
};
Q_GLOBAL_STATIC(AuthorizationManagerSingleton, privateAuthorizationManagerSelf)
AuthorizationManager *AuthorizationManager::self()
{
return &privateAuthorizationManagerSelf()->self;
}
AuthorizationManager::AuthorizationManager()
: QObject(),
d(new AuthorizationManagerPrivate(this))
{
qRegisterMetaTypeStreamOperators<Plasma::Credentials>("Plasma::Credentials");
}
AuthorizationManager::~AuthorizationManager()
{
delete d;
}
void AuthorizationManager::setAuthorizationPolicy(AuthorizationPolicy policy)
{
if (d->locked) {
#ifndef NDEBUG
kDebug() << "Can't change AuthorizationPolicy: interface locked.";
#endif
return;
}
if (policy == d->authorizationPolicy) {
return;
}
d->authorizationPolicy = policy;
if (d->authorizationInterface != d->customAuthorizationInterface) {
delete d->authorizationInterface;
}
switch (policy) {
case DenyAll:
d->authorizationInterface = new DenyAllAuthorization();
break;
case PinPairing:
d->authorizationInterface = new PinPairingAuthorization();
break;
case TrustedOnly:
d->authorizationInterface = new TrustedOnlyAuthorization();
break;
case Custom:
d->authorizationInterface = d->customAuthorizationInterface;
break;
}
d->locked = true;
}
void AuthorizationManager::setAuthorizationInterface(AuthorizationInterface *interface)
{
if (d->authorizationInterface) {
#ifndef NDEBUG
kDebug() << "Can't change AuthorizationInterface: interface locked.";
#endif
return;
}
delete d->customAuthorizationInterface;
d->customAuthorizationInterface = interface;
if (d->authorizationPolicy == Custom) {
d->authorizationInterface = interface;
}
}
AuthorizationManagerPrivate::AuthorizationManagerPrivate(AuthorizationManager *manager)
: q(manager),
server(0),
authorizationPolicy(AuthorizationManager::DenyAll),
authorizationInterface(new DenyAllAuthorization()),
customAuthorizationInterface(0),
rulesConfig(KSharedConfig::openConfig("/etc/plasma-remotewidgets.conf")->group("Rules")),
locked(false)
{
}
AuthorizationManagerPrivate::~AuthorizationManagerPrivate()
{
delete authorizationInterface;
delete customAuthorizationInterface;
delete server;
}
void AuthorizationManagerPrivate::prepareForServiceAccess()
{
if (myCredentials.isValid()) {
return;
}
wallet = KWallet::Wallet::openWallet("kdewallet", 0, KWallet::Wallet::Asynchronous);
q->connect(wallet, SIGNAL(walletOpened(bool)), q, SLOT(slotWalletOpened()));
QTimer::singleShot(0, q, SLOT(slotLoadRules()));
}
void AuthorizationManagerPrivate::prepareForServicePublication()
{
if (!server) {
server = new Jolie::Server(4000);
}
}
void AuthorizationManagerPrivate::saveRules()
{
#ifndef NDEBUG
kDebug() << "SAVE RULES";
#endif
QTemporaryFile tempFile;
tempFile.open();
tempFile.setAutoRemove(false);
KConfigGroup rulesGroup = KSharedConfig::openConfig(tempFile.fileName())->group("Rules");
int i = 0;
foreach (AuthorizationRule *rule, rules) {
if (rule->persistence() == AuthorizationRule::Persistent) {
#ifndef NDEBUG
kDebug() << "adding rule " << i;
#endif
rulesGroup.group(QString::number(i)).writeEntry("CredentialsID", rule->credentials().id());
rulesGroup.group(QString::number(i)).writeEntry("serviceName", rule->serviceName());
rulesGroup.group(QString::number(i)).writeEntry("Policy", (uint)rule->policy());
rulesGroup.group(QString::number(i)).writeEntry("Targets", (uint)rule->targets());
rulesGroup.group(QString::number(i)).writeEntry("Persistence", (uint)rule->persistence());
i++;
}
}
rulesGroup.sync();
tempFile.close();
#ifndef NDEBUG
kDebug() << "tempfile = " << tempFile.fileName();
#endif
KAuth::Action action("org.kde.kcontrol.kcmremotewidgets.save");
action.addArgument("source", tempFile.fileName());
action.addArgument("filename", "/etc/plasma-remotewidgets.conf");
KAuth::ExecuteJob *job = action.execute();
if (!job->exec()) {
#ifndef NDEBUG
kDebug() << "KAuth failed.... YOU SUCK!";
#endif
}
}
void AuthorizationManagerPrivate::slotWalletOpened()
{
QByteArray identity;
if (!wallet->readEntry("Credentials", identity)) {
#ifndef NDEBUG
kDebug() << "Existing identity found";
#endif
QDataStream stream(&identity, QIODevice::ReadOnly);
stream >> myCredentials;
}
if (!myCredentials.isValid()) {
#ifndef NDEBUG
kDebug() << "Creating a new identity";
#endif
myCredentials = Credentials::createCredentials(QHostInfo::localHostName());
QDataStream stream(&identity, QIODevice::WriteOnly);
stream << myCredentials;
wallet->writeEntry("Credentials", identity);
}
emit q->readyForRemoteAccess();
}
void AuthorizationManagerPrivate::slotLoadRules()
{
foreach (const QString &groupName, rulesConfig.groupList()) {
QString identityID = rulesConfig.group(groupName).readEntry("CredentialsID", "");
QString serviceName = rulesConfig.group(groupName).readEntry("serviceName", "");
uint policy = rulesConfig.group(groupName).readEntry("Policy", 0);
uint targets = rulesConfig.group(groupName).readEntry("Targets", 0);
uint persistence = rulesConfig.group(groupName).readEntry("Persistence", 0);
//Credentials storedCredentials = identities[identityID];
if (serviceName.isEmpty()) {
#ifndef NDEBUG
kDebug() << "Invalid rule";
#endif
} else {
AuthorizationRule *rule = new AuthorizationRule(serviceName, identityID);
rule->setPolicy(static_cast<AuthorizationRule::Policy>(policy));
rule->setTargets(static_cast<AuthorizationRule::Targets>(targets));
rule->setPersistence(static_cast<AuthorizationRule::Persistence>(persistence));
rules.append(rule);
}
}
}
AuthorizationRule *AuthorizationManagerPrivate::matchingRule(const QString &serviceName,
const Credentials &identity) const
{
AuthorizationRule *matchingRule = 0;
foreach (AuthorizationRule *rule, rules) {
if (rule->d->matches(serviceName, identity.id())) {
//a message can have multiple matching rules, consider priorities: the more specific the
//rule is, the higher it's priority
if (!matchingRule) {
matchingRule = rule;
} else {
if (!matchingRule->targets().testFlag(AuthorizationRule::AllServices) &&
!matchingRule->targets().testFlag(AuthorizationRule::AllUsers)) {
matchingRule = rule;
}
}
}
}
if (!matchingRule) {
#ifndef NDEBUG
kDebug() << "no matching rule";
#endif
} else {
#ifndef NDEBUG
kDebug() << "matching rule found: " << matchingRule->description();
#endif
}
return matchingRule;
}
Credentials AuthorizationManagerPrivate::getCredentials(const QString &id)
{
if (identities.contains(id)) {
return identities[id];
} else {
return Credentials();
}
}
void AuthorizationManagerPrivate::addCredentials(const Credentials &identity)
{
if (identities.contains(identity.id())) {
return;
} else if (identity.isValid()) {
#ifndef NDEBUG
kDebug() << "Adding a new identity for " << identity.id();
#endif
identities[identity.id()] = identity;
}
}
} // Plasma namespace
#include "moc_authorizationmanager.cpp"

View File

@ -1,124 +0,0 @@
/*
* Copyright 2009 by Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
*
* This library 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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 library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#ifndef PLASMA_AUTHORIZATIONMANAGER_H
#define PLASMA_AUTHORIZATIONMANAGER_H
#include "plasma_export.h"
#include <QtCore/QObject>
class QString;
namespace Plasma
{
class AuthorizationInterface;
class AuthorizationManagerPrivate;
class ServiceAccessJob;
class ServiceJob;
/**
* @class AuthorizationManager plasma/authorizationmanager.h <Plasma/AccessManager>
*
* @short Allows authorization of access to plasma services.
*
* This is the class where every message to or from another machine passes through.
* It's responsibilities are:
* - creating/keeping a credentials used for message signing.
* - verifying credentials of incoming messages.
* - testing whether or not the sender is allowed to access the requested resource by testing the
* request to a set of rules.
* - allowing the shell to respond to a remote request that doesn't match any of the rules that
* are in effect.
* Besides internal use in libplasma, the only moment you'll need to access this class is when you
* implement a plasma shell.
*
* @since 4.4
*/
class PLASMA_EXPORT AuthorizationManager : public QObject
{
Q_OBJECT
public:
enum AuthorizationPolicy {
DenyAll= 0, /** < Don't allow any incoming connections */
TrustedOnly= 1, /**< Standard PIN pairing for untrusted connections */
PinPairing= 2, /** < Only allow connections from trusted machines */
Custom= 256 /** < Specify a custom AuthorizationInterface */
};
/**
* Singleton pattern accessor.
*/
static AuthorizationManager *self();
/**
* Set a policy used for authorizing incoming connections. You can either use one of the
* included policies, Default is to deny all incoming connections. This can only be set
* once to avoid that malicious plugins can change this. This means that you should ALWAYS
* call this function in any plasma shell, even if you like to use the default DenyAll
* policy.
*/
void setAuthorizationPolicy(AuthorizationPolicy policy);
/**
* Register an implementation of AuthorizationInterface. Use this to make your shell
* handle authorization requests. This can only be set once to avoid that malicious plugins
* can change this.
*/
void setAuthorizationInterface(AuthorizationInterface *interface);
Q_SIGNALS:
/**
* fires when the AuthorizationManager is ready for accesssing remote plasmoids, meaning the
* private key has been unlocked by the user.
*/
void readyForRemoteAccess();
private:
AuthorizationManager();
~AuthorizationManager();
AuthorizationManagerPrivate *const d;
Q_PRIVATE_SLOT(d, void slotLoadRules())
Q_PRIVATE_SLOT(d, void slotWalletOpened())
friend class AccessManager;
friend class AuthorizationManagerPrivate;
friend class AuthorizationManagerSingleton;
friend class AuthorizationRule;
friend class AuthorizationRulePrivate;
friend class Applet;
friend class AppletPrivate;
friend class Credentials;
friend class DataEngine;
friend class GetSource;
friend class PackagePrivate;
friend class PlasmoidServiceJob;
friend class RemoteService;
friend class RemoteServiceJob;
friend class ServicePrivate;
friend class ServiceProvider;
};
} // Plasma namespace
#endif

View File

@ -1,93 +0,0 @@
/*
* Copyright 2009 by Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
*
* This library 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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 library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#ifndef PLASMA_AUTHORIZATIONMANAGER_P_H
#define PLASMA_AUTHORIZATIONMANAGER_P_H
#include "config-plasma.h"
#include <QtCore/QMap>
#include <QtCore/QString>
#if ENABLE_REMOTE_WIDGETS
#include <QtCrypto>
#endif
#include <kconfiggroup.h>
#include <authorizationmanager.h>
#include <credentials.h>
class QByteArray;
namespace KWallet
{
class Wallet;
} // namespace KWallet
namespace Jolie
{
class Server;
} // namespace Jolie
namespace Plasma
{
class AuthorizationInterface;
class AuthorizationRule;
class Credentials;
class AuthorizationManagerPrivate
{
public:
AuthorizationManagerPrivate(AuthorizationManager *manager);
~AuthorizationManagerPrivate();
void prepareForServiceAccess();
void prepareForServicePublication();
void slotWalletOpened();
void slotLoadRules();
AuthorizationRule *matchingRule(const QString &serviceName, const Credentials &key) const;
Credentials getCredentials(const QString &id = QString());
void addCredentials(const Credentials &identity);
void saveRules();
#if ENABLE_REMOTE_WIDGETS
QCA::Initializer initializer;
#endif
AuthorizationManager *q;
Jolie::Server *server;
AuthorizationManager::AuthorizationPolicy
authorizationPolicy;
AuthorizationInterface *authorizationInterface;
AuthorizationInterface *customAuthorizationInterface;
KWallet::Wallet *wallet;
Credentials myCredentials;
QMap<QString, Credentials> identities;
QList<AuthorizationRule*> rules;
KConfigGroup identitiesConfig;
KConfigGroup rulesConfig;
bool locked;
};
}
#endif // PLASMA_AUTHORIZATIONMANAGER_P_H

View File

@ -1,172 +0,0 @@
/*
* Copyright 2009 by Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
*
* This library 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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 library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#include "authorizationrule.h"
#include "authorizationmanager.h"
#include "authorizationmanager_p.h"
#include "authorizationrule_p.h"
#include "credentials.h"
#include <QtCore/QObject>
#include <QtCore/QTimer>
#include <kurl.h>
#include <klocalizedstring.h>
namespace Plasma
{
AuthorizationRulePrivate::AuthorizationRulePrivate(const QString &serviceName, const QString &credentialID,
AuthorizationRule *rule)
: q(rule),
serviceName(serviceName),
credentialID(credentialID),
policy(AuthorizationRule::Deny),
targets(AuthorizationRule::Default),
persistence(AuthorizationRule::Transient)
{
}
AuthorizationRulePrivate::~AuthorizationRulePrivate()
{
}
bool AuthorizationRulePrivate::matches(const QString &name, const QString &id) const
{
if (serviceName == name && (credentialID == id)) {
return true;
}
if (targets.testFlag(AuthorizationRule::AllUsers) && (serviceName == name)) {
return true;
}
if (targets.testFlag(AuthorizationRule::AllServices) && (credentialID == id)) {
return true;
}
return false;
}
void AuthorizationRulePrivate::scheduleChangedSignal()
{
QTimer::singleShot(0, q, SLOT(fireChangedSignal()));
}
void AuthorizationRulePrivate::fireChangedSignal()
{
if ((persistence == AuthorizationRule::Persistent) &&
(policy != AuthorizationRule::PinRequired)) {
AuthorizationManager::self()->d->saveRules();
}
emit q->changed(q);
}
AuthorizationRule::AuthorizationRule(const QString &serviceName, const QString &credentialID)
: QObject(AuthorizationManager::self()),
d(new AuthorizationRulePrivate(serviceName, credentialID, this))
{
}
AuthorizationRule::~AuthorizationRule()
{
delete d;
}
QString AuthorizationRule::description() const
{
//i18n megafest :p
if (d->targets.testFlag(AllUsers) && d->policy == Allow) {
return i18n("Allow everybody access to %1.", d->serviceName);
} else if (d->targets.testFlag(AllUsers) && d->policy == Deny) {
return i18n("Deny everybody access to %1", d->serviceName);
} else if (d->targets.testFlag(AllServices) && d->policy == Allow) {
return i18n("Allow %1 access to all services.", credentials().name());
} else if (d->targets.testFlag(AllServices) && d->policy == Deny) {
return i18n("Deny %1 access to all services.", credentials().name());
} else if (d->policy == Allow) {
return i18n("Allow access to %1, by %2.", d->serviceName, credentials().name());
} else if (d->policy == Deny) {
return i18n("Deny access to %1, by %2.", d->serviceName, credentials().name());
} else {
return i18n("Allow access to %1, by %2?", d->serviceName, credentials().name());
}
}
void AuthorizationRule::setPolicy(Policy policy)
{
d->policy = policy;
d->scheduleChangedSignal();
}
AuthorizationRule::Policy AuthorizationRule::policy()
{
return d->policy;
}
void AuthorizationRule::setTargets(Targets targets)
{
d->targets = targets;
d->scheduleChangedSignal();
}
AuthorizationRule::Targets AuthorizationRule::targets()
{
return d->targets;
}
void AuthorizationRule::setPersistence(Persistence persistence)
{
d->persistence = persistence;
d->scheduleChangedSignal();
}
AuthorizationRule::Persistence AuthorizationRule::persistence()
{
return d->persistence;
}
void AuthorizationRule::setPin(const QString &pin)
{
d->pin = pin;
d->scheduleChangedSignal();
}
QString AuthorizationRule::pin() const
{
return d->pin;
}
Credentials AuthorizationRule::credentials() const
{
return AuthorizationManager::self()->d->getCredentials(d->credentialID);
}
QString AuthorizationRule::serviceName() const
{
return d->serviceName;
}
} // Plasma namespace
#include "moc_authorizationrule.cpp"

View File

@ -1,170 +0,0 @@
/*
* Copyright 2009 by Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
*
* This library 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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 library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#ifndef PLASMA_AUTHORIZATIONRULE_H
#define PLASMA_AUTHORIZATIONRULE_H
#include "plasma_export.h"
#include <QtCore/QObject>
class QString;
namespace QCA
{
class PublicKey;
}
namespace Plasma
{
class AuthorizationManager;
class AuthorizationRulePrivate;
class Credentials;
/**
* @class AuthorizationRule plasma/authorizationrule.h <Plasma/AuthorizationRule>
*
* @short Defines a rule indicating whether or not a certain service can be accessed by a certain
* machine.
*
* Rules allow you to have control over which computers are allowed to access which
* services. Every time a message get's in, AuthorizationManager validates it's sender, and then
* checks it's list of rules for rules matching the sender and/or the service. If no rules match,
* or all matching rules have the value Unspecified, AuthorizationManager will create a new rule
* for this message, and invoke authorize on your shells implementation of AuthorizationInterface.
* Here, you can change that rule to either allow or deny that request.
* This class can be used to specify different types of rules:
* - Rules matching only a user
* - Rules matching only a service
* - Rules matching both a service, and a user.
* A more specific rule always takes precedence over a more global rule: so if for example you have
* a rule for "myAwesomeService" specifying Deny, and a rule for "myAwesomeService" in combination
* with "130.42.120.146" as caller specifying Allow, only 130.42.120.146 can access
* myAwesomeService.
* By setting the PinRequired flag in setRules in an AuthorizationInterface implementation, you
* trigger Pin pairing (user will be asked to enter the same password on both machines).
*
* @since 4.4?
*/
class PLASMA_EXPORT AuthorizationRule : public QObject
{
Q_OBJECT
public:
~AuthorizationRule();
enum Policy {
Deny = 0, /**< access for messages matching this rule is denied. */
Allow = 1, /**< access for messages matching this rule is allowed. */
PinRequired = 2 /**< specify that the user will need to enter a pin at both sides */
};
enum Persistence {
Transient = 0, /**< specify that this rule is just valid for this session. */
Persistent = 1 /**< specify that this rule will be saved between sessions. */
};
enum Target {
Default = 0,
AllUsers = 1, /**< specify that this rule is valid for all users */
AllServices = 2 /**< specify that this rule is valid for all services */
};
Q_DECLARE_FLAGS(Targets, Target)
/**
* @returns a friendly and i18n'd description of the current rule, useful for creating a
* GUI to allow editing rules, or asking permission for an access attempt.
*/
QString description() const;
/**
* @param rules the flags describing this rule.
*/
void setPolicy(Policy policy);
/**
* @returns the flags describing this rule.
*/
Policy policy();
/**
* @param rules the flags describing this rule.
*/
void setPersistence(Persistence persistence);
/**
* @returns the flags describing this rule.
*/
Persistence persistence();
/**
* @param rules the flags describing this rule.
*/
void setTargets(Targets targets);
/**
* @returns the flags describing this rule.
*/
Targets targets();
/**
* @param pin set pin for pin pairing. You'll need to call this bevore setting the rule.
*/
void setPin(const QString &pin);
/**
* @returns the pin for pin pairing.
*/
QString pin() const;
/**
* @returns the identity of the caller.
*/
Credentials credentials() const;
/**
* @returns the name of the service this rule applies to.
*/
QString serviceName() const;
Q_SIGNALS:
void changed(Plasma::AuthorizationRule *);
private:
AuthorizationRule();
AuthorizationRule(const QString &serviceName, const QString &identityID);
AuthorizationRulePrivate * const d;
Q_PRIVATE_SLOT(d, void fireChangedSignal())
friend class AppletPrivate;
friend class AuthorizationManager;
friend class AuthorizationManagerPrivate;
friend class AuthorizationRulePrivate;
friend class GetSource;
friend class PlasmoidServiceJob;
friend class ServiceProvider;
};
} // Plasma namespace
Q_DECLARE_OPERATORS_FOR_FLAGS(Plasma::AuthorizationRule::Targets)
#endif

View File

@ -1,49 +0,0 @@
/*
* Copyright 2009 by Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
*
* This library 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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 library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#ifndef PRIVATE_AUTHORIZATIONRULE_P_H
#define PRIVATE_AUTHORIZATIONRULE_P_H
#include "../remote/authorizationrule.h"
namespace Plasma
{
class AuthorizationRulePrivate {
public:
AuthorizationRulePrivate(const QString &serviceName, const QString &credentialID,
AuthorizationRule *rule);
~AuthorizationRulePrivate();
bool matches(const QString &serviceName, const QString &credentialID) const;
void scheduleChangedSignal();
void fireChangedSignal();
AuthorizationRule *q;
QString serviceName;
QString credentialID;
bool PINvalidated;
QString pin;
AuthorizationRule::Policy policy;
AuthorizationRule::Targets targets;
AuthorizationRule::Persistence persistence;
};
}
#endif // PRIVATE_AUTHORIZATIONRULE_P_H

View File

@ -1,79 +0,0 @@
/*
* Copyright 2009 by Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
*
* This library 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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 library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#include "clientpinrequest.h"
#include "service.h"
#include "private/remoteservice_p.h"
#include <kdebug.h>
#include <klocalizedstring.h>
namespace Plasma
{
class ClientPinRequestPrivate {
public:
ClientPinRequestPrivate(RemoteService *service)
: service(service)
{
}
~ClientPinRequestPrivate() {}
RemoteService *service;
QString pin;
};
ClientPinRequest::ClientPinRequest(RemoteService *service)
: QObject(service),
d(new ClientPinRequestPrivate(service))
{
}
ClientPinRequest::~ClientPinRequest()
{
delete d;
}
QString ClientPinRequest::description() const
{
return i18n("You have requested access to the %1 hosted at %2.", d->service->name(),
d->service->location());
}
void ClientPinRequest::setPin(const QString &pin)
{
#ifndef NDEBUG
kDebug() << "pin = " << pin;
#endif
d->pin = pin;
emit changed(this);
}
QString ClientPinRequest::pin() const
{
return d->pin;
}
} // Plasma namespace
#include "moc_clientpinrequest.cpp"

View File

@ -1,79 +0,0 @@
/*
* Copyright 2009 by Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
*
* This library 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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 library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#ifndef PLASMA_CLIENTPINREQUEST_H
#define PLASMA_CLIENTPINREQUEST_H
#include "plasma_export.h"
#include <QtCore/QObject>
class QString;
namespace Plasma
{
class ClientPinRequestPrivate;
class RemoteService;
class Service;
/**
* @class ClientPinRequest plasma/clientpinrequest.h <Plasma/ClientPinRequest>
*
* describes an outgoing connection. this is just passed to AuthorizationInterface when a remote
* widget asks to do pin pairing first, so the shell can ask the user for a pin.
*
* @since 4.4
*/
class PLASMA_EXPORT ClientPinRequest : public QObject
{
Q_OBJECT
public:
/**
* @returns nice i18n'ed description of this outgoing connection.
*/
QString description() const;
/**
* @param pin set a pin for pin pairing.
*/
void setPin(const QString &pin);
/**
* @returns the pin for pin pairing.
*/
QString pin() const;
Q_SIGNALS:
void changed(Plasma::ClientPinRequest *);
private:
ClientPinRequest();
ClientPinRequest(RemoteService *service);
~ClientPinRequest();
ClientPinRequestPrivate * const d;
friend class RemoteService;
};
} // Plasma namespace
#endif

View File

@ -1,305 +0,0 @@
/*
* Copyright © 2009 Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2 as
* published by the Free Software Foundation
*
* 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 General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "credentials.h"
#include "config-plasma.h"
#include <QCryptographicHash>
#include <QObject>
#if ENABLE_REMOTE_WIDGETS
#include <QtCrypto>
#endif
#include <kdebug.h>
#include <kstandarddirs.h>
#include "authorizationmanager.h"
#define REQUIRED_FEATURES "rsa,sha1,pkey"
namespace Plasma {
class CredentialsPrivate {
public:
CredentialsPrivate()
{
}
CredentialsPrivate(const QString &id, const QString &name,
const QString &pemKey, bool isPrivateKey)
: id(id),
name(name)
{
#if ENABLE_REMOTE_WIDGETS
if (!QCA::isSupported(REQUIRED_FEATURES)) {
kWarning() << "QCA doesn't support " << REQUIRED_FEATURES;
return;
}
if (isPrivateKey) {
privateKey = QCA::PrivateKey::fromPEM(pemKey);
publicKey = privateKey.toPublicKey();
} else {
publicKey = QCA::PublicKey::fromPEM(pemKey);
}
#endif
}
~CredentialsPrivate()
{
}
QString id;
QString name;
#if ENABLE_REMOTE_WIDGETS
QCA::PublicKey publicKey;
QCA::PrivateKey privateKey;
#endif
};
Credentials::Credentials(const QString &id, const QString &name,
const QString &key, bool isPrivateKey)
: d(new CredentialsPrivate(id, name, key, isPrivateKey))
{
}
Credentials::Credentials()
: d(new CredentialsPrivate())
{
}
Credentials::Credentials(const Credentials &other)
: d(new CredentialsPrivate())
{
*d = *other.d;
}
Credentials::~Credentials()
{
delete d;
}
Credentials &Credentials::operator=(const Credentials &other)
{
*d = *other.d;
return *this;
}
Credentials Credentials::createCredentials(const QString &name)
{
#if ENABLE_REMOTE_WIDGETS
if (!QCA::isSupported(REQUIRED_FEATURES)) {
kWarning() << "QCA doesn't support " << REQUIRED_FEATURES;
return Credentials();
}
QCA::KeyGenerator generator;
QCA::PrivateKey key = generator.createRSA(2048);
QString pemKey(key.toPublicKey().toPEM());
QString id = QCryptographicHash::hash(pemKey.toLatin1(), QCryptographicHash::Sha1);
return Credentials(id, name, key.toPEM(), true);
#else
return Credentials();
#endif
}
TrustLevel Credentials::trustLevel() const
{
/**
QString pemFile = KStandardDirs::locate("trustedkeys", id());
if (!pemFile.isEmpty()) {
QCA::PublicKey pubKey = QCA::PublicKey::fromPEMFile(pemFile);
if (pubKey == d->publicKey) {
return true;
}
}
*/
//Trust no one ;)
return UnknownTrusted;
}
bool Credentials::isValid() const
{
#if ENABLE_REMOTE_WIDGETS
if (!QCA::isSupported(REQUIRED_FEATURES)) {
kWarning() << "QCA doesn't support " << REQUIRED_FEATURES;
return false;
}
if (d->publicKey.isNull()) {
return false;
} else {
QString id = QCryptographicHash::hash(d->publicKey.toPEM().toLatin1(), QCryptographicHash::Sha1);
return (id == d->id);
}
#else
#ifndef NDEBUG
kDebug() << "libplasma is compiled without support for remote widgets. Key invalid.";
#endif
return false;
#endif
}
QString Credentials::name() const
{
return d->name;
}
QString Credentials::id() const
{
return d->id;
}
bool Credentials::isValidSignature(const QByteArray &signature, const QByteArray &payload)
{
#if ENABLE_REMOTE_WIDGETS
if (!QCA::isSupported(REQUIRED_FEATURES)) {
kWarning() << "QCA doesn't support " << REQUIRED_FEATURES;
return false;
}
if (d->publicKey.canVerify()) {
if (!isValid()) {
#ifndef NDEBUG
kDebug() << "Key is null?";
#endif
}
QCA::PublicKey publicKey = QCA::PublicKey::fromPEM(d->publicKey.toPEM());
publicKey.startVerify( QCA::EMSA3_MD5 );
publicKey.update(payload);
return ( publicKey.validSignature( signature ) );
} else {
#ifndef NDEBUG
kDebug() << "Can't verify?";
#endif
return false;
}
#else
return false;
#endif
}
bool Credentials::canSign() const
{
#if ENABLE_REMOTE_WIDGETS
if (!QCA::isSupported(REQUIRED_FEATURES)) {
kWarning() << "QCA doesn't support " << REQUIRED_FEATURES;
return false;
}
return d->privateKey.canSign();
#else
return false;
#endif
}
QByteArray Credentials::signMessage(const QByteArray &message)
{
#if ENABLE_REMOTE_WIDGETS
if(!QCA::isSupported(REQUIRED_FEATURES)) {
#ifndef NDEBUG
kDebug() << "RSA not supported";
#endif
return QByteArray();
} else if (canSign()) {
//QCA::PrivateKey privateKey = QCA::PrivateKey::fromPEM(d->privateKey.toPEM());
d->privateKey.startSign( QCA::EMSA3_MD5 );
d->privateKey.update( message );
QByteArray signature = d->privateKey.signature();
return signature;
} else {
return QByteArray();
}
#else
return QByteArray();
#endif
}
Credentials Credentials::toPublicCredentials() const
{
#if ENABLE_REMOTE_WIDGETS
Credentials result(*this);
result.d->privateKey = QCA::PrivateKey();
return result;
#else
return Credentials();
#endif
}
QDataStream &operator<<(QDataStream &out, const Credentials &myObj)
{
#if ENABLE_REMOTE_WIDGETS
if (!QCA::isSupported(REQUIRED_FEATURES)) {
kWarning() << "QCA doesn't support " << REQUIRED_FEATURES;
return out;
}
QString privateKeyPem;
QString publicKeyPem;
if (!myObj.d->privateKey.isNull()) {
privateKeyPem = myObj.d->privateKey.toPEM();
}
if (!myObj.d->publicKey.isNull()) {
publicKeyPem = myObj.d->publicKey.toPEM();
}
out << 1 << myObj.d->id << myObj.d->name << privateKeyPem << publicKeyPem;
#endif
return out;
}
QDataStream &operator>>(QDataStream &in, Credentials &myObj)
{
#if ENABLE_REMOTE_WIDGETS
if (!QCA::isSupported(REQUIRED_FEATURES)) {
kWarning() << "QCA doesn't support " << REQUIRED_FEATURES;
return in;
}
QString privateKeyString;
QString publicKeyString;
uint version;
in >> version >> myObj.d->id >> myObj.d->name >> privateKeyString >> publicKeyString;
QCA::ConvertResult conversionResult;
if (!privateKeyString.isEmpty()) {
myObj.d->privateKey = QCA::PrivateKey::fromPEM(privateKeyString,
QByteArray(), &conversionResult);
}
if (!publicKeyString.isEmpty()) {
myObj.d->publicKey = QCA::PublicKey::fromPEM(publicKeyString, &conversionResult);
}
if (conversionResult != QCA::ConvertGood) {
#ifndef NDEBUG
kDebug() << "Unsuccessfull conversion of key?";
#endif
}
#endif
return in;
}
}

Some files were not shown because too many files have changed in this diff Show More