ActiveSync: boiler plate code with empty function bodies
Compiles inside SyncEvolution, see README. Sync session and design outlined in the ActiveSyncSource.h header file for the main class, ActiveSyncSource. activesyncd commit ID: ec8071ae67c107f32305c6d47f176210421c17c7
This commit is contained in:
parent
1f3f3bdd53
commit
6ba4b8680d
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_ACTIVESYNC
|
||||
|
||||
#include "ActiveSyncSource.h"
|
||||
|
||||
#include <syncevo/declarations.h>
|
||||
SE_BEGIN_CXX
|
||||
|
||||
void ActiveSyncSource::enableServerMode()
|
||||
{
|
||||
SyncSourceAdmin::init(m_operations, this);
|
||||
SyncSourceBlob::init(m_operations, getCacheDir());
|
||||
}
|
||||
bool ActiveSyncSource::serverModeEnabled() const
|
||||
{
|
||||
return m_operations.m_loadAdminData;
|
||||
}
|
||||
void ActiveSyncSource::open()
|
||||
{
|
||||
// TODO: extract account ID and throw error if missing
|
||||
}
|
||||
void ActiveSyncSource::close()
|
||||
{
|
||||
}
|
||||
|
||||
void ActiveSyncSource::beginSync(const std::string &lastToken, const std::string &resumeToken)
|
||||
{
|
||||
// TODO: incremental sync (non-empty token) or start from scratch
|
||||
// TODO: Test that we really get an empty token here for an unexpected slow
|
||||
// sync. If not, we'll start an incremental sync here and later the engine
|
||||
// will ask us for older, unmodified item content which we won't have.
|
||||
}
|
||||
|
||||
std::string ActiveSyncSource::endSync(bool success)
|
||||
{
|
||||
// let engine do incremental sync next time or start from scratch
|
||||
// in case of failure
|
||||
return success ? m_currentSyncKey : "";
|
||||
}
|
||||
|
||||
void ActiveSyncSource::deleteItem(const string &luid)
|
||||
{
|
||||
// TODO: send delete request
|
||||
// remove from item list
|
||||
// update key
|
||||
}
|
||||
|
||||
SyncSourceSerialize::InsertItemResult ActiveSyncSource::insertItem(const std::string &luid, const std::string &item)
|
||||
{
|
||||
SyncSourceSerialize::InsertItemResult res;
|
||||
|
||||
// distinguish between update (existing luid)
|
||||
// or creation (empty luid)
|
||||
if (luid.empty()) {
|
||||
// TODO: send item to server
|
||||
// add to item list
|
||||
} else {
|
||||
// update item on server
|
||||
}
|
||||
// update key
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void ActiveSyncSource::readItem(const std::string &luid, std::string &item)
|
||||
{
|
||||
// TODO: return straight from cache
|
||||
}
|
||||
|
||||
SE_END_CXX
|
||||
|
||||
#endif /* ENABLE_ACTIVESYNC */
|
||||
|
||||
#ifdef ENABLE_MODULES
|
||||
# include "ActiveSyncSourceRegister.cpp"
|
||||
#endif
|
|
@ -0,0 +1,222 @@
|
|||
/*
|
||||
* Copyright (C) 2007-2009 Patrick Ohly <patrick.ohly@gmx.de>
|
||||
* Copyright (C) 2011 Patrick Ohly <patrick.ohly@intel.com>
|
||||
*
|
||||
* 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 INCL_ACTIVESYNCSOURCE
|
||||
#define INCL_ACTIVESYNCSOURCE
|
||||
|
||||
#include <syncevo/SyncSource.h>
|
||||
#include <syncevo/PrefixConfigNode.h>
|
||||
#include <syncevo/SafeConfigNode.h>
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
// TODO: include header files instead
|
||||
typedef enum {
|
||||
EAS_ITEM_FOLDER=0,
|
||||
EAS_ITEM_MAIL,
|
||||
EAS_ITEM_CALENDAR, ///< iCalendar 2.0 VEVENT
|
||||
EAS_ITEM_CONTACT, ///< vCard 3.0 contact
|
||||
EAS_ITEM_TODO, ///< iCalendar 2.0 VTODO
|
||||
EAS_ITEM_JOURNAL, ///< iCalendar 2.0 VJOURNAL
|
||||
|
||||
//TODO: add all other items here
|
||||
|
||||
EAS_ITEM_LAST
|
||||
}EasItemType;
|
||||
|
||||
|
||||
#include <syncevo/declarations.h>
|
||||
SE_BEGIN_CXX
|
||||
|
||||
#ifdef ENABLE_ACTIVESYNC
|
||||
|
||||
/**
|
||||
* Synchronizes contacts, events, tasks and journals with an
|
||||
* ActiveSync server. Sub-classes provide the necessary specialization
|
||||
* for different data formats.
|
||||
*
|
||||
* Data is exchanged between ActiveSyncSource, ActiveSync library, and
|
||||
* Synthesis engine as vCard 3.0 and iCalendar 2.0 format. The
|
||||
* standard contact and calendar profile is used, with ACTIVESYNC set
|
||||
* as sub-rule. This influences how the Synthesis engine converts to
|
||||
* and from its internal format. See KDE in
|
||||
* src/syncevo/profiles/datatypes/01vcard-profile.xml for an extensive
|
||||
* example how that works.
|
||||
*
|
||||
* Each item is a single calendar item, in other words, multiple
|
||||
* VEVENTs with the same UID are treated as separate items.
|
||||
*
|
||||
* A sync session is done like this:
|
||||
* - The Synthesis sync anchor directly maps to the
|
||||
* ActiveSync sync key.
|
||||
* - In SyncSourceSession::beginSync() (inherited from TestingSyncSource),
|
||||
* the ActiveSync library is asked for changes (for a non-empty key)
|
||||
* or all items (empty key).
|
||||
* - The returned item IDs are stored in SyncSourceChanges.
|
||||
* Only the server's IDs are used. They map 1:1 with the "luid" in
|
||||
* the SyncSource API and the Synthesis engine.
|
||||
* Because a full list of all existing items is expected,
|
||||
* ActiveSyncSource maintains a list of all known items
|
||||
* in the params.m_nodes.getTrackingNode() that it gets
|
||||
* for that purpose.
|
||||
* - The returned item content is cached in a local content cache
|
||||
* and returns items from that when asked to via
|
||||
* SyncSourceSerialize.
|
||||
* - As items are added/remove/updated, the content cache, the list
|
||||
* of IDs, and the sync key are updated. The expectation is
|
||||
* that any changes made by other ActiveSync server clients
|
||||
* will be reported when asking for changes based on that updated
|
||||
* key without including changes made by our own client, even
|
||||
* when these changes happen concurrently.
|
||||
* TODO: write a test program to verify that assumption.
|
||||
* - At the end of the sync, the updated ID list is stored and
|
||||
* the updated sync key is returned to the Synthesis engine.
|
||||
* - If anything goes wrong, a fatal error is returned to the
|
||||
* Synthesis engine, which then invalidates the sync key and
|
||||
* thus forces a slow sync in the next session.
|
||||
* TODO: investigate more intelligent ways of recovering.
|
||||
* The problem will be that trying again with the original
|
||||
* sync key will return changes made by the client itself
|
||||
* as part of the incomplete sync session.
|
||||
*
|
||||
* The command line item manipulation operations
|
||||
* (--import/export/update/print-items/delete-items) always start a
|
||||
* session without a sync key and thus (with the current API) have to
|
||||
* download all items before doing anything.
|
||||
* TODO: optimize that
|
||||
*/
|
||||
class ActiveSyncSource :
|
||||
public TestingSyncSource, // == SyncSourceSession, SyncSourceChanges, SyncSourceDelete, SyncSourceSerialize
|
||||
// TODO: implement SyncSourceLogging to get nicer debug and command line output
|
||||
// virtual public SyncSourceLogging,
|
||||
virtual public SyncSourceAdmin,
|
||||
virtual public SyncSourceBlob
|
||||
{
|
||||
public:
|
||||
ActiveSyncSource(const SyncSourceParams ¶ms) :
|
||||
TestingSyncSource(params),
|
||||
// Ensure that arbitrary keys can be stored (SafeConfigNode) and
|
||||
// that we use a common prefix, so that we can use the key/value store
|
||||
// also for other keys if the need ever arises).
|
||||
m_ids(new PrefixConfigNode("item-",
|
||||
boost::shared_ptr<ConfigNode>(new SafeConfigNode(params.m_nodes.getTrackingNode()))))
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
/* partial implementation of SyncSource */
|
||||
virtual void enableServerMode();
|
||||
virtual bool serverModeEnabled() const;
|
||||
virtual Databases getDatabases() { return Databases(); } // not supported
|
||||
virtual void open();
|
||||
virtual void close();
|
||||
virtual std::string getPeerMimeType() const { return getMimeType(); }
|
||||
|
||||
/* implementation of SyncSourceSession */
|
||||
virtual void beginSync(const std::string &lastToken, const std::string &resumeToken);
|
||||
virtual std::string endSync(bool success);
|
||||
|
||||
/* implementation of SyncSourceDelete */
|
||||
virtual void deleteItem(const string &luid);
|
||||
|
||||
/* partial implementation of SyncSourceSerialize */
|
||||
virtual std::string getMimeType() const = 0;
|
||||
virtual std::string getMimeVersion() const = 0;
|
||||
virtual InsertItemResult insertItem(const std::string &luid, const std::string &item);
|
||||
virtual void readItem(const std::string &luid, std::string &item);
|
||||
|
||||
private:
|
||||
/** smart pointer holding reference to EasSyncHandler during session */
|
||||
// TODO: include headers - eptr<EasSyncHandler, GObject> m_handler;
|
||||
|
||||
/** original sync key, set when session starts */
|
||||
std::string m_startSyncKey;
|
||||
|
||||
/** current sync key, set when session starts and updated as changes are made */
|
||||
std::string m_currentSyncKey;
|
||||
|
||||
/** server-side IDs of all items, updated as changes are reported and/or are made */
|
||||
boost::shared_ptr<ConfigNode> m_ids;
|
||||
|
||||
/** cache of all items, filled at begin of session and updated as changes are made */
|
||||
std::map<std::string, std::string> m_items;
|
||||
};
|
||||
|
||||
class ActiveSyncContactSource : public ActiveSyncSource
|
||||
{
|
||||
public:
|
||||
ActiveSyncContactSource(const SyncSourceParams ¶ms) :
|
||||
ActiveSyncSource(params)
|
||||
{}
|
||||
|
||||
protected:
|
||||
/* partial implementation of SyncSourceSerialize */
|
||||
virtual std::string getMimeType() const { return "text/vcard"; }
|
||||
virtual std::string getMimeVersion() const { return "3.0"; }
|
||||
|
||||
|
||||
#if 0 // currently disabled, and thus using the same conversion as the Evolution backend
|
||||
void getSynthesisInfo(SynthesisInfo &info,
|
||||
XMLConfigFragments &fragments)
|
||||
{
|
||||
TrackingSyncSource::getSynthesisInfo(info, fragments);
|
||||
|
||||
/** enable the ActiveSync X- extensions in the Synthesis<->backend conversion */
|
||||
info.m_backendRule = "ACTIVESYNC";
|
||||
|
||||
/*
|
||||
* Disable the default VCARD_BEFOREWRITE_SCRIPT_EVOLUTION.
|
||||
* If any KDE-specific transformations via such a script
|
||||
* are needed, it can be named here and then defined by appending
|
||||
* to the fragments.
|
||||
*/
|
||||
info.m_beforeWriteScript = ""; // "$VCARD_BEFOREWRITE_SCRIPT_KDE;";
|
||||
// fragments.m_datatypes["VCARD_BEFOREWRITE_SCRIPT_KDE"] = "<macro name=\"VCARD_BEFOREWRITE_SCRIPT_KDE\"><![DATA[ ... ]]></macro>";
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* used for all iCalendar 2.0 items (events, todos, journals)
|
||||
*/
|
||||
class ActiveSyncCalendarSource : public ActiveSyncSource
|
||||
{
|
||||
EasItemType m_type;
|
||||
|
||||
public:
|
||||
ActiveSyncCalendarSource(const SyncSourceParams ¶ms, EasItemType type) :
|
||||
ActiveSyncSource(params),
|
||||
m_type(type)
|
||||
{}
|
||||
|
||||
protected:
|
||||
/* partial implementation of SyncSourceSerialize */
|
||||
virtual std::string getMimeType() const { return "text/calendar"; }
|
||||
virtual std::string getMimeVersion() const { return "2.0"; }
|
||||
};
|
||||
|
||||
#endif // ENABLE_ACTIVESYNC
|
||||
|
||||
SE_END_CXX
|
||||
#endif // INCL_ACTIVESYNCSOURCE
|
|
@ -0,0 +1,182 @@
|
|||
/*
|
||||
* Copyright (C) 2008-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 "ActiveSyncSource.h"
|
||||
|
||||
#ifdef ENABLE_UNIT_TESTS
|
||||
# include <cppunit/extensions/TestFactoryRegistry.h>
|
||||
# include <cppunit/extensions/HelperMacros.h>
|
||||
#endif
|
||||
|
||||
#include <syncevo/declarations.h>
|
||||
SE_BEGIN_CXX
|
||||
|
||||
static SyncSource *createSource(const SyncSourceParams ¶ms)
|
||||
{
|
||||
SourceType sourceType = SyncSource::getSourceType(params.m_nodes);
|
||||
bool isMe;
|
||||
|
||||
isMe = sourceType.m_backend == "ActiveSync Address Book";
|
||||
if (isMe) {
|
||||
return
|
||||
#ifdef ENABLE_ACTIVESYNC
|
||||
new ActiveSyncContactSource(params)
|
||||
#else
|
||||
RegisterSyncSource::InactiveSource
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
isMe = sourceType.m_backend == "ActiveSync Events";
|
||||
if (isMe) {
|
||||
return
|
||||
#ifdef ENABLE_ACTIVESYNC
|
||||
new ActiveSyncCalendarSource(params, EAS_ITEM_CALENDAR)
|
||||
#else
|
||||
RegisterSyncSource::InactiveSource
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
isMe = sourceType.m_backend == "ActiveSync Todos";
|
||||
if (isMe) {
|
||||
return
|
||||
#ifdef ENABLE_ACTIVESYNC
|
||||
new ActiveSyncCalendarSource(params, EAS_ITEM_TODO)
|
||||
#else
|
||||
RegisterSyncSource::InactiveSource
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
isMe = sourceType.m_backend == "ActiveSync Memos";
|
||||
if (isMe) {
|
||||
return
|
||||
#ifdef ENABLE_ACTIVESYNC
|
||||
new ActiveSyncCalendarSource(params, EAS_ITEM_JOURNAL)
|
||||
#else
|
||||
RegisterSyncSource::InactiveSource
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static RegisterSyncSource registerMe("ActiveSync",
|
||||
#ifdef ENABLE_ACTIVESYNC
|
||||
true,
|
||||
#else
|
||||
false,
|
||||
#endif
|
||||
createSource,
|
||||
"ActiveSync Address Book = eas-contacts\n"
|
||||
"ActiveSync Events = eas-events\n"
|
||||
"ActiveSync Todos = eas-todos\n"
|
||||
"ActiveSync Memos = eas-memos",
|
||||
Values() +
|
||||
(Aliases("ActiveSync Address Book") + "eas-contacts") +
|
||||
(Aliases("ActiveSync Events") + "eas-events") +
|
||||
(Aliases("ActiveSync Todos") + "eas-todos") +
|
||||
(Aliases("ActiveSync Memos") + "eas-memos"));
|
||||
|
||||
#ifdef ENABLE_ACTIVESYNC
|
||||
#ifdef ENABLE_UNIT_TESTS
|
||||
|
||||
class ActiveSyncsTest : public CppUnit::TestFixture {
|
||||
CPPUNIT_TEST_SUITE(ActiveSyncsTest);
|
||||
CPPUNIT_TEST(testInstantiate);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
protected:
|
||||
void testInstantiate() {
|
||||
boost::shared_ptr<SyncSource> source;
|
||||
source.reset(SyncSource::createTestingSource("contacts", "ActiveSync Address Book", true));
|
||||
source.reset(SyncSource::createTestingSource("events", "ActiveSync Events", true));
|
||||
source.reset(SyncSource::createTestingSource("todos", "ActiveSync Todos", true));
|
||||
source.reset(SyncSource::createTestingSource("memos", "ActiveSync Memos", true));
|
||||
}
|
||||
};
|
||||
|
||||
SYNCEVOLUTION_TEST_SUITE_REGISTRATION(ActiveSyncsTest);
|
||||
|
||||
#endif // ENABLE_UNIT_TESTS
|
||||
|
||||
#ifdef ENABLE_INTEGRATION_TESTS
|
||||
namespace {
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
static class ActiveSyncContactTest : public RegisterSyncSourceTest {
|
||||
public:
|
||||
ActiveSyncContactTest() :
|
||||
RegisterSyncSourceTest("eas_contact", // name of test => Client::Source::eas_contact"
|
||||
"eds_contact" // name of test cases: inherit from EDS, override below
|
||||
) {}
|
||||
|
||||
virtual void updateConfig(ClientTestConfig &config) const
|
||||
{
|
||||
// override default eds_contact test config
|
||||
config.type = "eas-contacts";
|
||||
// TODO: provide comprehensive set of vCard 3.0 contacts as they are understood by the ActiveSync library
|
||||
// config.testcases = "testcases/eas_contact.vcf";
|
||||
}
|
||||
} ActiveSyncContactTest;
|
||||
|
||||
static class ActiveSyncEventTest : public RegisterSyncSourceTest {
|
||||
public:
|
||||
ActiveSyncEventTest() :
|
||||
RegisterSyncSourceTest("eas_event", "eds_event")
|
||||
{}
|
||||
|
||||
virtual void updateConfig(ClientTestConfig &config) const
|
||||
{
|
||||
}
|
||||
} ActiveSyncEventTest;
|
||||
|
||||
static class ActiveSyncTodoTest : public RegisterSyncSourceTest {
|
||||
public:
|
||||
ActiveSyncTodoTest() :
|
||||
RegisterSyncSourceTest("eas_todo", "eds_todo")
|
||||
{}
|
||||
|
||||
virtual void updateConfig(ClientTestConfig &config) const
|
||||
{
|
||||
}
|
||||
} ActiveSyncTodoTest;
|
||||
|
||||
static class ActiveSyncMemoTest : public RegisterSyncSourceTest {
|
||||
public:
|
||||
ActiveSyncMemoTest() :
|
||||
RegisterSyncSourceTest("eas_memo", "eds_memo")
|
||||
{}
|
||||
|
||||
virtual void updateConfig(ClientTestConfig &config) const
|
||||
{
|
||||
}
|
||||
} ActiveSyncMemoTest;
|
||||
|
||||
}
|
||||
#endif // ENABLE_INTEGRATION_TESTS
|
||||
|
||||
#endif // ENABLE_ACTIVESYNC
|
||||
|
||||
SE_END_CXX
|
|
@ -0,0 +1,8 @@
|
|||
To compile this backend as part of SyncEvolution, ensure that this directory
|
||||
is visible at src/backends/activesync (symlink or copy), run ./autogen.sh at
|
||||
the top level, and use --enable-activesync in configure.
|
||||
|
||||
To compile as part of the activesync repo, please add a configure
|
||||
script which uses syncevolution.pc to find include files and libs. The
|
||||
Makefile.am here might already work. Set ENABLE_ACTIVESYNC in your config.h.
|
||||
|
Loading…
Reference in New Issue