dbus-server: Broke ReadOperations class out into its own .h file.
This commit is contained in:
parent
a0aeeecd8e
commit
ba1bf492ba
|
@ -21,6 +21,8 @@ libsyncevodbusserver_la_SOURCES = \
|
|||
info-req.h \
|
||||
info-req.cpp \
|
||||
main.cpp \
|
||||
read-operations.h \
|
||||
read-operations.cpp \
|
||||
restart.h \
|
||||
syncevo-dbus-server.h \
|
||||
syncevo-dbus-server.cpp \
|
||||
|
|
|
@ -0,0 +1,332 @@
|
|||
/*
|
||||
* Copyright (C) 2011 Intel Corporation
|
||||
*
|
||||
* 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) version 3.
|
||||
*
|
||||
* 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 Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "read-operations.h"
|
||||
#include "syncevo-dbus-server.h"
|
||||
|
||||
SE_BEGIN_CXX
|
||||
|
||||
ReadOperations::ReadOperations(const std::string &config_name, DBusServer &server) :
|
||||
m_configName(config_name), m_server(server)
|
||||
{}
|
||||
|
||||
void ReadOperations::getConfigs(bool getTemplates, std::vector<std::string> &configNames)
|
||||
{
|
||||
if (getTemplates) {
|
||||
SyncConfig::DeviceList devices;
|
||||
|
||||
// get device list from dbus server, currently only bluetooth devices
|
||||
m_server.getDeviceList(devices);
|
||||
|
||||
// also include server templates in search
|
||||
devices.push_back(SyncConfig::DeviceDescription("", "", SyncConfig::MATCH_FOR_CLIENT_MODE));
|
||||
|
||||
//clear existing templates in dbus server
|
||||
m_server.clearPeerTempls();
|
||||
|
||||
SyncConfig::TemplateList list = SyncConfig::getPeerTemplates(devices);
|
||||
std::map<std::string, int> numbers;
|
||||
BOOST_FOREACH(const boost::shared_ptr<SyncConfig::TemplateDescription> peer, list) {
|
||||
//if it is not a template for device
|
||||
if(peer->m_fingerprint.empty()) {
|
||||
configNames.push_back(peer->m_templateId);
|
||||
} else {
|
||||
string templName = "Bluetooth_";
|
||||
templName += peer->m_deviceId;
|
||||
templName += "_";
|
||||
std::map<std::string, int>::iterator it = numbers.find(peer->m_deviceId);
|
||||
if(it == numbers.end()) {
|
||||
numbers.insert(std::make_pair(peer->m_deviceId, 1));
|
||||
templName += "1";
|
||||
} else {
|
||||
it->second++;
|
||||
stringstream seq;
|
||||
seq << it->second;
|
||||
templName += seq.str();
|
||||
}
|
||||
configNames.push_back(templName);
|
||||
m_server.addPeerTempl(templName, peer);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
SyncConfig::ConfigList list = SyncConfig::getConfigs();
|
||||
BOOST_FOREACH(const SyncConfig::ConfigList::value_type &server, list) {
|
||||
configNames.push_back(server.first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boost::shared_ptr<DBusUserInterface> ReadOperations::getLocalConfig(const string &configName, bool mustExist)
|
||||
{
|
||||
string peer, context;
|
||||
SyncConfig::splitConfigString(SyncConfig::normalizeConfigString(configName),
|
||||
peer, context);
|
||||
|
||||
boost::shared_ptr<DBusUserInterface> syncConfig(new DBusUserInterface(configName));
|
||||
|
||||
/** if config was not set temporarily */
|
||||
if (!setFilters(*syncConfig)) {
|
||||
// the default configuration can always be opened for reading,
|
||||
// everything else must exist
|
||||
if ((context != "default" || peer != "") &&
|
||||
mustExist &&
|
||||
!syncConfig->exists()) {
|
||||
SE_THROW_EXCEPTION(NoSuchConfig, "No configuration '" + configName + "' found");
|
||||
}
|
||||
}
|
||||
return syncConfig;
|
||||
}
|
||||
|
||||
void ReadOperations::getConfig(bool getTemplate,
|
||||
Config_t &config)
|
||||
{
|
||||
map<string, string> localConfigs;
|
||||
boost::shared_ptr<SyncConfig> dbusConfig;
|
||||
boost::shared_ptr<DBusUserInterface> dbusUI;
|
||||
SyncConfig *syncConfig;
|
||||
string syncURL;
|
||||
/** get server template */
|
||||
if(getTemplate) {
|
||||
string peer, context;
|
||||
|
||||
boost::shared_ptr<SyncConfig::TemplateDescription> peerTemplate =
|
||||
m_server.getPeerTempl(m_configName);
|
||||
if(peerTemplate) {
|
||||
SyncConfig::splitConfigString(SyncConfig::normalizeConfigString(peerTemplate->m_templateId),
|
||||
peer, context);
|
||||
dbusConfig = SyncConfig::createPeerTemplate(peerTemplate->m_path);
|
||||
// if we have cached template information, add match information for it
|
||||
localConfigs.insert(pair<string, string>("description", peerTemplate->m_description));
|
||||
|
||||
stringstream score;
|
||||
score << peerTemplate->m_rank;
|
||||
localConfigs.insert(pair<string, string>("score", score.str()));
|
||||
// Actually this fingerprint is transferred by getConfigs, which refers to device name
|
||||
localConfigs.insert(pair<string, string>("deviceName", peerTemplate->m_fingerprint));
|
||||
// This is the fingerprint of the template
|
||||
localConfigs.insert(pair<string, string>("fingerPrint", peerTemplate->m_matchedModel));
|
||||
// This is the template name presented to UI (or device class)
|
||||
if (!peerTemplate->m_templateName.empty()) {
|
||||
localConfigs.insert(pair<string,string>("templateName", peerTemplate->m_templateName));
|
||||
}
|
||||
|
||||
// if the peer is client, then replace syncURL with bluetooth
|
||||
// MAC address
|
||||
syncURL = "obex-bt://";
|
||||
syncURL += peerTemplate->m_deviceId;
|
||||
} else {
|
||||
SyncConfig::splitConfigString(SyncConfig::normalizeConfigString(m_configName),
|
||||
peer, context);
|
||||
dbusConfig = SyncConfig::createPeerTemplate(peer);
|
||||
}
|
||||
|
||||
if(!dbusConfig.get()) {
|
||||
SE_THROW_EXCEPTION(NoSuchConfig, "No template '" + m_configName + "' found");
|
||||
}
|
||||
|
||||
// use the shared properties from the right context as filter
|
||||
// so that the returned template preserves existing properties
|
||||
boost::shared_ptr<DBusUserInterface> shared = getLocalConfig(string("@") + context, false);
|
||||
|
||||
ConfigProps props;
|
||||
shared->getProperties()->readProperties(props);
|
||||
dbusConfig->setConfigFilter(true, "", props);
|
||||
BOOST_FOREACH(std::string source, shared->getSyncSources()) {
|
||||
SyncSourceNodes nodes = shared->getSyncSourceNodes(source, "");
|
||||
props.clear();
|
||||
nodes.getProperties()->readProperties(props);
|
||||
// Special case "type" property: the value in the context
|
||||
// is not preserved. Every new peer must ensure that
|
||||
// its own value is compatible (= same backend) with
|
||||
// the other peers.
|
||||
props.erase("type");
|
||||
dbusConfig->setConfigFilter(false, source, props);
|
||||
}
|
||||
syncConfig = dbusConfig.get();
|
||||
} else {
|
||||
dbusUI = getLocalConfig(m_configName);
|
||||
//try to check password and read password from gnome keyring if possible
|
||||
ConfigPropertyRegistry& registry = SyncConfig::getRegistry();
|
||||
BOOST_FOREACH(const ConfigProperty *prop, registry) {
|
||||
prop->checkPassword(*dbusUI, m_configName, *dbusUI->getProperties());
|
||||
}
|
||||
list<string> configuredSources = dbusUI->getSyncSources();
|
||||
BOOST_FOREACH(const string &sourceName, configuredSources) {
|
||||
ConfigPropertyRegistry& registry = SyncSourceConfig::getRegistry();
|
||||
SyncSourceNodes sourceNodes = dbusUI->getSyncSourceNodes(sourceName);
|
||||
|
||||
BOOST_FOREACH(const ConfigProperty *prop, registry) {
|
||||
prop->checkPassword(*dbusUI, m_configName, *dbusUI->getProperties(),
|
||||
sourceName, sourceNodes.getProperties());
|
||||
}
|
||||
}
|
||||
syncConfig = dbusUI.get();
|
||||
}
|
||||
|
||||
/** get sync properties and their values */
|
||||
ConfigPropertyRegistry &syncRegistry = SyncConfig::getRegistry();
|
||||
BOOST_FOREACH(const ConfigProperty *prop, syncRegistry) {
|
||||
bool isDefault = false;
|
||||
string value = prop->getProperty(*syncConfig->getProperties(), &isDefault);
|
||||
if(boost::iequals(prop->getMainName(), "syncURL") && !syncURL.empty() ) {
|
||||
localConfigs.insert(pair<string, string>(prop->getMainName(), syncURL));
|
||||
} else if(!isDefault) {
|
||||
localConfigs.insert(pair<string, string>(prop->getMainName(), value));
|
||||
}
|
||||
}
|
||||
|
||||
// Set ConsumerReady for existing SyncEvolution < 1.2 configs
|
||||
// if not set explicitly,
|
||||
// because in older releases all existing configurations where
|
||||
// shown. SyncEvolution 1.2 is more strict and assumes that
|
||||
// ConsumerReady must be set explicitly. The sync-ui always has
|
||||
// set the flag for configs created or modified with it, but the
|
||||
// command line did not. Matches similar code in the Cmdline.cpp
|
||||
// migration code.
|
||||
//
|
||||
// This does not apply to templates which always have ConsumerReady
|
||||
// set explicitly (to on or off) or not set (same as off).
|
||||
if (!getTemplate &&
|
||||
syncConfig->getConfigVersion(CONFIG_LEVEL_PEER, CONFIG_CUR_VERSION) == 0 /* SyncEvolution < 1.2 */) {
|
||||
localConfigs.insert(make_pair("ConsumerReady", "1"));
|
||||
}
|
||||
|
||||
// insert 'configName' of the chosen config (m_configName is not normalized)
|
||||
localConfigs.insert(pair<string, string>("configName", syncConfig->getConfigName()));
|
||||
|
||||
config.insert(pair<string,map<string, string> >("", localConfigs));
|
||||
|
||||
/* get configurations from sources */
|
||||
list<string> sources = syncConfig->getSyncSources();
|
||||
BOOST_FOREACH(const string &name, sources) {
|
||||
localConfigs.clear();
|
||||
SyncSourceNodes sourceNodes = syncConfig->getSyncSourceNodes(name);
|
||||
ConfigPropertyRegistry &sourceRegistry = SyncSourceConfig::getRegistry();
|
||||
BOOST_FOREACH(const ConfigProperty *prop, sourceRegistry) {
|
||||
bool isDefault = false;
|
||||
string value = prop->getProperty(*sourceNodes.getProperties(), &isDefault);
|
||||
if(!isDefault) {
|
||||
localConfigs.insert(pair<string, string>(prop->getMainName(), value));
|
||||
}
|
||||
}
|
||||
config.insert(pair<string, map<string, string> >( "source/" + name, localConfigs));
|
||||
}
|
||||
}
|
||||
|
||||
void ReadOperations::getReports(uint32_t start, uint32_t count,
|
||||
Reports_t &reports)
|
||||
{
|
||||
SyncContext client(m_configName, false);
|
||||
std::vector<string> dirs;
|
||||
client.getSessions(dirs);
|
||||
|
||||
uint32_t index = 0;
|
||||
// newest report firstly
|
||||
for( int i = dirs.size() - 1; i >= 0; --i) {
|
||||
/** if start plus count is bigger than actual size, then return actual - size reports */
|
||||
if(index >= start && index - start < count) {
|
||||
const string &dir = dirs[i];
|
||||
std::map<string, string> aReport;
|
||||
// insert a 'dir' as an ID for the current report
|
||||
aReport.insert(pair<string, string>("dir", dir));
|
||||
SyncReport report;
|
||||
// peerName is also extracted from the dir
|
||||
string peerName = client.readSessionInfo(dir,report);
|
||||
boost::shared_ptr<SyncConfig> config(new SyncConfig(m_configName));
|
||||
string storedPeerName = config->getPeerName();
|
||||
//if can't find peer name, use the peer name from the log dir
|
||||
if(!storedPeerName.empty()) {
|
||||
peerName = storedPeerName;
|
||||
}
|
||||
|
||||
/** serialize report to ConfigProps and then copy them to reports */
|
||||
HashFileConfigNode node("/dev/null","",true);
|
||||
node << report;
|
||||
ConfigProps props;
|
||||
node.readProperties(props);
|
||||
|
||||
BOOST_FOREACH(const ConfigProps::value_type &entry, props) {
|
||||
aReport.insert(entry);
|
||||
}
|
||||
// a new key-value pair <"peer", [peer name]> is transferred
|
||||
aReport.insert(pair<string, string>("peer", peerName));
|
||||
reports.push_back(aReport);
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
void ReadOperations::checkSource(const std::string &sourceName)
|
||||
{
|
||||
boost::shared_ptr<SyncConfig> config(new SyncConfig(m_configName));
|
||||
setFilters(*config);
|
||||
|
||||
list<std::string> sourceNames = config->getSyncSources();
|
||||
list<std::string>::iterator it;
|
||||
for(it = sourceNames.begin(); it != sourceNames.end(); ++it) {
|
||||
if(*it == sourceName) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(it == sourceNames.end()) {
|
||||
SE_THROW_EXCEPTION(NoSuchSource, "'" + m_configName + "' has no '" + sourceName + "' source");
|
||||
}
|
||||
bool checked = false;
|
||||
try {
|
||||
// this can already throw exceptions when the config is invalid
|
||||
SyncSourceParams params(sourceName, config->getSyncSourceNodes(sourceName), config);
|
||||
auto_ptr<SyncSource> syncSource(SyncSource::createSource(params, false, config.get()));
|
||||
|
||||
if (syncSource.get()) {
|
||||
syncSource->open();
|
||||
// success!
|
||||
checked = true;
|
||||
}
|
||||
} catch (...) {
|
||||
Exception::handle();
|
||||
}
|
||||
|
||||
if (!checked) {
|
||||
SE_THROW_EXCEPTION(SourceUnusable, "The source '" + sourceName + "' is not usable");
|
||||
}
|
||||
}
|
||||
void ReadOperations::getDatabases(const string &sourceName, SourceDatabases_t &databases)
|
||||
{
|
||||
boost::shared_ptr<SyncConfig> config(new SyncConfig(m_configName));
|
||||
setFilters(*config);
|
||||
|
||||
SyncSourceParams params(sourceName, config->getSyncSourceNodes(sourceName), config);
|
||||
const SourceRegistry ®istry(SyncSource::getSourceRegistry());
|
||||
BOOST_FOREACH(const RegisterSyncSource *sourceInfo, registry) {
|
||||
SyncSource *source = sourceInfo->m_create(params);
|
||||
if (!source) {
|
||||
continue;
|
||||
} else if (source == RegisterSyncSource::InactiveSource) {
|
||||
SE_THROW_EXCEPTION(NoSuchSource, "'" + m_configName + "' backend of source '" + sourceName + "' is not supported");
|
||||
} else {
|
||||
auto_ptr<SyncSource> autoSource(source);
|
||||
databases = autoSource->getDatabases();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SE_THROW_EXCEPTION(NoSuchSource, "'" + m_configName + "' has no '" + sourceName + "' source");
|
||||
}
|
||||
|
||||
SE_END_CXX
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* Copyright (C) 2011 Intel Corporation
|
||||
*
|
||||
* 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) version 3.
|
||||
*
|
||||
* 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 Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef READ_OPERATIONS_H
|
||||
#define READ_OPERATIONS_H
|
||||
|
||||
#include "common.h"
|
||||
#include "gdbus/gdbus-cxx-bridge.h"
|
||||
|
||||
SE_BEGIN_CXX
|
||||
|
||||
class DBusUserInterface;
|
||||
class DBusServer;
|
||||
|
||||
/**
|
||||
* Implements the read-only methods in a Session and the Server.
|
||||
* Only data is the server configuration name, everything else
|
||||
* is created and destroyed inside the methods.
|
||||
*/
|
||||
class ReadOperations
|
||||
{
|
||||
public:
|
||||
const std::string m_configName;
|
||||
|
||||
DBusServer &m_server;
|
||||
|
||||
ReadOperations(const std::string &config_name, DBusServer &server);
|
||||
|
||||
/** the double dictionary used to represent configurations */
|
||||
typedef std::map< std::string, StringMap > Config_t;
|
||||
|
||||
/** the array of reports filled by getReports() */
|
||||
typedef std::vector< StringMap > Reports_t;
|
||||
|
||||
/** the array of databases used by getDatabases() */
|
||||
typedef SyncSource::Database SourceDatabase;
|
||||
typedef SyncSource::Databases SourceDatabases_t;
|
||||
|
||||
/** implementation of D-Bus GetConfigs() */
|
||||
void getConfigs(bool getTemplates, std::vector<std::string> &configNames);
|
||||
|
||||
/** implementation of D-Bus GetConfig() for m_configName as server configuration */
|
||||
void getConfig(bool getTemplate,
|
||||
Config_t &config);
|
||||
|
||||
/** implementation of D-Bus GetReports() for m_configName as server configuration */
|
||||
void getReports(uint32_t start, uint32_t count,
|
||||
Reports_t &reports);
|
||||
|
||||
/** Session.CheckSource() */
|
||||
void checkSource(const string &sourceName);
|
||||
|
||||
/** Session.GetDatabases() */
|
||||
void getDatabases(const string &sourceName, SourceDatabases_t &databases);
|
||||
|
||||
private:
|
||||
/**
|
||||
* This virtual function is used to let subclass set
|
||||
* filters to config. Only used internally.
|
||||
* Return true if filters exists and have been set.
|
||||
* Otherwise, nothing is set to config
|
||||
*/
|
||||
virtual bool setFilters(SyncConfig &config) { return false; }
|
||||
|
||||
/**
|
||||
* utility method which constructs a SyncConfig which references a local configuration (never a template)
|
||||
*
|
||||
* In general, the config must exist, except in two cases:
|
||||
* - configName = @default (considered always available)
|
||||
* - mustExist = false (used when reading a templates for a context which might not exist yet)
|
||||
*/
|
||||
boost::shared_ptr<DBusUserInterface> getLocalConfig(const std::string &configName, bool mustExist = true);
|
||||
};
|
||||
|
||||
SE_END_CXX
|
||||
|
||||
namespace GDBusCXX {
|
||||
using namespace SyncEvo;
|
||||
/**
|
||||
* dbus_traits for SourceDatabase. Put it here for
|
||||
* avoiding polluting gxx-dbus-bridge.h
|
||||
*/
|
||||
template<> struct dbus_traits<ReadOperations::SourceDatabase> :
|
||||
public dbus_struct_traits<ReadOperations::SourceDatabase,
|
||||
dbus_member<ReadOperations::SourceDatabase, std::string, &ReadOperations::SourceDatabase::m_name,
|
||||
dbus_member<ReadOperations::SourceDatabase, std::string, &ReadOperations::SourceDatabase::m_uri,
|
||||
dbus_member_single<ReadOperations::SourceDatabase, bool, &ReadOperations::SourceDatabase::m_isDefault> > > >{};
|
||||
}
|
||||
|
||||
#endif // READ_OPERATIONS_H
|
|
@ -26,315 +26,6 @@ using namespace SyncEvo;
|
|||
|
||||
SE_BEGIN_CXX
|
||||
|
||||
/***************** ReadOperations implementation ****************/
|
||||
|
||||
ReadOperations::ReadOperations(const std::string &config_name, DBusServer &server) :
|
||||
m_configName(config_name), m_server(server)
|
||||
{}
|
||||
|
||||
void ReadOperations::getConfigs(bool getTemplates, std::vector<std::string> &configNames)
|
||||
{
|
||||
if (getTemplates) {
|
||||
SyncConfig::DeviceList devices;
|
||||
|
||||
// get device list from dbus server, currently only bluetooth devices
|
||||
m_server.getDeviceList(devices);
|
||||
|
||||
// also include server templates in search
|
||||
devices.push_back(SyncConfig::DeviceDescription("", "", SyncConfig::MATCH_FOR_CLIENT_MODE));
|
||||
|
||||
//clear existing templates in dbus server
|
||||
m_server.clearPeerTempls();
|
||||
|
||||
SyncConfig::TemplateList list = SyncConfig::getPeerTemplates(devices);
|
||||
std::map<std::string, int> numbers;
|
||||
BOOST_FOREACH(const boost::shared_ptr<SyncConfig::TemplateDescription> peer, list) {
|
||||
//if it is not a template for device
|
||||
if(peer->m_fingerprint.empty()) {
|
||||
configNames.push_back(peer->m_templateId);
|
||||
} else {
|
||||
string templName = "Bluetooth_";
|
||||
templName += peer->m_deviceId;
|
||||
templName += "_";
|
||||
std::map<std::string, int>::iterator it = numbers.find(peer->m_deviceId);
|
||||
if(it == numbers.end()) {
|
||||
numbers.insert(std::make_pair(peer->m_deviceId, 1));
|
||||
templName += "1";
|
||||
} else {
|
||||
it->second++;
|
||||
stringstream seq;
|
||||
seq << it->second;
|
||||
templName += seq.str();
|
||||
}
|
||||
configNames.push_back(templName);
|
||||
m_server.addPeerTempl(templName, peer);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
SyncConfig::ConfigList list = SyncConfig::getConfigs();
|
||||
BOOST_FOREACH(const SyncConfig::ConfigList::value_type &server, list) {
|
||||
configNames.push_back(server.first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boost::shared_ptr<DBusUserInterface> ReadOperations::getLocalConfig(const string &configName, bool mustExist)
|
||||
{
|
||||
string peer, context;
|
||||
SyncConfig::splitConfigString(SyncConfig::normalizeConfigString(configName),
|
||||
peer, context);
|
||||
|
||||
boost::shared_ptr<DBusUserInterface> syncConfig(new DBusUserInterface(configName));
|
||||
|
||||
/** if config was not set temporarily */
|
||||
if (!setFilters(*syncConfig)) {
|
||||
// the default configuration can always be opened for reading,
|
||||
// everything else must exist
|
||||
if ((context != "default" || peer != "") &&
|
||||
mustExist &&
|
||||
!syncConfig->exists()) {
|
||||
SE_THROW_EXCEPTION(NoSuchConfig, "No configuration '" + configName + "' found");
|
||||
}
|
||||
}
|
||||
return syncConfig;
|
||||
}
|
||||
|
||||
void ReadOperations::getConfig(bool getTemplate,
|
||||
Config_t &config)
|
||||
{
|
||||
map<string, string> localConfigs;
|
||||
boost::shared_ptr<SyncConfig> dbusConfig;
|
||||
boost::shared_ptr<DBusUserInterface> dbusUI;
|
||||
SyncConfig *syncConfig;
|
||||
string syncURL;
|
||||
/** get server template */
|
||||
if(getTemplate) {
|
||||
string peer, context;
|
||||
|
||||
boost::shared_ptr<SyncConfig::TemplateDescription> peerTemplate =
|
||||
m_server.getPeerTempl(m_configName);
|
||||
if(peerTemplate) {
|
||||
SyncConfig::splitConfigString(SyncConfig::normalizeConfigString(peerTemplate->m_templateId),
|
||||
peer, context);
|
||||
dbusConfig = SyncConfig::createPeerTemplate(peerTemplate->m_path);
|
||||
// if we have cached template information, add match information for it
|
||||
localConfigs.insert(pair<string, string>("description", peerTemplate->m_description));
|
||||
|
||||
stringstream score;
|
||||
score << peerTemplate->m_rank;
|
||||
localConfigs.insert(pair<string, string>("score", score.str()));
|
||||
// Actually this fingerprint is transferred by getConfigs, which refers to device name
|
||||
localConfigs.insert(pair<string, string>("deviceName", peerTemplate->m_fingerprint));
|
||||
// This is the fingerprint of the template
|
||||
localConfigs.insert(pair<string, string>("fingerPrint", peerTemplate->m_matchedModel));
|
||||
// This is the template name presented to UI (or device class)
|
||||
if (!peerTemplate->m_templateName.empty()) {
|
||||
localConfigs.insert(pair<string,string>("templateName", peerTemplate->m_templateName));
|
||||
}
|
||||
|
||||
// if the peer is client, then replace syncURL with bluetooth
|
||||
// MAC address
|
||||
syncURL = "obex-bt://";
|
||||
syncURL += peerTemplate->m_deviceId;
|
||||
} else {
|
||||
SyncConfig::splitConfigString(SyncConfig::normalizeConfigString(m_configName),
|
||||
peer, context);
|
||||
dbusConfig = SyncConfig::createPeerTemplate(peer);
|
||||
}
|
||||
|
||||
if(!dbusConfig.get()) {
|
||||
SE_THROW_EXCEPTION(NoSuchConfig, "No template '" + m_configName + "' found");
|
||||
}
|
||||
|
||||
// use the shared properties from the right context as filter
|
||||
// so that the returned template preserves existing properties
|
||||
boost::shared_ptr<DBusUserInterface> shared = getLocalConfig(string("@") + context, false);
|
||||
|
||||
ConfigProps props;
|
||||
shared->getProperties()->readProperties(props);
|
||||
dbusConfig->setConfigFilter(true, "", props);
|
||||
BOOST_FOREACH(std::string source, shared->getSyncSources()) {
|
||||
SyncSourceNodes nodes = shared->getSyncSourceNodes(source, "");
|
||||
props.clear();
|
||||
nodes.getProperties()->readProperties(props);
|
||||
// Special case "type" property: the value in the context
|
||||
// is not preserved. Every new peer must ensure that
|
||||
// its own value is compatible (= same backend) with
|
||||
// the other peers.
|
||||
props.erase("type");
|
||||
dbusConfig->setConfigFilter(false, source, props);
|
||||
}
|
||||
syncConfig = dbusConfig.get();
|
||||
} else {
|
||||
dbusUI = getLocalConfig(m_configName);
|
||||
//try to check password and read password from gnome keyring if possible
|
||||
ConfigPropertyRegistry& registry = SyncConfig::getRegistry();
|
||||
BOOST_FOREACH(const ConfigProperty *prop, registry) {
|
||||
prop->checkPassword(*dbusUI, m_configName, *dbusUI->getProperties());
|
||||
}
|
||||
list<string> configuredSources = dbusUI->getSyncSources();
|
||||
BOOST_FOREACH(const string &sourceName, configuredSources) {
|
||||
ConfigPropertyRegistry& registry = SyncSourceConfig::getRegistry();
|
||||
SyncSourceNodes sourceNodes = dbusUI->getSyncSourceNodes(sourceName);
|
||||
|
||||
BOOST_FOREACH(const ConfigProperty *prop, registry) {
|
||||
prop->checkPassword(*dbusUI, m_configName, *dbusUI->getProperties(),
|
||||
sourceName, sourceNodes.getProperties());
|
||||
}
|
||||
}
|
||||
syncConfig = dbusUI.get();
|
||||
}
|
||||
|
||||
/** get sync properties and their values */
|
||||
ConfigPropertyRegistry &syncRegistry = SyncConfig::getRegistry();
|
||||
BOOST_FOREACH(const ConfigProperty *prop, syncRegistry) {
|
||||
bool isDefault = false;
|
||||
string value = prop->getProperty(*syncConfig->getProperties(), &isDefault);
|
||||
if(boost::iequals(prop->getMainName(), "syncURL") && !syncURL.empty() ) {
|
||||
localConfigs.insert(pair<string, string>(prop->getMainName(), syncURL));
|
||||
} else if(!isDefault) {
|
||||
localConfigs.insert(pair<string, string>(prop->getMainName(), value));
|
||||
}
|
||||
}
|
||||
|
||||
// Set ConsumerReady for existing SyncEvolution < 1.2 configs
|
||||
// if not set explicitly,
|
||||
// because in older releases all existing configurations where
|
||||
// shown. SyncEvolution 1.2 is more strict and assumes that
|
||||
// ConsumerReady must be set explicitly. The sync-ui always has
|
||||
// set the flag for configs created or modified with it, but the
|
||||
// command line did not. Matches similar code in the Cmdline.cpp
|
||||
// migration code.
|
||||
//
|
||||
// This does not apply to templates which always have ConsumerReady
|
||||
// set explicitly (to on or off) or not set (same as off).
|
||||
if (!getTemplate &&
|
||||
syncConfig->getConfigVersion(CONFIG_LEVEL_PEER, CONFIG_CUR_VERSION) == 0 /* SyncEvolution < 1.2 */) {
|
||||
localConfigs.insert(make_pair("ConsumerReady", "1"));
|
||||
}
|
||||
|
||||
// insert 'configName' of the chosen config (m_configName is not normalized)
|
||||
localConfigs.insert(pair<string, string>("configName", syncConfig->getConfigName()));
|
||||
|
||||
config.insert(pair<string,map<string, string> >("", localConfigs));
|
||||
|
||||
/* get configurations from sources */
|
||||
list<string> sources = syncConfig->getSyncSources();
|
||||
BOOST_FOREACH(const string &name, sources) {
|
||||
localConfigs.clear();
|
||||
SyncSourceNodes sourceNodes = syncConfig->getSyncSourceNodes(name);
|
||||
ConfigPropertyRegistry &sourceRegistry = SyncSourceConfig::getRegistry();
|
||||
BOOST_FOREACH(const ConfigProperty *prop, sourceRegistry) {
|
||||
bool isDefault = false;
|
||||
string value = prop->getProperty(*sourceNodes.getProperties(), &isDefault);
|
||||
if(!isDefault) {
|
||||
localConfigs.insert(pair<string, string>(prop->getMainName(), value));
|
||||
}
|
||||
}
|
||||
config.insert(pair<string, map<string, string> >( "source/" + name, localConfigs));
|
||||
}
|
||||
}
|
||||
|
||||
void ReadOperations::getReports(uint32_t start, uint32_t count,
|
||||
Reports_t &reports)
|
||||
{
|
||||
SyncContext client(m_configName, false);
|
||||
std::vector<string> dirs;
|
||||
client.getSessions(dirs);
|
||||
|
||||
uint32_t index = 0;
|
||||
// newest report firstly
|
||||
for( int i = dirs.size() - 1; i >= 0; --i) {
|
||||
/** if start plus count is bigger than actual size, then return actual - size reports */
|
||||
if(index >= start && index - start < count) {
|
||||
const string &dir = dirs[i];
|
||||
std::map<string, string> aReport;
|
||||
// insert a 'dir' as an ID for the current report
|
||||
aReport.insert(pair<string, string>("dir", dir));
|
||||
SyncReport report;
|
||||
// peerName is also extracted from the dir
|
||||
string peerName = client.readSessionInfo(dir,report);
|
||||
boost::shared_ptr<SyncConfig> config(new SyncConfig(m_configName));
|
||||
string storedPeerName = config->getPeerName();
|
||||
//if can't find peer name, use the peer name from the log dir
|
||||
if(!storedPeerName.empty()) {
|
||||
peerName = storedPeerName;
|
||||
}
|
||||
|
||||
/** serialize report to ConfigProps and then copy them to reports */
|
||||
HashFileConfigNode node("/dev/null","",true);
|
||||
node << report;
|
||||
ConfigProps props;
|
||||
node.readProperties(props);
|
||||
|
||||
BOOST_FOREACH(const ConfigProps::value_type &entry, props) {
|
||||
aReport.insert(entry);
|
||||
}
|
||||
// a new key-value pair <"peer", [peer name]> is transferred
|
||||
aReport.insert(pair<string, string>("peer", peerName));
|
||||
reports.push_back(aReport);
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
void ReadOperations::checkSource(const std::string &sourceName)
|
||||
{
|
||||
boost::shared_ptr<SyncConfig> config(new SyncConfig(m_configName));
|
||||
setFilters(*config);
|
||||
|
||||
list<std::string> sourceNames = config->getSyncSources();
|
||||
list<std::string>::iterator it;
|
||||
for(it = sourceNames.begin(); it != sourceNames.end(); ++it) {
|
||||
if(*it == sourceName) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(it == sourceNames.end()) {
|
||||
SE_THROW_EXCEPTION(NoSuchSource, "'" + m_configName + "' has no '" + sourceName + "' source");
|
||||
}
|
||||
bool checked = false;
|
||||
try {
|
||||
// this can already throw exceptions when the config is invalid
|
||||
SyncSourceParams params(sourceName, config->getSyncSourceNodes(sourceName), config);
|
||||
auto_ptr<SyncSource> syncSource(SyncSource::createSource(params, false, config.get()));
|
||||
|
||||
if (syncSource.get()) {
|
||||
syncSource->open();
|
||||
// success!
|
||||
checked = true;
|
||||
}
|
||||
} catch (...) {
|
||||
Exception::handle();
|
||||
}
|
||||
|
||||
if (!checked) {
|
||||
SE_THROW_EXCEPTION(SourceUnusable, "The source '" + sourceName + "' is not usable");
|
||||
}
|
||||
}
|
||||
void ReadOperations::getDatabases(const string &sourceName, SourceDatabases_t &databases)
|
||||
{
|
||||
boost::shared_ptr<SyncConfig> config(new SyncConfig(m_configName));
|
||||
setFilters(*config);
|
||||
|
||||
SyncSourceParams params(sourceName, config->getSyncSourceNodes(sourceName), config);
|
||||
const SourceRegistry ®istry(SyncSource::getSourceRegistry());
|
||||
BOOST_FOREACH(const RegisterSyncSource *sourceInfo, registry) {
|
||||
SyncSource *source = sourceInfo->m_create(params);
|
||||
if (!source) {
|
||||
continue;
|
||||
} else if (source == RegisterSyncSource::InactiveSource) {
|
||||
SE_THROW_EXCEPTION(NoSuchSource, "'" + m_configName + "' backend of source '" + sourceName + "' is not supported");
|
||||
} else {
|
||||
auto_ptr<SyncSource> autoSource(source);
|
||||
databases = autoSource->getDatabases();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SE_THROW_EXCEPTION(NoSuchSource, "'" + m_configName + "' has no '" + sourceName + "' source");
|
||||
}
|
||||
|
||||
/***************** DBusUserInterface implementation **********************/
|
||||
DBusUserInterface::DBusUserInterface(const std::string &config):
|
||||
SyncContext(config, true)
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "timeout.h"
|
||||
#include "restart.h"
|
||||
#include "client.h"
|
||||
#include "read-operations.h"
|
||||
|
||||
using namespace GDBusCXX;
|
||||
using namespace SyncEvo;
|
||||
|
@ -50,82 +51,6 @@ class DBusTransportAgent;
|
|||
class DBusUserInterface;
|
||||
class DBusServer;
|
||||
|
||||
/**
|
||||
* Implements the read-only methods in a Session and the Server.
|
||||
* Only data is the server configuration name, everything else
|
||||
* is created and destroyed inside the methods.
|
||||
*/
|
||||
class ReadOperations
|
||||
{
|
||||
public:
|
||||
const std::string m_configName;
|
||||
|
||||
DBusServer &m_server;
|
||||
|
||||
ReadOperations(const std::string &config_name, DBusServer &server);
|
||||
|
||||
/** the double dictionary used to represent configurations */
|
||||
typedef std::map< std::string, StringMap > Config_t;
|
||||
|
||||
/** the array of reports filled by getReports() */
|
||||
typedef std::vector< StringMap > Reports_t;
|
||||
|
||||
/** the array of databases used by getDatabases() */
|
||||
typedef SyncSource::Database SourceDatabase;
|
||||
typedef SyncSource::Databases SourceDatabases_t;
|
||||
|
||||
/** implementation of D-Bus GetConfigs() */
|
||||
void getConfigs(bool getTemplates, std::vector<std::string> &configNames);
|
||||
|
||||
/** implementation of D-Bus GetConfig() for m_configName as server configuration */
|
||||
void getConfig(bool getTemplate,
|
||||
Config_t &config);
|
||||
|
||||
/** implementation of D-Bus GetReports() for m_configName as server configuration */
|
||||
void getReports(uint32_t start, uint32_t count,
|
||||
Reports_t &reports);
|
||||
|
||||
/** Session.CheckSource() */
|
||||
void checkSource(const string &sourceName);
|
||||
|
||||
/** Session.GetDatabases() */
|
||||
void getDatabases(const string &sourceName, SourceDatabases_t &databases);
|
||||
|
||||
private:
|
||||
/**
|
||||
* This virtual function is used to let subclass set
|
||||
* filters to config. Only used internally.
|
||||
* Return true if filters exists and have been set.
|
||||
* Otherwise, nothing is set to config
|
||||
*/
|
||||
virtual bool setFilters(SyncConfig &config) { return false; }
|
||||
|
||||
/**
|
||||
* utility method which constructs a SyncConfig which references a local configuration (never a template)
|
||||
*
|
||||
* In general, the config must exist, except in two cases:
|
||||
* - configName = @default (considered always available)
|
||||
* - mustExist = false (used when reading a templates for a context which might not exist yet)
|
||||
*/
|
||||
boost::shared_ptr<DBusUserInterface> getLocalConfig(const std::string &configName, bool mustExist = true);
|
||||
};
|
||||
|
||||
SE_END_CXX
|
||||
namespace GDBusCXX {
|
||||
|
||||
/**
|
||||
* dbus_traits for SourceDatabase. Put it here for
|
||||
* avoiding polluting gxx-dbus-bridge.h
|
||||
*/
|
||||
template<> struct dbus_traits<ReadOperations::SourceDatabase> :
|
||||
public dbus_struct_traits<ReadOperations::SourceDatabase,
|
||||
dbus_member<ReadOperations::SourceDatabase, std::string, &ReadOperations::SourceDatabase::m_name,
|
||||
dbus_member<ReadOperations::SourceDatabase, std::string, &ReadOperations::SourceDatabase::m_uri,
|
||||
dbus_member_single<ReadOperations::SourceDatabase, bool, &ReadOperations::SourceDatabase::m_isDefault> > > >{};
|
||||
|
||||
}
|
||||
SE_BEGIN_CXX
|
||||
|
||||
class InfoReq;
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue