Raising exceptions via throwError() looses the original source code location information. Fixing that by explicitly passing that information as additional parameter, created with the preprocessor macro SE_HERE. Several files included the complex SyncContext.h only because needed throwError(). A better place for the revised implementation is the Exception class which used to be in util.h, now Exception.h. Simplifying the include statements exposed indirect include dependencies and removed "using namespace std" from the compilation of some source files which happened to rely on it. We want to get rid of that name space polution, so fix the code instead of adding it back.
174 lines
4.8 KiB
C++
174 lines
4.8 KiB
C++
/*
|
|
* Copyright (C) 2009 m-otion communications GmbH <knipp@m-otion.com>, waived
|
|
* Copyright (C) 2007-2009 Patrick Ohly <patrick.ohly@gmx.de>
|
|
* Copyright (C) 2009 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 "config.h"
|
|
|
|
#ifdef ENABLE_XMLRPC
|
|
|
|
#include "XMLRPCSyncSource.h"
|
|
|
|
#include <boost/algorithm/string/split.hpp>
|
|
#include <boost/algorithm/string/classification.hpp>
|
|
|
|
#include <syncevo/declarations.h>
|
|
SE_BEGIN_CXX
|
|
|
|
XMLRPCSyncSource::XMLRPCSyncSource(const SyncSourceParams ¶ms,
|
|
const string &dataformat) :
|
|
TrackingSyncSource(params)
|
|
{
|
|
if (dataformat.empty()) {
|
|
throwError(SE_HERE, "a data format must be specified");
|
|
}
|
|
size_t sep = dataformat.find(':');
|
|
if (sep == dataformat.npos) {
|
|
throwError(SE_HERE, string("data format not specified as <mime type>:<mime version>: " + dataformat));
|
|
}
|
|
m_mimeType.assign(dataformat, 0, sep);
|
|
m_mimeVersion = dataformat.substr(sep + 1);
|
|
m_supportedTypes = dataformat;
|
|
|
|
string const dbid = getDatabaseID();
|
|
boost::split(m_splitDatabase, dbid, boost::is_from_range('|', '|'));
|
|
m_serverUrl = m_splitDatabase[0];
|
|
}
|
|
|
|
std::string XMLRPCSyncSource::getMimeType() const
|
|
{
|
|
return m_mimeType.c_str();
|
|
}
|
|
|
|
std::string XMLRPCSyncSource::getMimeVersion() const
|
|
{
|
|
return m_mimeVersion.c_str();
|
|
}
|
|
|
|
void XMLRPCSyncSource::open()
|
|
{
|
|
}
|
|
|
|
bool XMLRPCSyncSource::isEmpty()
|
|
{
|
|
// TODO: provide a real implementation. Always returning false
|
|
// here disables the "allow slow sync when no local data" heuristic
|
|
// for preventSlowSync=1.
|
|
return false;
|
|
}
|
|
|
|
void XMLRPCSyncSource::close()
|
|
{
|
|
}
|
|
|
|
XMLRPCSyncSource::Databases XMLRPCSyncSource::getDatabases()
|
|
{
|
|
Databases result;
|
|
|
|
result.push_back(Database("select database via URL",
|
|
"<serverUrl>"));
|
|
return result;
|
|
}
|
|
|
|
void XMLRPCSyncSource::listAllItems(RevisionMap_t &revisions)
|
|
{
|
|
|
|
xmlrpc_c::value result;
|
|
|
|
client.call(m_serverUrl, "listAllItems", prepareParamList(), &result);
|
|
|
|
if(result.type() == xmlrpc_c::value::TYPE_STRUCT) {
|
|
xmlrpc_c::value_struct const tmp(result);
|
|
map<string, xmlrpc_c::value> const resultMap(
|
|
static_cast<map<string, xmlrpc_c::value> >(tmp));
|
|
map<string, xmlrpc_c::value>::const_iterator it;
|
|
|
|
for(it = resultMap.begin(); it != resultMap.end(); ++it)
|
|
revisions[(*it).first] = xmlrpc_c::value_string((*it).second);
|
|
|
|
}
|
|
}
|
|
|
|
void XMLRPCSyncSource::readItem(const string &uid, std::string &item, bool raw)
|
|
{
|
|
|
|
xmlrpc_c::paramList p = prepareParamList();
|
|
p.add(xmlrpc_c::value_string(uid));
|
|
xmlrpc_c::value result;
|
|
|
|
client.call(m_serverUrl, "readItem", p, &result);
|
|
|
|
item = xmlrpc_c::value_string(result);
|
|
|
|
}
|
|
|
|
TrackingSyncSource::InsertItemResult XMLRPCSyncSource::insertItem(const string &uid, const std::string &item, bool raw)
|
|
{
|
|
|
|
xmlrpc_c::paramList p = prepareParamList();
|
|
p.add(xmlrpc_c::value_string(uid));
|
|
p.add(xmlrpc_c::value_string(item));
|
|
xmlrpc_c::value result;
|
|
|
|
client.call(m_serverUrl, "insertItem", p, &result);
|
|
|
|
xmlrpc_c::value_struct const tmp(result);
|
|
map<string, xmlrpc_c::value> const resultMap(
|
|
static_cast<map<string, xmlrpc_c::value> >(tmp));
|
|
|
|
if(resultMap.size() != 1) {
|
|
throw("Return value of insertItem has wrong length.");
|
|
}
|
|
|
|
map<string, xmlrpc_c::value>::const_iterator it;
|
|
it = resultMap.begin();
|
|
|
|
return InsertItemResult((*it).first,
|
|
xmlrpc_c::value_string((*it).second),
|
|
ITEM_OKAY);
|
|
}
|
|
|
|
|
|
void XMLRPCSyncSource::removeItem(const string &uid)
|
|
{
|
|
xmlrpc_c::paramList p = prepareParamList();
|
|
p.add(xmlrpc_c::value_string(uid));
|
|
xmlrpc_c::value result;
|
|
|
|
client.call(m_serverUrl, "removeItem", p, &result);
|
|
}
|
|
|
|
xmlrpc_c::paramList XMLRPCSyncSource::prepareParamList()
|
|
{
|
|
xmlrpc_c::paramList p;
|
|
for(size_t i = 1; i < m_splitDatabase.size(); i++) {
|
|
p.add(xmlrpc_c::value_string(m_splitDatabase[i]));
|
|
}
|
|
|
|
return p;
|
|
}
|
|
|
|
SE_END_CXX
|
|
|
|
#endif /* ENABLE_XMLRPC */
|
|
|
|
#ifdef ENABLE_MODULES
|
|
# include "XMLRPCSyncSourceRegister.cpp"
|
|
#endif
|