3 /// Class which detects a set of available or known devices
4 /// in an opensync-able system.
8 Copyright (C) 2009-2013, Net Direct Inc. (http://www.netdirect.ca/)
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License in the COPYING file at the
20 root directory of this project for more details.
23 #ifndef __BARRY_OSCONFIG_H__
24 #define __BARRY_OSCONFIG_H__
26 #include <barry/barry.h>
34 namespace OpenSync
{ namespace Config
{
36 // Exception class for configuration load errors
37 class LoadError
: public std::exception
41 LoadError(const std::string
&msg
) : m_msg(msg
) {}
42 virtual ~LoadError() throw() {}
43 virtual const char* what() const throw() { return m_msg
.c_str(); }
46 class SaveError
: public std::exception
50 SaveError(const std::string
&msg
) : m_msg(msg
) {}
51 virtual ~SaveError() throw() {}
52 virtual const char* what() const throw() { return m_msg
.c_str(); }
55 /// Thrown when a member cannot be deleted from the group
56 class DeleteError
: public std::logic_error
59 DeleteError(const std::string
&msg
) : std::logic_error(msg
) {}
62 // Base class for all opensync plugin configurations
65 long m_member_id
; // -1 if not saved to the group yet
77 virtual long GetMemberId() const { return m_member_id
; }
78 virtual void SetMemberId(long id
) { m_member_id
= id
; }
84 virtual Plugin
* Clone() const = 0;
86 /// IsUnsupported() returns true if the config format for this
87 /// plugin has no OpenSync::Config::* class to parse / handle it.
88 virtual bool IsUnsupported() const { return true; }
89 virtual std::string
GetAppName() const = 0; // returns a GUI-friendly
90 // name for the application that this plugin
91 // is for... i.e. plugin name might
92 // be "evo2-sync" but the app name
93 // would be "Evolution"
94 /// Throws SaveError if member_id is -1
95 virtual void Save(OpenSync::API
&api
, const std::string
&group_name
) const = 0;
96 // sample implementation:
98 // api.GetConverter().Save(*this, group_name);
100 virtual std::string
GetPluginName(OpenSync::API
&api
) const = 0;
101 // sample implementation:
103 // return api.GetConverter().GetPluginName(*this);
105 virtual bool IsConfigured(OpenSync::API
&api
) const = 0;
106 // sample implementation:
108 // return api.GetConverter().IsConfigured(*this);
110 virtual pst_type
GetConfiguredSyncTypes() const { return PST_NONE
; }
111 virtual pst_type
GetSupportedSyncTypes(OpenSync::API
&api
) const = 0;
112 // sample implementation:
114 // return api.GetConverter().GetSupportedSyncTypes(*this)
115 // && GetConfiguredSyncTypes();
118 /// Support function for Group::Compare(). If plugin is the
119 /// same type as this, sametype is set to true. If sametype
120 /// is true, and the data is functionally equivalent,
121 /// equal is set to true. Returns (sametype && equal).
122 virtual bool Compare(const Plugin
&plugin
,
123 bool &sametype
, bool &equal
) const
125 sametype
= equal
= false;
126 return sametype
&& equal
;
130 class Unsupported
: public Plugin
133 // configuration settings
134 std::string m_raw_config
;
141 explicit Unsupported(Converter
*load_converter
, const Member
&member
)
143 load_converter
->Load(*this, member
);
146 const std::string
& GetRawConfig() const { return m_raw_config
; }
148 void SetRawConfig(const std::string
&c
) { m_raw_config
= c
; }
151 virtual Unsupported
* Clone() const { return new Unsupported(*this); }
152 virtual bool IsUnsupported() const { return true; }
153 virtual std::string
GetAppName() const { return AppName(); }
154 virtual void Save(OpenSync::API
&api
, const std::string
&group_name
) const
156 api
.GetConverter().Save(*this, group_name
);
158 virtual std::string
GetPluginName(OpenSync::API
&api
) const
160 return api
.GetConverter().GetPluginName(*this);
162 virtual bool IsConfigured(OpenSync::API
&api
) const
164 return api
.GetConverter().IsConfigured(*this);
166 virtual pst_type
GetSupportedSyncTypes(OpenSync::API
&api
) const
168 return api
.GetConverter().GetSupportedSyncTypes(*this) &
169 GetConfiguredSyncTypes();;
173 static std::string
AppName();
176 class Barry
: public Plugin
179 // configuration settings
182 std::string m_password
;
185 // This constructor is protected, so that only derived
186 // classes can create a configuration without a pin number.
188 : m_debug_mode(false)
193 explicit Barry(const ::Barry::Pin
&pin
);
194 explicit Barry(Converter
*load_converter
, const Member
&member
);
196 bool IsDebugMode() const { return m_debug_mode
; }
197 ::Barry::Pin
GetPin() const { return m_pin
; }
198 std::string
GetPassword() const { return m_password
; }
200 void DebugMode(bool mode
= true) { m_debug_mode
= mode
; }
201 void SetPin(const ::Barry::Pin
&pin
) { m_pin
= pin
; }
202 void SetPassword(const std::string
&pass
) { m_password
= pass
; }
205 virtual Barry
* Clone() const { return new Barry(*this); }
206 virtual bool IsUnsupported() const { return false; }
207 virtual std::string
GetAppName() const { return AppName(); }
208 virtual void Save(OpenSync::API
&api
, const std::string
&group_name
) const
210 api
.GetConverter().Save(*this, group_name
);
212 virtual std::string
GetPluginName(OpenSync::API
&api
) const
214 return api
.GetConverter().GetPluginName(*this);
216 virtual bool IsConfigured(OpenSync::API
&api
) const
218 return api
.GetConverter().IsConfigured(*this);
220 virtual pst_type
GetConfiguredSyncTypes() const
222 return m_pin
.Valid() ? PST_ALL
: PST_NONE
;
224 virtual pst_type
GetSupportedSyncTypes(OpenSync::API
&api
) const
226 return api
.GetConverter().GetSupportedSyncTypes(*this) &
227 GetConfiguredSyncTypes();
229 virtual bool Compare(const Plugin
&plugin
,
230 bool &sametype
, bool &equal
) const
232 sametype
= equal
= false;
233 const Barry
*other
= dynamic_cast<const Barry
*> (&plugin
);
237 if( m_debug_mode
== other
->m_debug_mode
&&
238 m_pin
== other
->m_pin
&&
239 m_password
== other
->m_password
)
242 return sametype
&& equal
;
246 static std::string
AppName() { return "Barry"; }
247 static std::string
PluginName(OpenSync::API
&api
)
249 return api
.GetConverter().GetPluginName(Barry());
251 static pst_type
SupportedSyncTypes(OpenSync::API
&api
)
253 return api
.GetConverter().GetSupportedSyncTypes(Barry());
257 class Evolution
: public Plugin
260 // configuration settings
261 std::string m_address_path
;
262 std::string m_calendar_path
;
263 std::string m_tasks_path
;
264 std::string m_memos_path
;
267 static void SetIfExists(std::string
&var
, const std::string
&dir
);
274 explicit Evolution(Converter
*load_converter
, const Member
&member
)
276 load_converter
->Load(*this, member
);
279 const std::string
& GetAddressPath() const { return m_address_path
; }
280 const std::string
& GetCalendarPath() const { return m_calendar_path
; }
281 const std::string
& GetTasksPath() const { return m_tasks_path
; }
282 const std::string
& GetMemosPath() const { return m_memos_path
; }
284 void SetAddressPath(const std::string
&p
) { m_address_path
= p
; }
285 void SetCalendarPath(const std::string
&p
) { m_calendar_path
= p
; }
286 void SetTasksPath(const std::string
&p
) { m_tasks_path
= p
; }
287 void SetMemosPath(const std::string
&p
) { m_memos_path
= p
; }
289 // specific operations
290 bool AutoDetect(); // throw if unable to detect??
293 virtual Evolution
* Clone() const { return new Evolution(*this); }
294 virtual bool IsUnsupported() const { return false; }
295 virtual std::string
GetAppName() const { return AppName(); }
296 virtual void Save(OpenSync::API
&api
, const std::string
&group_name
) const
298 api
.GetConverter().Save(*this, group_name
);
300 virtual std::string
GetPluginName(OpenSync::API
&api
) const
302 return api
.GetConverter().GetPluginName(*this);
304 virtual bool IsConfigured(OpenSync::API
&api
) const
306 return api
.GetConverter().IsConfigured(*this);
308 virtual pst_type
GetConfiguredSyncTypes() const
310 pst_type pst
= PST_NONE
;
311 if( m_address_path
.size() ) pst
|= PST_CONTACTS
;
312 if( m_calendar_path
.size() ) pst
|= PST_EVENTS
;
313 if( m_tasks_path
.size() ) pst
|= PST_TODOS
;
314 if( m_memos_path
.size() ) pst
|= PST_NOTES
;
317 virtual pst_type
GetSupportedSyncTypes(OpenSync::API
&api
) const
319 // supported types include what the plugin is capable of,
320 // ANDed against what has been configured
321 return api
.GetConverter().GetSupportedSyncTypes(*this) &
322 GetConfiguredSyncTypes();
324 virtual bool Compare(const Plugin
&plugin
,
325 bool &sametype
, bool &equal
) const
327 sametype
= equal
= false;
328 const Evolution
*other
= dynamic_cast<const Evolution
*> (&plugin
);
332 if( m_address_path
== other
->m_address_path
&&
333 m_calendar_path
== other
->m_calendar_path
&&
334 m_tasks_path
== other
->m_tasks_path
&&
335 m_memos_path
== other
->m_memos_path
)
338 return sametype
&& equal
;
342 static std::string
AppName() { return "Evolution"; }
343 static std::string
PluginName(OpenSync::API
&api
)
345 return api
.GetConverter().GetPluginName(Evolution());
347 static pst_type
SupportedSyncTypes(OpenSync::API
&api
)
349 return api
.GetConverter().GetSupportedSyncTypes(Evolution());
353 class Evolution3
: public Evolution
360 explicit Evolution3(Converter
*load_converter
, const Member
&member
)
362 load_converter
->Load(*this, member
);
366 virtual Evolution3
* Clone() const { return new Evolution3(*this); }
367 virtual std::string
GetAppName() const { return AppName(); }
368 virtual void Save(OpenSync::API
&api
, const std::string
&group_name
) const
370 api
.GetConverter().Save(*this, group_name
);
372 virtual std::string
GetPluginName(OpenSync::API
&api
) const
374 return api
.GetConverter().GetPluginName(*this);
376 virtual bool IsConfigured(OpenSync::API
&api
) const
378 return api
.GetConverter().IsConfigured(*this);
380 virtual pst_type
GetSupportedSyncTypes(OpenSync::API
&api
) const
382 return api
.GetConverter().GetSupportedSyncTypes(*this) &
383 GetConfiguredSyncTypes();
385 virtual bool Compare(const Plugin
&plugin
,
386 bool &sametype
, bool &equal
) const
388 sametype
= equal
= false;
389 const Evolution3
*other
= dynamic_cast<const Evolution3
*> (&plugin
);
391 // we've established that Evolution3 == Evolution3,
392 // but the actual compare can be done by the base
394 return Evolution::Compare(plugin
, sametype
, equal
);
401 static std::string
AppName() { return "Evolution 3"; }
402 static std::string
PluginName(OpenSync::API
&api
)
404 return api
.GetConverter().GetPluginName(Evolution3());
406 static pst_type
SupportedSyncTypes(OpenSync::API
&api
)
408 return api
.GetConverter().GetSupportedSyncTypes(Evolution3());
412 class Google
: public Plugin
415 // configuration settings
416 std::string m_username
;
417 std::string m_password
;
418 bool m_contacts_enabled
;
419 bool m_calendar_enabled
;
423 : m_contacts_enabled(true)
424 , m_calendar_enabled(true)
428 explicit Google(Converter
*load_converter
, const Member
&member
)
430 load_converter
->Load(*this, member
);
433 const std::string
& GetUsername() const { return m_username
; }
434 const std::string
& GetPassword() const { return m_password
; }
435 bool IsContactsEnabled() const { return m_contacts_enabled
; }
436 bool IsCalendarEnabled() const { return m_calendar_enabled
; }
438 void SetUsername(const std::string
&u
) { m_username
= u
; }
439 void SetPassword(const std::string
&p
) { m_password
= p
; }
440 bool EnableContacts(bool setting
= true)
442 bool old
= m_contacts_enabled
;
443 m_contacts_enabled
= setting
;
446 bool EnableCalendar(bool setting
= true)
448 bool old
= m_calendar_enabled
;
449 m_calendar_enabled
= setting
;
454 virtual Google
* Clone() const { return new Google(*this); }
455 virtual bool IsUnsupported() const { return false; }
456 virtual std::string
GetAppName() const { return AppName(); }
457 virtual void Save(OpenSync::API
&api
, const std::string
&group_name
) const
459 api
.GetConverter().Save(*this, group_name
);
461 virtual std::string
GetPluginName(OpenSync::API
&api
) const
463 return api
.GetConverter().GetPluginName(*this);
465 virtual bool IsConfigured(OpenSync::API
&api
) const
467 return api
.GetConverter().IsConfigured(*this);
469 virtual pst_type
GetConfiguredSyncTypes() const
471 pst_type pst
= PST_NONE
;
472 if( m_contacts_enabled
) pst
|= PST_CONTACTS
;
473 if( m_calendar_enabled
) pst
|= PST_EVENTS
;
476 virtual pst_type
GetSupportedSyncTypes(OpenSync::API
&api
) const
478 return api
.GetConverter().GetSupportedSyncTypes(*this) &
479 GetConfiguredSyncTypes();
481 virtual bool Compare(const Plugin
&plugin
,
482 bool &sametype
, bool &equal
) const
484 sametype
= equal
= false;
485 const Google
*other
= dynamic_cast<const Google
*> (&plugin
);
489 if( m_username
== other
->m_username
&&
490 m_password
== other
->m_password
&&
491 m_contacts_enabled
== other
->m_contacts_enabled
&&
492 m_calendar_enabled
== other
->m_calendar_enabled
)
495 return sametype
&& equal
;
499 static std::string
AppName() { return "Google Calendar"; }
500 static std::string
PluginName(OpenSync::API
&api
)
502 return api
.GetConverter().GetPluginName(Google());
504 static pst_type
SupportedSyncTypes(OpenSync::API
&api
)
506 return api
.GetConverter().GetSupportedSyncTypes(Google());
510 class KDEPim
: public Plugin
513 // version 0.22 has no config
520 explicit KDEPim(Converter
*load_converter
, const Member
&member
)
522 load_converter
->Load(*this, member
);
526 virtual KDEPim
* Clone() const { return new KDEPim(*this); }
527 virtual bool IsUnsupported() const { return false; }
528 virtual std::string
GetAppName() const { return AppName(); }
529 virtual void Save(OpenSync::API
&api
, const std::string
&group_name
) const
531 api
.GetConverter().Save(*this, group_name
);
533 virtual std::string
GetPluginName(OpenSync::API
&api
) const
535 return api
.GetConverter().GetPluginName(*this);
537 virtual bool IsConfigured(OpenSync::API
&api
) const
539 return api
.GetConverter().IsConfigured(*this);
541 virtual pst_type
GetConfiguredSyncTypes() const
545 virtual pst_type
GetSupportedSyncTypes(OpenSync::API
&api
) const
547 return api
.GetConverter().GetSupportedSyncTypes(*this) &
548 GetConfiguredSyncTypes();
550 virtual bool Compare(const Plugin
&plugin
,
551 bool &sametype
, bool &equal
) const
553 sametype
= equal
= false;
554 const KDEPim
*other
= dynamic_cast<const KDEPim
*> (&plugin
);
558 // no data for this config, so always equal
561 return sametype
&& equal
;
565 static std::string
AppName() { return "KDEPim / Kontact"; }
566 static std::string
PluginName(OpenSync::API
&api
)
568 return api
.GetConverter().GetPluginName(KDEPim());
570 static pst_type
SupportedSyncTypes(OpenSync::API
&api
)
572 return api
.GetConverter().GetSupportedSyncTypes(KDEPim());
579 /// This class handles the loading of all the config plugins in a
583 private std::vector
<std::tr1::shared_ptr
<OpenSync::Config::Plugin
> >
586 typedef std::tr1::shared_ptr
<OpenSync::Config::Plugin
> value_type
;
587 typedef std::tr1::shared_ptr
<Group
> group_ptr
;
588 typedef value_type plugin_ptr
;
589 typedef std::vector
<value_type
> base_type
;
590 typedef base_type::iterator iterator
;
591 typedef base_type::const_iterator const_iterator
;
594 std::string m_group_name
;
597 static void BarryCheck(OpenSync::API
&api
,
598 const std::string
&group_name
,
599 const member_list_type
&members
,
600 unsigned throw_mask
);
602 // not copyable... use Clone()
603 Group(const Group
&other
);
604 Group
& operator=(const Group
&other
);
607 // OpenSync Config Group Throw Masks
608 #define OSCG_THROW_ON_UNSUPPORTED 0x01
609 #define OSCG_THROW_ON_NO_BARRY 0x02
610 #define OSCG_THROW_ON_MULTIPLE_BARRIES 0x04
612 /// This constructor loads an existing Group from the
613 /// given OpenSync api resource, filling the vector
614 /// array with the required plugin config classes.
616 /// If desired, specify a mask, which will cause the
617 /// constructor to throw exceptions on the given conditions.
619 /// OSCG_THROW_ON_UNSUPPORTED - if set, the constructor will
620 /// throw LoadError if there is a plugin in the group
621 /// for which there is no corresponding Plugin-
622 /// derived class to handle it
623 /// OSCG_THROW_ON_NO_BARRY - if set, the constructor will
624 /// throw LoadError if there are no Barry plugins
626 /// OSCG_THROW_ON_MULTIPLE_BARRIES - if set, the constructor will
627 /// throw LoadError if there is more than one Barry
628 /// plugin in the group
630 Group(const std::string
&group_name
, OpenSync::API
&api
,
631 unsigned throw_mask
= 0);
633 /// This constructor creates an empty, but named, Group.
634 explicit Group(const std::string
&group_name
);
636 bool HasUnsupportedPlugins() const;
637 bool HasBarryPlugins() const;
638 bool GroupExists(OpenSync::API
&api
) const;
639 bool AllConfigured(OpenSync::API
&api
) const;
640 int GetConnectedCount() const;
641 const std::string
& GetGroupName() const { return m_group_name
; }
643 /// Cycles through all plugins and ANDs the supported types
644 /// for each together, and returns it. The returned value is
645 /// the minimum set of supportable sync types for this group for
646 /// the given API engine.
647 pst_type
GetSupportedSyncTypes(OpenSync::API
&api
) const;
649 /// Returns comma separated string of application/plugin names,
651 std::string
GetAppNames() const;
653 /// Returns a reference to the (first) Barry plugin in the group.
654 /// Will throw std::logic_error if not found.
655 OpenSync::Config::Barry
& GetBarryPlugin();
656 const OpenSync::Config::Barry
& GetBarryPlugin() const;
658 /// Returns a pointer to the first non-Barry plugin in the group.
659 /// Returns 0 if not found.
660 OpenSync::Config::Plugin
* GetNonBarryPlugin();
661 const OpenSync::Config::Plugin
* GetNonBarryPlugin() const;
663 /// Sets the member_id of all plugins to -1, thereby making them
664 /// appear like they have never been saved to an API before.
665 /// A call to Save() after a call to DisconnectMembers() will
666 /// create a completely new group. Note that if the group name
667 /// already exists in the API, saving to it again may cause
668 /// a low level exception to be thrown.
669 void DisconnectMembers();
671 /// Loads all available plugins from the named group, using
672 /// the api given. If this Group isn't empty (size() != 0),
673 /// then DisconnectMembers() will be called first.
674 void Load(OpenSync::API
&api
, unsigned throw_mask
= 0);
675 /// Same as Load() above, but loads from src_group_name instead
676 /// of m_group_name. m_group_name will not be changed.
677 void Load(const std::string
&src_group_name
, OpenSync::API
&api
,
678 unsigned throw_mask
= 0);
680 /// Overwrites m_group_name with a new one.
681 void ResetGroupName(const std::string
&new_group_name
);
683 /// Adds plugin to group, and takes ownership of the pointer
684 void AddPlugin(OpenSync::Config::Plugin
*plugin
);
686 /// Remove the plugin from the group. Only can guarantee removal
687 /// of non-saved (i.e. disconnected) plugins. If a plugin has
688 /// already been saved to the underlying OpenSync API, it
689 /// may not be possible to delete just one member from the
690 /// group (0.22), and a DeleteError will be thrown.
692 /// If you don't want to actually delete any members from any
693 /// existing configs, then DisconnectMembers() first.
694 void DeletePlugin(iterator i
, OpenSync::API
&api
);
696 /// Returns true if it is possible to resave this
697 /// Group to the existing opensync config. If this returns
698 /// false, and there are connected members, Save() will
699 /// throw. Save() will automatically call this function
702 /// Note: only call this if GroupExists() is true, otherwise,
703 /// this function is irrelevant.
704 bool GroupMatchesExistingConfig(OpenSync::API
&api
);
706 /// Save all plugins as members of the group. If the group doesn't
707 /// exist, it will be created. If the group does exist, and its
708 /// existing plugin list and member_id's don't match this Group's
709 /// list, SaveError will be thrown. If a plugin doesn't have a
710 /// member_id, it will be added as a new member to the group and
711 /// given an id. Note that an exception thrown from this function
712 /// means that the group is left in an undefined state. Best to
713 /// delete it and start over. Or load it, delete it (through the API),
714 /// disconnect it, and save it again.
715 void Save(OpenSync::API
&api
);
717 /// Compares against another group, including all the plugins,
718 /// and each plugin data. Order of plugins in group does not
719 /// matter, nor do file-specific data, like member IDs.
720 /// If saving both groups would result in functionally equivalent
721 /// sync groups, then they are equal. This is used to avoid
722 /// re-saving when not necessary.
723 /// Returns true if equal.
724 bool Compare(const Group
&group
) const;
726 /// Clones this Group object and returns a group_ptr of the new one
727 group_ptr
Clone() const;
729 /// Forget all plugins and delete them all
730 using base_type::clear
;
732 // bring underlying implementation forward
733 using base_type::size
;
734 using base_type::begin
;
735 using base_type::end
;
736 using base_type::operator[];
740 }} // namespace OpenSync::Config