2008-03-06 23:23:13 +01:00
/*
2009-03-25 15:21:04 +01:00
* Copyright ( C ) 2008 - 2009 Patrick Ohly < patrick . ohly @ gmx . de >
* Copyright ( C ) 2009 Intel Corporation
2009-04-30 18:14:03 +02:00
*
* 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
2008-03-06 23:23:13 +01:00
*/
2009-07-09 18:58:21 +02:00
# include "config.h"
2009-10-05 14:49:32 +02:00
# include <syncevo/SyncConfig.h>
# include <syncevo/SyncSource.h>
# include <syncevo/SyncContext.h>
# include <syncevo/FileConfigTree.h>
# include <syncevo/VolatileConfigTree.h>
# include <syncevo/VolatileConfigNode.h>
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
# include <syncevo/DevNullConfigNode.h>
# include <syncevo/MultiplexConfigNode.h>
2010-05-03 17:47:18 +02:00
# include <syncevo/SingleFileConfigTree.h>
2012-06-05 10:27:29 +02:00
# include <syncevo/IniConfigNode.h>
2011-01-10 15:56:53 +01:00
# include <syncevo/Cmdline.h>
Configuration templates matching: match templates based on metadata
Introduced TemplateConfig to abstracting the template configuration structure,
the template metadata used for matching is also parsed here.
The fields introduced in the metadata are:
PeerIsClient: identify whether this is a server side configuration or a client
side configuration.
Fingerprint: the matching string for this template, it is a comma separated string
with each string modeled as: "Manufacture_Model". The first substring is also
used as the name to identify this template so that user can select the template
by this name.
eg:
Nokia 7210c: Nokia_7210c
SyncEvolution server: SyncEvolutionServer, SyncEvolution
ScheduleWorld: ScheduleWorld,default
SyncEvolution client: SyncEvolutionClient, SyncEvolution
Description: this is a just a descriptive string not used for matching.
GetServerTemplates is changed to add another "devices" parameter to identify
it is asking for templates for a list of "devices". Each device is a tuple
<matchstring (devicename), matchMode (server/client/all)>.
TemplateList as the return type, which is a list of class TemplateDescription
so that we can also return enough information for corresponding templates. This
list is sorted by the 3-tuple <finger, rank, name>.
Add MatchServerTemplates method which will iterating all templates inside the
folder and match against the input parameter and finally return a sorted
list of matched templates.
The atcually fuzzy match algorithm is based on a LCS (added in the following
commit).
Cmdline interface is changed accordingly:
--template ? is changed to --template ?[string], so that user use the former
case to match all templates for a tradiontial SyncML client and the latter case
to match templates related to an input string.
SyncConfig API is also renamed (Server -> Peer) because both server/client
configuration/template are handled.
The original configuration template (Funambol and ScheduleWorld) has been moved
to the new template structure (under servers), they also have a .template.ini
file added so that they can be matched and picked up. All templates for
supported servers still have built-in template support in the code as before.
Templates for SyncEvolution based server is also added.
Server side templates are added (Nokia default, Nokia_7210c and SyncEvolutionServer).
Add unit test for the new template match use case.
2010-01-19 08:01:05 +01:00
# include <syncevo/lcs.h>
2013-04-24 12:00:45 +02:00
# include <syncevo/ThreadSupport.h>
2013-07-26 10:22:11 +02:00
# include <syncevo/IdentityProvider.h>
2010-01-13 19:12:40 +01:00
# include <test.h>
2009-10-05 14:49:32 +02:00
# include <synthesis/timeutil.h>
2008-03-06 23:23:13 +01:00
2008-07-11 22:25:02 +02:00
# include <iterator>
# include <algorithm>
# include <functional>
Configuration templates matching: match templates based on metadata
Introduced TemplateConfig to abstracting the template configuration structure,
the template metadata used for matching is also parsed here.
The fields introduced in the metadata are:
PeerIsClient: identify whether this is a server side configuration or a client
side configuration.
Fingerprint: the matching string for this template, it is a comma separated string
with each string modeled as: "Manufacture_Model". The first substring is also
used as the name to identify this template so that user can select the template
by this name.
eg:
Nokia 7210c: Nokia_7210c
SyncEvolution server: SyncEvolutionServer, SyncEvolution
ScheduleWorld: ScheduleWorld,default
SyncEvolution client: SyncEvolutionClient, SyncEvolution
Description: this is a just a descriptive string not used for matching.
GetServerTemplates is changed to add another "devices" parameter to identify
it is asking for templates for a list of "devices". Each device is a tuple
<matchstring (devicename), matchMode (server/client/all)>.
TemplateList as the return type, which is a list of class TemplateDescription
so that we can also return enough information for corresponding templates. This
list is sorted by the 3-tuple <finger, rank, name>.
Add MatchServerTemplates method which will iterating all templates inside the
folder and match against the input parameter and finally return a sorted
list of matched templates.
The atcually fuzzy match algorithm is based on a LCS (added in the following
commit).
Cmdline interface is changed accordingly:
--template ? is changed to --template ?[string], so that user use the former
case to match all templates for a tradiontial SyncML client and the latter case
to match templates related to an input string.
SyncConfig API is also renamed (Server -> Peer) because both server/client
configuration/template are handled.
The original configuration template (Funambol and ScheduleWorld) has been moved
to the new template structure (under servers), they also have a .template.ini
file added so that they can be matched and picked up. All templates for
supported servers still have built-in template support in the code as before.
Templates for SyncEvolution based server is also added.
Server side templates are added (Nokia default, Nokia_7210c and SyncEvolutionServer).
Add unit test for the new template match use case.
2010-01-19 08:01:05 +01:00
# include <queue>
2008-07-11 22:25:02 +02:00
2008-03-06 23:23:13 +01:00
# include <unistd.h>
# include "config.h"
2009-10-05 14:49:32 +02:00
# include <syncevo/declarations.h>
2009-10-02 17:23:53 +02:00
SE_BEGIN_CXX
2009-10-25 22:46:09 +01:00
const char * const SourceAdminDataName = " adminData " ;
2014-09-01 12:43:08 +02:00
const char * const SyncMaxMsgSize = " maxMsgSize " ;
2009-10-25 22:46:09 +01:00
2011-01-10 15:56:53 +01:00
int ConfigVersions [ CONFIG_LEVEL_MAX ] [ CONFIG_VERSION_MAX ] =
{
{ CONFIG_ROOT_MIN_VERSION , CONFIG_ROOT_CUR_VERSION } ,
{ CONFIG_CONTEXT_MIN_VERSION , CONFIG_CONTEXT_CUR_VERSION } ,
{ CONFIG_PEER_MIN_VERSION , CONFIG_PEER_CUR_VERSION } ,
} ;
std : : string ConfigLevel2String ( ConfigLevel level )
{
switch ( level ) {
case CONFIG_LEVEL_ROOT :
return " config root " ;
break ;
case CONFIG_LEVEL_CONTEXT :
return " context config " ;
break ;
case CONFIG_LEVEL_PEER :
return " peer config " ;
break ;
default :
return StringPrintf ( " config level %d (?) " , level) ;
break ;
}
}
2011-01-25 11:11:53 +01:00
PropertySpecifier PropertySpecifier : : StringToPropSpec ( const std : : string & spec , int flags )
{
PropertySpecifier res ;
size_t slash = spec . find ( ' / ' ) ;
if ( slash ! = spec . npos ) {
// no normalization needed at the moment
res . m_source = spec . substr ( 0 , slash ) ;
slash + + ;
} else {
slash = 0 ;
}
size_t at = spec . find ( ' @ ' , slash ) ;
if ( at ! = spec . npos ) {
// Context or config?
if ( spec . find ( ' @ ' , at + 1 ) ! = spec . npos ) {
// has a second @ sign, must be config name
res . m_config = spec . substr ( at + 1 ) ;
} else {
// context, include leading @ sign
res . m_config = spec . substr ( at ) ;
}
if ( flags & NORMALIZE_CONFIG ) {
2011-03-02 11:20:27 +01:00
res . m_config = SyncConfig : : normalizeConfigString ( res . m_config , SyncConfig : : NORMALIZE_LONG_FORMAT ) ;
2011-01-25 11:11:53 +01:00
}
} else {
at = spec . size ( ) ;
}
res . m_property = spec . substr ( slash , at - slash ) ;
return res ;
}
2013-07-26 10:22:11 +02:00
UserIdentity : : UserIdentity ( ) :
m_provider ( InitStateString ( USER_IDENTITY_PLAIN_TEXT , false ) )
{
}
UserIdentity UserIdentity : : fromString ( const InitStateString & idString )
{
UserIdentity id ;
if ( idString . wasSet ( ) ) {
size_t off = idString . find ( ' : ' ) ;
if ( off ! = idString . npos ) {
id . m_provider = off ?
idString . substr ( 0 , off ) :
InitStateString ( USER_IDENTITY_PLAIN_TEXT , false ) ;
id . m_identity = idString . substr ( off + 1 ) ;
} else {
id . m_provider = InitStateString ( USER_IDENTITY_PLAIN_TEXT , false ) ;
id . m_identity = idString ;
}
}
return id ;
}
InitStateString UserIdentity : : toString ( ) const
{
std : : string str ;
if ( m_provider . wasSet ( ) ) {
str + = m_provider ;
str + = ' : ' ;
}
str + = m_identity ;
return InitStateString ( str , m_provider . wasSet ( ) | | m_identity . wasSet ( ) ) ;
}
2011-01-25 11:11:53 +01:00
std : : string PropertySpecifier : : toString ( )
{
std : : string res ;
res . reserve ( m_source . size ( ) + 1 + m_property . size ( ) + 1 + m_config . size ( ) ) ;
res + = m_source ;
if ( ! m_source . empty ( ) ) {
res + = ' / ' ;
}
res + = m_property ;
if ( ! m_config . empty ( ) ) {
if ( m_config [ 0 ] ! = ' @ ' ) {
res + = ' @ ' ;
}
res + = m_config ;
}
return res ;
}
configuration: added possibility to define property name aliases
The goal is to allow multiple names for properties. This will be used
to replace legacy names like "evolutionsource", but it could also be
used to allow abbreviations on the command line.
First the patch replaces the single ConfigProperty::m_name with a list
of names, of which the first one is the current name of the
property.
The name that is to be used depends on the node which is to be
manipulated: if it already has a property under an alias, that alias
is read and also written, so existing configuration continue to use
the old config name (avoids the problem of having to remove the old
name and insert the new one at the same spot in a .ini file). Old
configs continue to parse okay. Writing into node which has none of
the names set, as in migrating into a fresh config, uses the new
names.
Most of the patch deals with the removal of a single, unique name,
either by picking the name so that it matches a node, using the
default name or simply hard-coding a property name ("sync").
The command line accepts all aliases, then uses the main name for
overriding configuration options.
2011-01-18 15:18:21 +01:00
string ConfigProperty : : getName ( const ConfigNode & node ) const
{
if ( m_names . empty ( ) ) {
// shouldn't happen
return " ??? " ;
}
if ( m_names . size ( ) = = 1 ) {
// typical case for most properties
return m_names . front ( ) ;
}
// pick the name already used in the node
2018-01-16 10:58:04 +01:00
for ( const std : : string & name : m_names ) {
configuration: added possibility to define property name aliases
The goal is to allow multiple names for properties. This will be used
to replace legacy names like "evolutionsource", but it could also be
used to allow abbreviations on the command line.
First the patch replaces the single ConfigProperty::m_name with a list
of names, of which the first one is the current name of the
property.
The name that is to be used depends on the node which is to be
manipulated: if it already has a property under an alias, that alias
is read and also written, so existing configuration continue to use
the old config name (avoids the problem of having to remove the old
name and insert the new one at the same spot in a .ini file). Old
configs continue to parse okay. Writing into node which has none of
the names set, as in migrating into a fresh config, uses the new
names.
Most of the patch deals with the removal of a single, unique name,
either by picking the name so that it matches a node, using the
default name or simply hard-coding a property name ("sync").
The command line accepts all aliases, then uses the main name for
overriding configuration options.
2011-01-18 15:18:21 +01:00
string value ;
if ( node . getProperty ( name , value ) ) {
return name ;
}
}
// main name as fallback
return m_names . front ( ) ;
}
2008-03-18 22:45:34 +01:00
void ConfigProperty : : splitComment ( const string & comment , list < string > & commentLines )
{
size_t start = 0 ;
while ( true ) {
size_t end = comment . find ( ' \n ' , start ) ;
if ( end = = comment . npos ) {
commentLines . push_back ( comment . substr ( start ) ) ;
break ;
} else {
commentLines . push_back ( comment . substr ( start , end - start ) ) ;
start = end + 1 ;
}
}
}
2008-03-19 12:29:14 +01:00
void ConfigProperty : : throwValueError ( const ConfigNode & node , const string & name , const string & value , const string & error ) const
{
2014-04-02 14:57:56 +02:00
Exception : : throwError ( SE_HERE , node . getName ( ) + " : " + name + " = " + value + " : " + error ) ;
2008-03-19 12:29:14 +01:00
}
2011-10-19 17:15:50 +02:00
std : : string ConfigProperty : : sharing2str ( Sharing sharing )
{
switch ( sharing ) {
case GLOBAL_SHARING :
return " global " ;
break ;
case SOURCE_SET_SHARING :
return " shared " ;
break ;
case NO_SHARING :
return " unshared " ;
break ;
}
return " ??? " ;
}
2011-03-02 11:20:27 +01:00
string SyncConfig : : normalizeConfigString ( const string & config , NormalizeFlags flags )
2009-11-13 14:52:00 +01:00
{
2010-01-29 20:45:27 +01:00
string normal = config ;
2009-11-13 14:52:00 +01:00
boost : : to_lower ( normal ) ;
2018-01-16 10:58:04 +01:00
for ( char & character : normal ) {
2010-01-13 19:12:40 +01:00
if ( ! isprint ( character ) | |
character = = ' / ' | |
character = = ' \\ ' | |
character = = ' : ' ) {
character = ' _ ' ;
}
}
2009-11-13 14:52:00 +01:00
if ( boost : : ends_with ( normal , " @default " ) ) {
2011-03-02 11:20:27 +01:00
if ( flags & NORMALIZE_SHORTHAND ) {
2011-01-25 10:27:39 +01:00
normal . resize ( normal . size ( ) - strlen ( " @default " ) ) ;
}
2009-11-13 14:52:00 +01:00
} else if ( boost : : ends_with ( normal , " @ " ) ) {
normal . resize ( normal . size ( ) - 1 ) ;
2009-11-25 23:08:57 +01:00
} else {
size_t at = normal . rfind ( ' @ ' ) ;
2011-03-02 11:20:27 +01:00
if ( at = = normal . npos & &
! ( flags & NORMALIZE_IS_NEW ) ) {
2010-01-29 20:45:27 +01:00
// No explicit context. Pick the first server which matches
// when ignoring their context. Peer list is sorted by name,
// therefore shorter config names (= without context) are
// found first, as intended.
2021-02-06 15:39:12 +01:00
for ( const auto & entry : getConfigs ( ) ) {
2010-01-29 20:45:27 +01:00
string entry_peer , entry_context ;
splitConfigString ( entry . first , entry_peer , entry_context ) ;
if ( normal = = entry_peer ) {
// found a matching, existing config, use it
normal = entry . first ;
break ;
}
}
2009-11-25 23:08:57 +01:00
}
2011-03-02 11:20:27 +01:00
if ( ! ( flags & NORMALIZE_SHORTHAND ) & & normal . find ( ' @ ' ) = = normal . npos ) {
2011-01-25 10:27:39 +01:00
// explicitly include @default context specifier
normal + = " @default " ;
}
2009-11-13 14:52:00 +01:00
}
2010-01-29 20:45:27 +01:00
2009-11-21 18:25:19 +01:00
if ( normal . empty ( ) ) {
2010-01-29 20:45:27 +01:00
// default context is meant with the empty string,
// better make that explicit
2009-11-21 18:25:19 +01:00
normal = " @default " ;
}
2010-01-29 20:45:27 +01:00
return normal ;
2009-11-13 14:52:00 +01:00
}
2011-07-26 03:12:58 +02:00
std : : string SyncConfig : : DeviceDescription : : getFingerprint ( ) const
{
std : : string fingerprint ;
/** In the case that we have the PnpInformation we prefer it over
* the mutable device name . The is true even if we only found the
* vendor component of the PnpInformation .
*/
if ( m_pnpInformation ) {
if ( m_pnpInformation - > isKnownProduct ( ) )
fingerprint = m_pnpInformation - > m_product ;
else
fingerprint = m_pnpInformation - > m_vendor ;
}
else {
fingerprint = m_deviceName ;
}
return fingerprint ;
}
2010-03-02 21:28:28 +01:00
bool SyncConfig : : splitConfigString ( const string & config , string & peer , string & context )
2009-11-21 18:25:19 +01:00
{
string : : size_type at = config . rfind ( ' @ ' ) ;
if ( at ! = config . npos ) {
peer = config . substr ( 0 , at ) ;
context = config . substr ( at + 1 ) ;
2010-03-02 21:28:28 +01:00
return true ;
2009-11-21 18:25:19 +01:00
} else {
peer = config ;
context = " default " ;
2010-03-02 21:28:28 +01:00
return false ;
2009-11-21 18:25:19 +01:00
}
}
2011-01-10 15:56:53 +01:00
static SyncConfig : : ConfigWriteMode defaultConfigWriteMode ( )
{
return SyncContext : : isStableRelease ( ) ?
SyncConfig : : MIGRATE_AUTOMATICALLY :
SyncConfig : : ASK_USER_TO_MIGRATE ;
}
2009-10-06 17:22:47 +02:00
SyncConfig : : SyncConfig ( ) :
2011-01-10 15:56:53 +01:00
m_layout ( HTTP_SERVER_LAYOUT ) , // use more compact layout with shorter paths and less source nodes
m_configWriteMode ( defaultConfigWriteMode ( ) )
2008-04-05 14:08:30 +02:00
{
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
// initialize properties
SyncConfig : : getRegistry ( ) ;
SyncSourceConfig : : getRegistry ( ) ;
m_peerPath =
m_contextPath = " volatile " ;
2009-11-20 13:23:15 +01:00
makeVolatile ( ) ;
}
void SyncConfig : : makeVolatile ( )
{
2008-04-05 14:08:30 +02:00
m_tree . reset ( new VolatileConfigTree ( ) ) ;
2013-09-06 10:30:30 +02:00
m_fileTree . reset ( ) ;
2009-11-13 14:52:00 +01:00
m_peerNode . reset ( new VolatileConfigNode ( ) ) ;
m_hiddenPeerNode = m_peerNode ;
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
m_globalNode = m_peerNode ;
m_contextNode = m_peerNode ;
m_contextHiddenNode = m_peerNode ;
m_props [ false ] = m_peerNode ;
m_props [ true ] = m_peerNode ;
2008-04-05 14:08:30 +02:00
}
2012-12-04 15:38:03 +01:00
void SyncConfig : : makeEphemeral ( )
{
m_ephemeral = true ;
// m_hiddenPeerNode.reset(new VolatileConfigNode());
// m_contextHiddenNode = m_hiddenPeerNode;
}
2013-09-09 10:32:12 +02:00
/**
* The goal is to have only one FileConfigTree instance per file system
* location . This ensures that in - memory representations remain in sync
* when instantiating a SyncConfig is created multiple times . In addition ,
* FilterConfigNodes also must only exit once per underlying node . This
* allows sharing cached passwords between configs when using indirect
* password lookup .
*
* The implementation in both cases is the same : keep a cache with
* weak pointers . When asked for an instance , consult the cache first .
* If the instance still exists , we can return that shared pointer . If
* not , we create a new one .
*
* It is necessary to garbage - collect obsolete entries , because the
* lookup parameters might never be used again .
*/
class ConfigCache
{
2018-01-16 17:17:34 +01:00
typedef std : : map < std : : pair < std : : string , SyncConfig : : Layout > , std : : weak_ptr < FileConfigTree > > TreeMap ;
2013-09-09 10:32:12 +02:00
TreeMap m_trees ;
2018-01-16 17:17:34 +01:00
typedef std : : map < ConfigNode * , std : : weak_ptr < FilterConfigNode > > NodeMap ;
2013-09-09 10:32:12 +02:00
NodeMap m_nodes ;
template < class M > void purge ( M & map )
{
2018-01-31 17:28:28 +01:00
auto it = map . begin ( ) ;
2013-09-09 10:32:12 +02:00
while ( it ! = map . end ( ) ) {
if ( ! it - > second . lock ( ) ) {
2018-01-31 17:28:28 +01:00
auto next = it ;
2013-09-09 10:32:12 +02:00
+ + next ;
map . erase ( it ) ;
it = next ;
} else {
+ + it ;
}
}
}
void purge ( ) ;
public :
2018-01-16 17:17:34 +01:00
std : : shared_ptr < FileConfigTree > createTree ( const std : : string & root ,
2013-09-09 10:32:12 +02:00
SyncConfig : : Layout layout ) ;
/**
* The filter is only installed when creating a new node . It is
* assumed to be the same when reusing the node .
*/
2018-01-16 17:17:34 +01:00
std : : shared_ptr < FilterConfigNode > createNode ( const std : : shared_ptr < ConfigNode > & node ,
2013-09-09 10:32:12 +02:00
const FilterConfigNode : : ConfigFilter & filter = FilterConfigNode : : ConfigFilter ( ) ) ;
static ConfigCache & singleton ( ) ;
} ;
ConfigCache & ConfigCache : : singleton ( )
{
static ConfigCache instance ;
return instance ;
}
void ConfigCache : : purge ( )
{
purge ( m_trees ) ;
purge ( m_nodes ) ;
}
2018-01-16 17:17:34 +01:00
std : : shared_ptr < FileConfigTree > ConfigCache : : createTree ( const std : : string & root ,
2013-09-09 10:32:12 +02:00
SyncConfig : : Layout layout )
{
TreeMap : : mapped_type & entry = m_trees [ TreeMap : : key_type ( root , layout ) ] ;
2018-01-16 17:17:34 +01:00
std : : shared_ptr < FileConfigTree > result ;
2013-09-09 10:32:12 +02:00
result = entry . lock ( ) ;
if ( ! result ) {
result . reset ( new FileConfigTree ( root , layout ) ) ;
entry = result ;
}
purge ( ) ;
return result ;
}
2018-01-16 17:17:34 +01:00
std : : shared_ptr < FilterConfigNode > ConfigCache : : createNode ( const std : : shared_ptr < ConfigNode > & node ,
2013-09-09 10:32:12 +02:00
const FilterConfigNode : : ConfigFilter & filter )
{
NodeMap : : mapped_type & entry = m_nodes [ node . get ( ) ] ;
2018-01-16 17:17:34 +01:00
std : : shared_ptr < FilterConfigNode > result ;
2013-09-09 10:32:12 +02:00
result = entry . lock ( ) ;
if ( ! result ) {
result . reset ( new FilterConfigNode ( node , filter ) ) ;
entry = result ;
}
purge ( ) ;
return result ;
}
2009-11-13 14:52:00 +01:00
SyncConfig : : SyncConfig ( const string & peer ,
2018-01-16 17:17:34 +01:00
std : : shared_ptr < ConfigTree > tree ,
support local sync (BMC #712)
Local sync is configured with a new syncURL = local://<context> where
<context> identifies the set of databases to synchronize with. The
URI of each source in the config identifies the source in that context
to synchronize with.
The databases in that context run a SyncML session as client. The
config itself is for a server. Reversing these roles is possible by
putting the config into the other context.
A sync is started by the server side, via the new LocalTransportAgent.
That agent forks, sets up the client side, then passes messages
back and forth via stream sockets. Stream sockets are useful because
unexpected peer shutdown can be detected.
Running the server side requires a few changes:
- do not send a SAN message, the client will start the
message exchange based on the config
- wait for that message before doing anything
The client side is more difficult:
- Per-peer config nodes do not exist in the target context.
They are stored in a hidden .<context> directory inside
the server config tree. This depends on the new "registering nodes
in the tree" feature. All nodes are hidden, because users
are not meant to edit any of them. Their name is intentionally
chosen like traditional nodes so that removing the config
also removes the new files.
- All relevant per-peer properties must be copied from the server
config (log level, printing changes, ...); they cannot be set
differently.
Because two separate SyncML sessions are used, we end up with
two normal session directories and log files.
The implementation is not complete yet:
- no glib support, so cannot be used in syncevo-dbus-server
- no support for CTRL-C and abort
- no interactive password entry for target sources
- unexpected slow syncs are detected on the client side, but
not reported properly on the server side
2010-07-31 18:28:53 +02:00
const string & redirectPeerRootPath ) :
m_layout ( SHARED_LAYOUT ) ,
2011-01-10 15:56:53 +01:00
m_redirectPeerRootPath ( redirectPeerRootPath ) ,
m_configWriteMode ( defaultConfigWriteMode ( ) )
2008-03-06 23:23:13 +01:00
{
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
// initialize properties
SyncConfig : : getRegistry ( ) ;
SyncSourceConfig : : getRegistry ( ) ;
2008-03-06 23:23:13 +01:00
string root ;
2010-01-29 20:45:27 +01:00
m_peer = normalizeConfigString ( peer ) ;
2009-11-13 14:52:00 +01:00
// except for SHARED_LAYOUT (set below),
// everything is below the directory called like
// the peer
m_peerPath =
m_contextPath =
m_peer ;
2018-01-30 17:00:24 +01:00
if ( tree . get ( ) ! = nullptr ) {
2013-08-02 22:02:03 +02:00
// existing tree points into simple configuration
2008-03-19 15:35:22 +01:00
m_tree = tree ;
2013-08-02 22:02:03 +02:00
m_layout = HTTP_SERVER_LAYOUT ;
m_peerPath =
m_contextPath = " " ;
2008-03-06 23:23:13 +01:00
} else {
2008-03-19 15:35:22 +01:00
// search for configuration in various places...
2009-11-13 14:52:00 +01:00
root = getOldRoot ( ) ;
string path = root + " / " + m_peerPath ;
if ( ! access ( ( path + " /spds/syncml/config.txt " ) . c_str ( ) , F_OK ) ) {
m_layout = SYNC4J_LAYOUT ;
2008-03-19 15:35:22 +01:00
} else {
2013-09-06 10:30:30 +02:00
m_layout = SHARED_LAYOUT ;
2009-11-13 14:52:00 +01:00
root = getNewRoot ( ) ;
path = root + " / " + m_peerPath ;
if ( ! access ( ( path + " /config.ini " ) . c_str ( ) , F_OK ) & &
2010-08-02 13:48:10 +02:00
! access ( ( path + " /sources " ) . c_str ( ) , F_OK ) & &
access ( ( path + " /peers " ) . c_str ( ) , F_OK ) ) {
2009-11-13 14:52:00 +01:00
m_layout = HTTP_SERVER_LAYOUT ;
} else {
// check whether config name specifies a context,
// otherwise use "default"
2009-11-21 18:25:19 +01:00
splitConfigString ( m_peer , m_peerPath , m_contextPath ) ;
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
if ( ! m_peerPath . empty ( ) ) {
m_peerPath = m_contextPath + " /peers/ " + m_peerPath ;
}
2009-11-13 14:52:00 +01:00
}
2008-03-19 15:35:22 +01:00
}
2013-09-09 10:32:12 +02:00
m_fileTree = ConfigCache : : singleton ( ) . createTree ( root , m_layout ) ;
2013-09-06 10:30:30 +02:00
m_tree = m_fileTree ;
2008-03-06 23:23:13 +01:00
}
2009-11-13 14:52:00 +01:00
string path ;
2018-01-16 17:17:34 +01:00
std : : shared_ptr < ConfigNode > node ;
2009-11-13 14:52:00 +01:00
switch ( m_layout ) {
case SYNC4J_LAYOUT :
// all properties reside in the same node
path = m_peerPath + " /spds/syncml " ;
node = m_tree - > open ( path , ConfigTree : : visible ) ;
2013-09-09 10:32:12 +02:00
m_peerNode = ConfigCache : : singleton ( ) . createNode ( node ) ;
2009-11-13 14:52:00 +01:00
m_globalNode =
m_contextNode = m_peerNode ;
m_hiddenPeerNode =
m_contextHiddenNode =
2011-01-10 15:56:53 +01:00
m_globalHiddenNode =
2009-11-13 14:52:00 +01:00
node ;
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
m_props [ false ] = m_peerNode ;
2013-09-09 10:32:12 +02:00
m_props [ true ] = ConfigCache : : singleton ( ) . createNode ( m_hiddenPeerNode ) ;
2009-11-13 14:52:00 +01:00
break ;
2009-12-01 17:19:50 +01:00
case HTTP_SERVER_LAYOUT : {
2009-11-13 14:52:00 +01:00
// properties which are normally considered shared are
2009-12-01 17:19:50 +01:00
// stored in the same nodes as the per-peer properties,
// except for global ones
path = " " ;
node = m_tree - > open ( path , ConfigTree : : visible ) ;
2013-09-09 10:32:12 +02:00
m_globalNode = ConfigCache : : singleton ( ) . createNode ( node ) ;
2011-01-10 15:56:53 +01:00
node = m_tree - > open ( path , ConfigTree : : hidden ) ;
m_globalHiddenNode = node ;
2009-12-01 17:19:50 +01:00
path = m_peerPath ;
2009-11-13 14:52:00 +01:00
node = m_tree - > open ( path , ConfigTree : : visible ) ;
2013-09-09 10:32:12 +02:00
m_peerNode = ConfigCache : : singleton ( ) . createNode ( node ) ;
2009-12-01 17:19:50 +01:00
m_contextNode = m_peerNode ;
2009-11-13 14:52:00 +01:00
m_hiddenPeerNode =
m_contextHiddenNode =
m_tree - > open ( path , ConfigTree : : hidden ) ;
2009-12-01 17:19:50 +01:00
// similar multiplexing as for SHARED_LAYOUT,
// with two nodes underneath
2018-01-16 17:17:34 +01:00
std : : shared_ptr < MultiplexConfigNode > mnode ;
2009-12-01 17:19:50 +01:00
mnode . reset ( new MultiplexConfigNode ( m_peerNode - > getName ( ) ,
getRegistry ( ) ,
false ) ) ;
m_props [ false ] = mnode ;
mnode - > setNode ( false , ConfigProperty : : GLOBAL_SHARING ,
m_globalNode ) ;
mnode - > setNode ( false , ConfigProperty : : SOURCE_SET_SHARING ,
m_peerNode ) ;
mnode - > setNode ( false , ConfigProperty : : NO_SHARING ,
m_peerNode ) ;
2011-01-10 15:56:53 +01:00
mnode . reset ( new MultiplexConfigNode ( m_peerNode - > getName ( ) ,
getRegistry ( ) ,
true ) ) ;
m_props [ true ] = mnode ;
mnode - > setNode ( true , ConfigProperty : : GLOBAL_SHARING ,
m_globalHiddenNode ) ;
mnode - > setNode ( true , ConfigProperty : : SOURCE_SET_SHARING ,
m_peerNode ) ;
mnode - > setNode ( true , ConfigProperty : : NO_SHARING ,
m_peerNode ) ;
2009-11-13 14:52:00 +01:00
break ;
2009-12-01 17:19:50 +01:00
}
2009-11-13 14:52:00 +01:00
case SHARED_LAYOUT :
// really use different nodes for everything
path = " " ;
node = m_tree - > open ( path , ConfigTree : : visible ) ;
2013-09-09 10:32:12 +02:00
m_globalNode = ConfigCache : : singleton ( ) . createNode ( node ) ;
2011-01-10 15:56:53 +01:00
node = m_tree - > open ( path , ConfigTree : : hidden ) ;
m_globalHiddenNode = node ;
2009-11-13 14:52:00 +01:00
path = m_peerPath ;
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
if ( path . empty ( ) ) {
support local sync (BMC #712)
Local sync is configured with a new syncURL = local://<context> where
<context> identifies the set of databases to synchronize with. The
URI of each source in the config identifies the source in that context
to synchronize with.
The databases in that context run a SyncML session as client. The
config itself is for a server. Reversing these roles is possible by
putting the config into the other context.
A sync is started by the server side, via the new LocalTransportAgent.
That agent forks, sets up the client side, then passes messages
back and forth via stream sockets. Stream sockets are useful because
unexpected peer shutdown can be detected.
Running the server side requires a few changes:
- do not send a SAN message, the client will start the
message exchange based on the config
- wait for that message before doing anything
The client side is more difficult:
- Per-peer config nodes do not exist in the target context.
They are stored in a hidden .<context> directory inside
the server config tree. This depends on the new "registering nodes
in the tree" feature. All nodes are hidden, because users
are not meant to edit any of them. Their name is intentionally
chosen like traditional nodes so that removing the config
also removes the new files.
- All relevant per-peer properties must be copied from the server
config (log level, printing changes, ...); they cannot be set
differently.
Because two separate SyncML sessions are used, we end up with
two normal session directories and log files.
The implementation is not complete yet:
- no glib support, so cannot be used in syncevo-dbus-server
- no support for CTRL-C and abort
- no interactive password entry for target sources
- unexpected slow syncs are detected on the client side, but
not reported properly on the server side
2010-07-31 18:28:53 +02:00
if ( ! m_redirectPeerRootPath . empty ( ) ) {
2012-06-05 10:27:29 +02:00
node . reset ( new IniFileConfigNode ( m_redirectPeerRootPath ,
" .internal.ini " ,
false ) ) ;
support local sync (BMC #712)
Local sync is configured with a new syncURL = local://<context> where
<context> identifies the set of databases to synchronize with. The
URI of each source in the config identifies the source in that context
to synchronize with.
The databases in that context run a SyncML session as client. The
config itself is for a server. Reversing these roles is possible by
putting the config into the other context.
A sync is started by the server side, via the new LocalTransportAgent.
That agent forks, sets up the client side, then passes messages
back and forth via stream sockets. Stream sockets are useful because
unexpected peer shutdown can be detected.
Running the server side requires a few changes:
- do not send a SAN message, the client will start the
message exchange based on the config
- wait for that message before doing anything
The client side is more difficult:
- Per-peer config nodes do not exist in the target context.
They are stored in a hidden .<context> directory inside
the server config tree. This depends on the new "registering nodes
in the tree" feature. All nodes are hidden, because users
are not meant to edit any of them. Their name is intentionally
chosen like traditional nodes so that removing the config
also removes the new files.
- All relevant per-peer properties must be copied from the server
config (log level, printing changes, ...); they cannot be set
differently.
Because two separate SyncML sessions are used, we end up with
two normal session directories and log files.
The implementation is not complete yet:
- no glib support, so cannot be used in syncevo-dbus-server
- no support for CTRL-C and abort
- no interactive password entry for target sources
- unexpected slow syncs are detected on the client side, but
not reported properly on the server side
2010-07-31 18:28:53 +02:00
node = m_tree - > add ( m_redirectPeerRootPath + " /.internal.ini " ,
node ) ;
} else {
node . reset ( new DevNullConfigNode ( m_contextPath + " without peer config " ) ) ;
}
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
} else {
node = m_tree - > open ( path , ConfigTree : : visible ) ;
}
2013-09-09 10:32:12 +02:00
m_peerNode = ConfigCache : : singleton ( ) . createNode ( node ) ;
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
if ( path . empty ( ) ) {
m_hiddenPeerNode = m_peerNode ;
} else {
m_hiddenPeerNode = m_tree - > open ( path , ConfigTree : : hidden ) ;
}
2009-11-13 14:52:00 +01:00
path = m_contextPath ;
node = m_tree - > open ( path , ConfigTree : : visible ) ;
2013-09-09 10:32:12 +02:00
m_contextNode = ConfigCache : : singleton ( ) . createNode ( node ) ;
2009-11-13 14:52:00 +01:00
m_contextHiddenNode = m_tree - > open ( path , ConfigTree : : hidden ) ;
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
// Instantiate multiplexer with the most specific node name in
// the set, the peer node's name. This is slightly inaccurate:
// error messages generated for this node in will reference
// the wrong config.ini file for shared properties. But
// there no shared properties which can trigger such an error
// at the moment, so this is good enough for now (MB#8037).
2018-01-16 17:17:34 +01:00
std : : shared_ptr < MultiplexConfigNode > mnode ;
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
mnode . reset ( new MultiplexConfigNode ( m_peerNode - > getName ( ) ,
getRegistry ( ) ,
false ) ) ;
2010-03-02 16:30:10 +01:00
mnode - > setHavePeerNodes ( ! m_peerPath . empty ( ) ) ;
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
m_props [ false ] = mnode ;
mnode - > setNode ( false , ConfigProperty : : GLOBAL_SHARING ,
m_globalNode ) ;
mnode - > setNode ( false , ConfigProperty : : SOURCE_SET_SHARING ,
m_contextNode ) ;
mnode - > setNode ( false , ConfigProperty : : NO_SHARING ,
m_peerNode ) ;
mnode . reset ( new MultiplexConfigNode ( m_hiddenPeerNode - > getName ( ) ,
getRegistry ( ) ,
true ) ) ;
2010-03-02 16:30:10 +01:00
mnode - > setHavePeerNodes ( ! m_peerPath . empty ( ) ) ;
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
m_props [ true ] = mnode ;
mnode - > setNode ( true , ConfigProperty : : SOURCE_SET_SHARING ,
m_contextHiddenNode ) ;
mnode - > setNode ( true , ConfigProperty : : NO_SHARING ,
m_hiddenPeerNode ) ;
2011-01-10 15:56:53 +01:00
mnode - > setNode ( true , ConfigProperty : : GLOBAL_SHARING ,
m_globalHiddenNode ) ;
2009-11-13 14:52:00 +01:00
break ;
}
2011-01-10 15:56:53 +01:00
// read version check
for ( ConfigLevel level = CONFIG_LEVEL_ROOT ;
level < CONFIG_LEVEL_MAX ;
level = ( ConfigLevel ) ( level + 1 ) ) {
if ( exists ( level ) ) {
if ( getConfigVersion ( level , CONFIG_MIN_VERSION ) > ConfigVersions [ level ] [ CONFIG_CUR_VERSION ] ) {
2013-04-08 19:17:36 +02:00
SE_LOG_INFO ( NULL , " config version check failed: %s has format %d, but this SyncEvolution release only supports format %d " ,
2011-01-10 15:56:53 +01:00
ConfigLevel2String ( level ) . c_str ( ) ,
getConfigVersion ( level , CONFIG_MIN_VERSION ) ,
ConfigVersions [ level ] [ CONFIG_CUR_VERSION ] ) ;
// our code is too old to read the config, reject it
SE_THROW_EXCEPTION_STATUS ( StatusException ,
StringPrintf ( " SyncEvolution %s is too old to read configuration '%s', please upgrade SyncEvolution. " ,
VERSION , peer . c_str ( ) ) ,
STATUS_RELEASE_TOO_OLD ) ;
}
}
}
// Note that the version check does not reject old configs because
// they are too old; so far, any release must be able to read any
// older config.
}
void SyncConfig : : prepareConfigForWrite ( )
{
// check versions before bumping to something incompatible with the
// previous user of the config
for ( ConfigLevel level = CONFIG_LEVEL_ROOT ;
level < CONFIG_LEVEL_MAX ;
level = ( ConfigLevel ) ( level + 1 ) ) {
2011-02-01 22:14:22 +01:00
if ( getLayout ( ) < SHARED_LAYOUT & &
level < CONFIG_LEVEL_PEER ) {
// old configs do not have explicit root or context,
// only check peer config itself
continue ;
}
2011-01-10 15:56:53 +01:00
if ( exists ( level ) ) {
if ( getConfigVersion ( level , CONFIG_CUR_VERSION ) < ConfigVersions [ level ] [ CONFIG_MIN_VERSION ] ) {
// release which created config will no longer be able to read
// updated config; either alert user or migrate automatically
string config ;
switch ( level ) {
case CONFIG_LEVEL_CONTEXT :
config = getContextName ( ) ;
break ;
case CONFIG_LEVEL_PEER :
config = getConfigName ( ) ;
break ;
case CONFIG_LEVEL_ROOT :
case CONFIG_LEVEL_MAX :
// keep compiler happy, not reached for _MAX
break ;
}
2013-04-08 19:17:36 +02:00
SE_LOG_INFO ( NULL , " must change format of %s '%s' in backward-incompatible way " ,
2011-01-10 15:56:53 +01:00
ConfigLevel2String ( level ) . c_str ( ) ,
config . c_str ( ) ) ;
if ( m_configWriteMode = = MIGRATE_AUTOMATICALLY ) {
// migrate config and anything beneath it,
// so no further checking needed
migrate ( config ) ;
break ;
} else {
SE_THROW_EXCEPTION_STATUS ( StatusException ,
StringPrintf ( " Proceeding would modify config '%s' such "
" that the previous SyncEvolution release "
" will not be able to use it. Stopping now. "
" Please explicitly acknowledge this step by "
" running the following command on the command "
" line: syncevolution --migrate '%s' " ,
config . c_str ( ) ,
config . c_str ( ) ) ,
STATUS_MIGRATION_NEEDED ) ;
}
}
}
}
// now set current versions at all levels,
// but without reducing versions: if a config has format
// "cur = 10", then properties or features added in that
// format remain even if the config is (temporarily?) used
// by a SyncEvolution binary which has "cur = 5".
for ( ConfigLevel level = CONFIG_LEVEL_ROOT ;
level < CONFIG_LEVEL_MAX ;
level = ( ConfigLevel ) ( level + 1 ) ) {
if ( level = = CONFIG_LEVEL_PEER & &
m_peerPath . empty ( ) ) {
// no need (and no possibility) to set per-peer version)
break ;
}
for ( ConfigLimit limit = CONFIG_MIN_VERSION ;
limit < CONFIG_VERSION_MAX ;
limit = ( ConfigLimit ) ( limit + 1 ) ) {
// set if equal to ensure that version == 0 (the default)
// is set explicitly
if ( getConfigVersion ( level , limit ) < = ConfigVersions [ level ] [ limit ] ) {
setConfigVersion ( level , limit , ConfigVersions [ level ] [ limit ] ) ;
}
}
}
flush ( ) ;
}
void SyncConfig : : migrate ( const std : : string & config )
{
if ( config . empty ( ) ) {
// migrating root not yet supported
SE_THROW ( " internal error, migrating config root not implemented " ) ;
} else {
// migrate using the higher-level logic in the Cmdline class
command line: cleaned up output
The user-visible part of this change is that command line output now
uses the same [ERROR/INFO] prefixes like the rest of SyncEvolution,
instead of "Error:". Several messages were split into [ERROR] and
[INFO] parts on seperate lines. Multi-line messages with such a prefix
now have the prefix at the start of each line. Full sentences start
with captital letters.
All usage errors related to the synopsis of the command line now
include the synopsis, without the detailed documentation of all
options. Some of those errors dumped the full documentation, which was
way too much information and pushed the actual synopsis off the
screen. Some other errors did not include usage information at all.
All output still goes to stdout, stderr is not used at all. Should be
changed in a seperate patch, because currently error messages during
operations like "--export -" get mixed with the result of the
operation.
Technically the output handling was simplified. All output is printed
via the logging system, instead of using a mixture of logging and
streaming into std::cout. The advantage is that it will be easier to
redirect all regular output inside the syncevo-dbus-helper to the
parent. In particular, the following code could be removed:
- the somewhat hacky std::streambuf->logging bridge code (CmdlineStreamBuf)
- SyncContext set/getOutput()
- ostream constructor parameters for Cmdline and derived classes
The new code uses SE_LOG_SHOW() to produce output without prefix. Each
call ends at the next line, regardless whether the string ends in a
newline or not. The LoggerStdout was adapted to behave according to
that expectation, and it inserts the line prefix at the start of each
line - probably didn't matter before, because hardly any (no?!)
message had line breaks.
Because of this implicit newline in the logging code, some newlines
become redundant; SE_LOG_SHOW("") is used to insert an empty line
where needed. Calls to the logging system are minimized if possible by
assembling output in buffers first, to reduce overhead and to adhere
to the "one call per message" guideline.
Testing was adapted accordingly. It's a bit stricter now, too, because
it checks the entire error output instead of just the last line. The
previous use of Cmdline ostreams to capture output from the class was
replaced with loggers which hook into the logging system while the
test runs and store the output. Same with SyncContext testing.
Conflicts:
src/dbus/server/cmdline-wrapper.h
2012-04-11 10:22:57 +02:00
Cmdline migrate ( m_peer . c_str ( ) ,
2011-01-10 15:56:53 +01:00
" --migrate " ,
config . c_str ( ) ,
2018-01-30 17:00:24 +01:00
nullptr ) ;
2011-01-10 15:56:53 +01:00
bool res = migrate . parse ( ) & & migrate . run ( ) ;
if ( ! res ) {
SE_THROW ( StringPrintf ( " migration of config '%s' failed " , config . c_str ( ) ) ) ;
}
// files that our tree access may have changed, refresh our
// in-memory copy
m_tree - > reload ( ) ;
}
2008-03-06 23:23:13 +01:00
}
2009-10-06 17:22:47 +02:00
string SyncConfig : : getRootPath ( ) const
2008-03-19 17:43:31 +01:00
{
2013-09-06 10:30:30 +02:00
return m_fileTree ?
normalizePath ( m_fileTree - > getRoot ( ) + " / " +
( ( m_layout = = SYNC4J_LAYOUT | | hasPeerProperties ( ) ) ? m_peerPath : m_contextPath ) ) :
" " ;
2008-03-19 17:43:31 +01:00
}
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
void SyncConfig : : addPeers ( const string & root ,
const std : : string & configname ,
Configuration templates matching: match templates based on metadata
Introduced TemplateConfig to abstracting the template configuration structure,
the template metadata used for matching is also parsed here.
The fields introduced in the metadata are:
PeerIsClient: identify whether this is a server side configuration or a client
side configuration.
Fingerprint: the matching string for this template, it is a comma separated string
with each string modeled as: "Manufacture_Model". The first substring is also
used as the name to identify this template so that user can select the template
by this name.
eg:
Nokia 7210c: Nokia_7210c
SyncEvolution server: SyncEvolutionServer, SyncEvolution
ScheduleWorld: ScheduleWorld,default
SyncEvolution client: SyncEvolutionClient, SyncEvolution
Description: this is a just a descriptive string not used for matching.
GetServerTemplates is changed to add another "devices" parameter to identify
it is asking for templates for a list of "devices". Each device is a tuple
<matchstring (devicename), matchMode (server/client/all)>.
TemplateList as the return type, which is a list of class TemplateDescription
so that we can also return enough information for corresponding templates. This
list is sorted by the 3-tuple <finger, rank, name>.
Add MatchServerTemplates method which will iterating all templates inside the
folder and match against the input parameter and finally return a sorted
list of matched templates.
The atcually fuzzy match algorithm is based on a LCS (added in the following
commit).
Cmdline interface is changed accordingly:
--template ? is changed to --template ?[string], so that user use the former
case to match all templates for a tradiontial SyncML client and the latter case
to match templates related to an input string.
SyncConfig API is also renamed (Server -> Peer) because both server/client
configuration/template are handled.
The original configuration template (Funambol and ScheduleWorld) has been moved
to the new template structure (under servers), they also have a .template.ini
file added so that they can be matched and picked up. All templates for
supported servers still have built-in template support in the code as before.
Templates for SyncEvolution based server is also added.
Server side templates are added (Nokia default, Nokia_7210c and SyncEvolutionServer).
Add unit test for the new template match use case.
2010-01-19 08:01:05 +01:00
SyncConfig : : ConfigList & res ) {
2013-09-06 10:30:30 +02:00
FileConfigTree tree ( root , SyncConfig : : HTTP_SERVER_LAYOUT ) ;
2008-03-18 22:45:34 +01:00
list < string > servers = tree . getChildren ( " " ) ;
2018-01-16 10:58:04 +01:00
for ( const string & server : servers ) {
2009-05-13 13:46:56 +02:00
// sanity check: only list server directories which actually
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
// contain a configuration. To distinguish between a context
// (~/.config/syncevolution/default) and an HTTP server config
// (~/.config/syncevolution/scheduleworld), we check for the
// "peer" subdirectory that is only in the former.
//
// Contexts which don't have a peer are therefore incorrectly
// listed as a peer. Short of adding a special hidden file
// this can't be fixed. This is probably overkill and thus not
// done yet.
string peerPath = server + " /peers " ;
if ( ! access ( ( root + " / " + peerPath ) . c_str ( ) , F_OK ) ) {
// not a real HTTP server, search for peers
2018-01-16 10:58:04 +01:00
for ( const string & peer : tree . getChildren ( peerPath ) ) {
Configuration templates matching: match templates based on metadata
Introduced TemplateConfig to abstracting the template configuration structure,
the template metadata used for matching is also parsed here.
The fields introduced in the metadata are:
PeerIsClient: identify whether this is a server side configuration or a client
side configuration.
Fingerprint: the matching string for this template, it is a comma separated string
with each string modeled as: "Manufacture_Model". The first substring is also
used as the name to identify this template so that user can select the template
by this name.
eg:
Nokia 7210c: Nokia_7210c
SyncEvolution server: SyncEvolutionServer, SyncEvolution
ScheduleWorld: ScheduleWorld,default
SyncEvolution client: SyncEvolutionClient, SyncEvolution
Description: this is a just a descriptive string not used for matching.
GetServerTemplates is changed to add another "devices" parameter to identify
it is asking for templates for a list of "devices". Each device is a tuple
<matchstring (devicename), matchMode (server/client/all)>.
TemplateList as the return type, which is a list of class TemplateDescription
so that we can also return enough information for corresponding templates. This
list is sorted by the 3-tuple <finger, rank, name>.
Add MatchServerTemplates method which will iterating all templates inside the
folder and match against the input parameter and finally return a sorted
list of matched templates.
The atcually fuzzy match algorithm is based on a LCS (added in the following
commit).
Cmdline interface is changed accordingly:
--template ? is changed to --template ?[string], so that user use the former
case to match all templates for a tradiontial SyncML client and the latter case
to match templates related to an input string.
SyncConfig API is also renamed (Server -> Peer) because both server/client
configuration/template are handled.
The original configuration template (Funambol and ScheduleWorld) has been moved
to the new template structure (under servers), they also have a .template.ini
file added so that they can be matched and picked up. All templates for
supported servers still have built-in template support in the code as before.
Templates for SyncEvolution based server is also added.
Server side templates are added (Nokia default, Nokia_7210c and SyncEvolutionServer).
Add unit test for the new template match use case.
2010-01-19 08:01:05 +01:00
res . push_back ( pair < string , string > ( normalizeConfigString ( peer + " @ " + server ) ,
root + " / " + peerPath + " / " + peer ) ) ;
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
}
} else if ( ! access ( ( root + " / " + server + " / " + configname ) . c_str ( ) , F_OK ) ) {
Configuration templates matching: match templates based on metadata
Introduced TemplateConfig to abstracting the template configuration structure,
the template metadata used for matching is also parsed here.
The fields introduced in the metadata are:
PeerIsClient: identify whether this is a server side configuration or a client
side configuration.
Fingerprint: the matching string for this template, it is a comma separated string
with each string modeled as: "Manufacture_Model". The first substring is also
used as the name to identify this template so that user can select the template
by this name.
eg:
Nokia 7210c: Nokia_7210c
SyncEvolution server: SyncEvolutionServer, SyncEvolution
ScheduleWorld: ScheduleWorld,default
SyncEvolution client: SyncEvolutionClient, SyncEvolution
Description: this is a just a descriptive string not used for matching.
GetServerTemplates is changed to add another "devices" parameter to identify
it is asking for templates for a list of "devices". Each device is a tuple
<matchstring (devicename), matchMode (server/client/all)>.
TemplateList as the return type, which is a list of class TemplateDescription
so that we can also return enough information for corresponding templates. This
list is sorted by the 3-tuple <finger, rank, name>.
Add MatchServerTemplates method which will iterating all templates inside the
folder and match against the input parameter and finally return a sorted
list of matched templates.
The atcually fuzzy match algorithm is based on a LCS (added in the following
commit).
Cmdline interface is changed accordingly:
--template ? is changed to --template ?[string], so that user use the former
case to match all templates for a tradiontial SyncML client and the latter case
to match templates related to an input string.
SyncConfig API is also renamed (Server -> Peer) because both server/client
configuration/template are handled.
The original configuration template (Funambol and ScheduleWorld) has been moved
to the new template structure (under servers), they also have a .template.ini
file added so that they can be matched and picked up. All templates for
supported servers still have built-in template support in the code as before.
Templates for SyncEvolution based server is also added.
Server side templates are added (Nokia default, Nokia_7210c and SyncEvolutionServer).
Add unit test for the new template match use case.
2010-01-19 08:01:05 +01:00
res . push_back ( pair < string , string > ( server , root + " / " + server ) ) ;
2009-05-13 13:46:56 +02:00
}
2008-03-18 22:45:34 +01:00
}
}
2011-01-17 10:26:25 +01:00
/** returns true if a precedes b (strict weak ordering) */
static bool cmpConfigEntries ( const StringPair & a , const StringPair & b )
{
string peerA , contextA , peerB , contextB ;
SyncConfig : : splitConfigString ( a . first , peerA , contextA ) ;
SyncConfig : : splitConfigString ( b . first , peerB , contextB ) ;
int res ;
res = contextA . compare ( contextB ) ;
if ( res = = 0 ) {
res = peerA . compare ( peerB ) ;
if ( res = = 0 ) {
res = a . second . compare ( b . second ) ;
}
}
return res < 0 ;
}
Configuration templates matching: match templates based on metadata
Introduced TemplateConfig to abstracting the template configuration structure,
the template metadata used for matching is also parsed here.
The fields introduced in the metadata are:
PeerIsClient: identify whether this is a server side configuration or a client
side configuration.
Fingerprint: the matching string for this template, it is a comma separated string
with each string modeled as: "Manufacture_Model". The first substring is also
used as the name to identify this template so that user can select the template
by this name.
eg:
Nokia 7210c: Nokia_7210c
SyncEvolution server: SyncEvolutionServer, SyncEvolution
ScheduleWorld: ScheduleWorld,default
SyncEvolution client: SyncEvolutionClient, SyncEvolution
Description: this is a just a descriptive string not used for matching.
GetServerTemplates is changed to add another "devices" parameter to identify
it is asking for templates for a list of "devices". Each device is a tuple
<matchstring (devicename), matchMode (server/client/all)>.
TemplateList as the return type, which is a list of class TemplateDescription
so that we can also return enough information for corresponding templates. This
list is sorted by the 3-tuple <finger, rank, name>.
Add MatchServerTemplates method which will iterating all templates inside the
folder and match against the input parameter and finally return a sorted
list of matched templates.
The atcually fuzzy match algorithm is based on a LCS (added in the following
commit).
Cmdline interface is changed accordingly:
--template ? is changed to --template ?[string], so that user use the former
case to match all templates for a tradiontial SyncML client and the latter case
to match templates related to an input string.
SyncConfig API is also renamed (Server -> Peer) because both server/client
configuration/template are handled.
The original configuration template (Funambol and ScheduleWorld) has been moved
to the new template structure (under servers), they also have a .template.ini
file added so that they can be matched and picked up. All templates for
supported servers still have built-in template support in the code as before.
Templates for SyncEvolution based server is also added.
Server side templates are added (Nokia default, Nokia_7210c and SyncEvolutionServer).
Add unit test for the new template match use case.
2010-01-19 08:01:05 +01:00
SyncConfig : : ConfigList SyncConfig : : getConfigs ( )
2008-03-18 22:45:34 +01:00
{
Configuration templates matching: match templates based on metadata
Introduced TemplateConfig to abstracting the template configuration structure,
the template metadata used for matching is also parsed here.
The fields introduced in the metadata are:
PeerIsClient: identify whether this is a server side configuration or a client
side configuration.
Fingerprint: the matching string for this template, it is a comma separated string
with each string modeled as: "Manufacture_Model". The first substring is also
used as the name to identify this template so that user can select the template
by this name.
eg:
Nokia 7210c: Nokia_7210c
SyncEvolution server: SyncEvolutionServer, SyncEvolution
ScheduleWorld: ScheduleWorld,default
SyncEvolution client: SyncEvolutionClient, SyncEvolution
Description: this is a just a descriptive string not used for matching.
GetServerTemplates is changed to add another "devices" parameter to identify
it is asking for templates for a list of "devices". Each device is a tuple
<matchstring (devicename), matchMode (server/client/all)>.
TemplateList as the return type, which is a list of class TemplateDescription
so that we can also return enough information for corresponding templates. This
list is sorted by the 3-tuple <finger, rank, name>.
Add MatchServerTemplates method which will iterating all templates inside the
folder and match against the input parameter and finally return a sorted
list of matched templates.
The atcually fuzzy match algorithm is based on a LCS (added in the following
commit).
Cmdline interface is changed accordingly:
--template ? is changed to --template ?[string], so that user use the former
case to match all templates for a tradiontial SyncML client and the latter case
to match templates related to an input string.
SyncConfig API is also renamed (Server -> Peer) because both server/client
configuration/template are handled.
The original configuration template (Funambol and ScheduleWorld) has been moved
to the new template structure (under servers), they also have a .template.ini
file added so that they can be matched and picked up. All templates for
supported servers still have built-in template support in the code as before.
Templates for SyncEvolution based server is also added.
Server side templates are added (Nokia default, Nokia_7210c and SyncEvolutionServer).
Add unit test for the new template match use case.
2010-01-19 08:01:05 +01:00
ConfigList res ;
2008-03-18 22:45:34 +01:00
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
addPeers ( getOldRoot ( ) , " config.txt " , res ) ;
addPeers ( getNewRoot ( ) , " config.ini " , res ) ;
2008-03-18 22:45:34 +01:00
2011-01-17 10:26:25 +01:00
// Sort the list by (context, peer name, path);
// better than returning it in random order.
// This sort order (compared to simple lexical
// sorting based on the full config name) has
// the advantage that peer names or contexts with
// suffix (foo.old vs. foo) come later.
res . sort ( cmpConfigEntries ) ;
2009-11-13 14:52:00 +01:00
2008-03-18 22:45:34 +01:00
return res ;
}
Configuration templates matching: match templates based on metadata
Introduced TemplateConfig to abstracting the template configuration structure,
the template metadata used for matching is also parsed here.
The fields introduced in the metadata are:
PeerIsClient: identify whether this is a server side configuration or a client
side configuration.
Fingerprint: the matching string for this template, it is a comma separated string
with each string modeled as: "Manufacture_Model". The first substring is also
used as the name to identify this template so that user can select the template
by this name.
eg:
Nokia 7210c: Nokia_7210c
SyncEvolution server: SyncEvolutionServer, SyncEvolution
ScheduleWorld: ScheduleWorld,default
SyncEvolution client: SyncEvolutionClient, SyncEvolution
Description: this is a just a descriptive string not used for matching.
GetServerTemplates is changed to add another "devices" parameter to identify
it is asking for templates for a list of "devices". Each device is a tuple
<matchstring (devicename), matchMode (server/client/all)>.
TemplateList as the return type, which is a list of class TemplateDescription
so that we can also return enough information for corresponding templates. This
list is sorted by the 3-tuple <finger, rank, name>.
Add MatchServerTemplates method which will iterating all templates inside the
folder and match against the input parameter and finally return a sorted
list of matched templates.
The atcually fuzzy match algorithm is based on a LCS (added in the following
commit).
Cmdline interface is changed accordingly:
--template ? is changed to --template ?[string], so that user use the former
case to match all templates for a tradiontial SyncML client and the latter case
to match templates related to an input string.
SyncConfig API is also renamed (Server -> Peer) because both server/client
configuration/template are handled.
The original configuration template (Funambol and ScheduleWorld) has been moved
to the new template structure (under servers), they also have a .template.ini
file added so that they can be matched and picked up. All templates for
supported servers still have built-in template support in the code as before.
Templates for SyncEvolution based server is also added.
Server side templates are added (Nokia default, Nokia_7210c and SyncEvolutionServer).
Add unit test for the new template match use case.
2010-01-19 08:01:05 +01:00
static string SyncEvolutionTemplateDir ( )
{
string templateDir ( TEMPLATE_DIR ) ;
const char * envvar = getenv ( " SYNCEVOLUTION_TEMPLATE_DIR " ) ;
if ( envvar ) {
templateDir = envvar ;
}
return templateDir ;
}
2010-01-21 14:39:09 +01:00
SyncConfig : : TemplateList SyncConfig : : matchPeerTemplates ( const DeviceList & peers , bool fuzzyMatch )
Configuration templates matching: match templates based on metadata
Introduced TemplateConfig to abstracting the template configuration structure,
the template metadata used for matching is also parsed here.
The fields introduced in the metadata are:
PeerIsClient: identify whether this is a server side configuration or a client
side configuration.
Fingerprint: the matching string for this template, it is a comma separated string
with each string modeled as: "Manufacture_Model". The first substring is also
used as the name to identify this template so that user can select the template
by this name.
eg:
Nokia 7210c: Nokia_7210c
SyncEvolution server: SyncEvolutionServer, SyncEvolution
ScheduleWorld: ScheduleWorld,default
SyncEvolution client: SyncEvolutionClient, SyncEvolution
Description: this is a just a descriptive string not used for matching.
GetServerTemplates is changed to add another "devices" parameter to identify
it is asking for templates for a list of "devices". Each device is a tuple
<matchstring (devicename), matchMode (server/client/all)>.
TemplateList as the return type, which is a list of class TemplateDescription
so that we can also return enough information for corresponding templates. This
list is sorted by the 3-tuple <finger, rank, name>.
Add MatchServerTemplates method which will iterating all templates inside the
folder and match against the input parameter and finally return a sorted
list of matched templates.
The atcually fuzzy match algorithm is based on a LCS (added in the following
commit).
Cmdline interface is changed accordingly:
--template ? is changed to --template ?[string], so that user use the former
case to match all templates for a tradiontial SyncML client and the latter case
to match templates related to an input string.
SyncConfig API is also renamed (Server -> Peer) because both server/client
configuration/template are handled.
The original configuration template (Funambol and ScheduleWorld) has been moved
to the new template structure (under servers), they also have a .template.ini
file added so that they can be matched and picked up. All templates for
supported servers still have built-in template support in the code as before.
Templates for SyncEvolution based server is also added.
Server side templates are added (Nokia default, Nokia_7210c and SyncEvolutionServer).
Add unit test for the new template match use case.
2010-01-19 08:01:05 +01:00
{
TemplateList result ;
// match against all possible templates without any assumption on directory
2010-01-20 04:20:24 +01:00
// layout, the match is entirely based on the metadata template.ini
Configuration templates matching: match templates based on metadata
Introduced TemplateConfig to abstracting the template configuration structure,
the template metadata used for matching is also parsed here.
The fields introduced in the metadata are:
PeerIsClient: identify whether this is a server side configuration or a client
side configuration.
Fingerprint: the matching string for this template, it is a comma separated string
with each string modeled as: "Manufacture_Model". The first substring is also
used as the name to identify this template so that user can select the template
by this name.
eg:
Nokia 7210c: Nokia_7210c
SyncEvolution server: SyncEvolutionServer, SyncEvolution
ScheduleWorld: ScheduleWorld,default
SyncEvolution client: SyncEvolutionClient, SyncEvolution
Description: this is a just a descriptive string not used for matching.
GetServerTemplates is changed to add another "devices" parameter to identify
it is asking for templates for a list of "devices". Each device is a tuple
<matchstring (devicename), matchMode (server/client/all)>.
TemplateList as the return type, which is a list of class TemplateDescription
so that we can also return enough information for corresponding templates. This
list is sorted by the 3-tuple <finger, rank, name>.
Add MatchServerTemplates method which will iterating all templates inside the
folder and match against the input parameter and finally return a sorted
list of matched templates.
The atcually fuzzy match algorithm is based on a LCS (added in the following
commit).
Cmdline interface is changed accordingly:
--template ? is changed to --template ?[string], so that user use the former
case to match all templates for a tradiontial SyncML client and the latter case
to match templates related to an input string.
SyncConfig API is also renamed (Server -> Peer) because both server/client
configuration/template are handled.
The original configuration template (Funambol and ScheduleWorld) has been moved
to the new template structure (under servers), they also have a .template.ini
file added so that they can be matched and picked up. All templates for
supported servers still have built-in template support in the code as before.
Templates for SyncEvolution based server is also added.
Server side templates are added (Nokia default, Nokia_7210c and SyncEvolutionServer).
Add unit test for the new template match use case.
2010-01-19 08:01:05 +01:00
string templateDir ( SyncEvolutionTemplateDir ( ) ) ;
std : : queue < std : : string , std : : list < std : : string > > directories ;
2010-05-03 17:47:18 +02:00
2010-05-03 21:41:36 +02:00
directories . push ( templateDir ) ;
templateDir = SubstEnvironment ( " ${XDG_CONFIG_HOME}/syncevolution-templates " ) ;
directories . push ( templateDir ) ;
Configuration templates matching: match templates based on metadata
Introduced TemplateConfig to abstracting the template configuration structure,
the template metadata used for matching is also parsed here.
The fields introduced in the metadata are:
PeerIsClient: identify whether this is a server side configuration or a client
side configuration.
Fingerprint: the matching string for this template, it is a comma separated string
with each string modeled as: "Manufacture_Model". The first substring is also
used as the name to identify this template so that user can select the template
by this name.
eg:
Nokia 7210c: Nokia_7210c
SyncEvolution server: SyncEvolutionServer, SyncEvolution
ScheduleWorld: ScheduleWorld,default
SyncEvolution client: SyncEvolutionClient, SyncEvolution
Description: this is a just a descriptive string not used for matching.
GetServerTemplates is changed to add another "devices" parameter to identify
it is asking for templates for a list of "devices". Each device is a tuple
<matchstring (devicename), matchMode (server/client/all)>.
TemplateList as the return type, which is a list of class TemplateDescription
so that we can also return enough information for corresponding templates. This
list is sorted by the 3-tuple <finger, rank, name>.
Add MatchServerTemplates method which will iterating all templates inside the
folder and match against the input parameter and finally return a sorted
list of matched templates.
The atcually fuzzy match algorithm is based on a LCS (added in the following
commit).
Cmdline interface is changed accordingly:
--template ? is changed to --template ?[string], so that user use the former
case to match all templates for a tradiontial SyncML client and the latter case
to match templates related to an input string.
SyncConfig API is also renamed (Server -> Peer) because both server/client
configuration/template are handled.
The original configuration template (Funambol and ScheduleWorld) has been moved
to the new template structure (under servers), they also have a .template.ini
file added so that they can be matched and picked up. All templates for
supported servers still have built-in template support in the code as before.
Templates for SyncEvolution based server is also added.
Server side templates are added (Nokia default, Nokia_7210c and SyncEvolutionServer).
Add unit test for the new template match use case.
2010-01-19 08:01:05 +01:00
while ( ! directories . empty ( ) ) {
string sDir = directories . front ( ) ;
directories . pop ( ) ;
2010-05-03 17:47:18 +02:00
if ( isDir ( sDir ) ) {
// check all sub directories
Configuration templates matching: match templates based on metadata
Introduced TemplateConfig to abstracting the template configuration structure,
the template metadata used for matching is also parsed here.
The fields introduced in the metadata are:
PeerIsClient: identify whether this is a server side configuration or a client
side configuration.
Fingerprint: the matching string for this template, it is a comma separated string
with each string modeled as: "Manufacture_Model". The first substring is also
used as the name to identify this template so that user can select the template
by this name.
eg:
Nokia 7210c: Nokia_7210c
SyncEvolution server: SyncEvolutionServer, SyncEvolution
ScheduleWorld: ScheduleWorld,default
SyncEvolution client: SyncEvolutionClient, SyncEvolution
Description: this is a just a descriptive string not used for matching.
GetServerTemplates is changed to add another "devices" parameter to identify
it is asking for templates for a list of "devices". Each device is a tuple
<matchstring (devicename), matchMode (server/client/all)>.
TemplateList as the return type, which is a list of class TemplateDescription
so that we can also return enough information for corresponding templates. This
list is sorted by the 3-tuple <finger, rank, name>.
Add MatchServerTemplates method which will iterating all templates inside the
folder and match against the input parameter and finally return a sorted
list of matched templates.
The atcually fuzzy match algorithm is based on a LCS (added in the following
commit).
Cmdline interface is changed accordingly:
--template ? is changed to --template ?[string], so that user use the former
case to match all templates for a tradiontial SyncML client and the latter case
to match templates related to an input string.
SyncConfig API is also renamed (Server -> Peer) because both server/client
configuration/template are handled.
The original configuration template (Funambol and ScheduleWorld) has been moved
to the new template structure (under servers), they also have a .template.ini
file added so that they can be matched and picked up. All templates for
supported servers still have built-in template support in the code as before.
Templates for SyncEvolution based server is also added.
Server side templates are added (Nokia default, Nokia_7210c and SyncEvolutionServer).
Add unit test for the new template match use case.
2010-01-19 08:01:05 +01:00
ReadDir dir ( sDir ) ;
2018-01-16 10:58:04 +01:00
for ( const string & entry : dir ) {
2011-05-18 16:19:26 +02:00
// ignore hidden files, . and ..
if ( ! boost : : starts_with ( entry , " . " ) ) {
directories . push ( sDir + " / " + entry ) ;
}
Configuration templates matching: match templates based on metadata
Introduced TemplateConfig to abstracting the template configuration structure,
the template metadata used for matching is also parsed here.
The fields introduced in the metadata are:
PeerIsClient: identify whether this is a server side configuration or a client
side configuration.
Fingerprint: the matching string for this template, it is a comma separated string
with each string modeled as: "Manufacture_Model". The first substring is also
used as the name to identify this template so that user can select the template
by this name.
eg:
Nokia 7210c: Nokia_7210c
SyncEvolution server: SyncEvolutionServer, SyncEvolution
ScheduleWorld: ScheduleWorld,default
SyncEvolution client: SyncEvolutionClient, SyncEvolution
Description: this is a just a descriptive string not used for matching.
GetServerTemplates is changed to add another "devices" parameter to identify
it is asking for templates for a list of "devices". Each device is a tuple
<matchstring (devicename), matchMode (server/client/all)>.
TemplateList as the return type, which is a list of class TemplateDescription
so that we can also return enough information for corresponding templates. This
list is sorted by the 3-tuple <finger, rank, name>.
Add MatchServerTemplates method which will iterating all templates inside the
folder and match against the input parameter and finally return a sorted
list of matched templates.
The atcually fuzzy match algorithm is based on a LCS (added in the following
commit).
Cmdline interface is changed accordingly:
--template ? is changed to --template ?[string], so that user use the former
case to match all templates for a tradiontial SyncML client and the latter case
to match templates related to an input string.
SyncConfig API is also renamed (Server -> Peer) because both server/client
configuration/template are handled.
The original configuration template (Funambol and ScheduleWorld) has been moved
to the new template structure (under servers), they also have a .template.ini
file added so that they can be matched and picked up. All templates for
supported servers still have built-in template support in the code as before.
Templates for SyncEvolution based server is also added.
Server side templates are added (Nokia default, Nokia_7210c and SyncEvolutionServer).
Add unit test for the new template match use case.
2010-01-19 08:01:05 +01:00
}
} else {
TemplateConfig templateConf ( sDir ) ;
2010-05-03 22:10:40 +02:00
if ( boost : : ends_with ( sDir , " ~ " ) | |
! templateConf . isTemplateConfig ( ) ) {
// ignore temporary files and files which do
// not contain a valid template
2010-05-03 17:47:18 +02:00
continue ;
}
2018-01-16 10:58:04 +01:00
for ( const auto & entry : peers ) {
2011-08-26 15:00:05 +02:00
std : : string fingerprint ( entry . getFingerprint ( ) ) ;
2011-08-29 16:12:46 +02:00
// peerName should be empty if no reliable device info is on hand.
std : : string peerName = entry . m_pnpInformation ? fingerprint : " " ;
int rank = templateConf . metaMatch ( entry . getFingerprint ( ) , entry . m_matchMode ) ;
2010-01-21 14:39:09 +01:00
if ( fuzzyMatch ) {
if ( rank > TemplateConfig : : NO_MATCH ) {
2018-01-16 17:17:34 +01:00
result . push_back ( std : : shared_ptr < TemplateDescription > (
2010-03-25 04:26:13 +01:00
new TemplateDescription ( templateConf . getTemplateId ( ) ,
templateConf . getDescription ( ) ,
rank ,
2011-08-29 16:12:46 +02:00
peerName ,
2010-03-25 04:26:13 +01:00
entry . m_deviceId ,
2011-08-29 16:12:46 +02:00
entry . m_deviceName ,
2010-03-25 04:26:13 +01:00
sDir ,
templateConf . getFingerprint ( ) ,
templateConf . getTemplateName ( )
)
) ) ;
2010-01-21 14:39:09 +01:00
}
} else if ( rank = = TemplateConfig : : BEST_MATCH ) {
2018-01-16 17:17:34 +01:00
result . push_back ( std : : shared_ptr < TemplateDescription > (
2010-03-25 04:26:13 +01:00
new TemplateDescription ( templateConf . getTemplateId ( ) ,
templateConf . getDescription ( ) ,
rank ,
2011-08-29 16:12:46 +02:00
peerName ,
2010-03-25 04:26:13 +01:00
entry . m_deviceId ,
2011-08-29 16:12:46 +02:00
entry . m_deviceName ,
2011-07-26 03:12:58 +02:00
sDir ,
2010-03-25 04:26:13 +01:00
templateConf . getFingerprint ( ) ,
templateConf . getTemplateName ( ) )
) ) ;
2010-01-21 14:39:09 +01:00
break ;
Configuration templates matching: match templates based on metadata
Introduced TemplateConfig to abstracting the template configuration structure,
the template metadata used for matching is also parsed here.
The fields introduced in the metadata are:
PeerIsClient: identify whether this is a server side configuration or a client
side configuration.
Fingerprint: the matching string for this template, it is a comma separated string
with each string modeled as: "Manufacture_Model". The first substring is also
used as the name to identify this template so that user can select the template
by this name.
eg:
Nokia 7210c: Nokia_7210c
SyncEvolution server: SyncEvolutionServer, SyncEvolution
ScheduleWorld: ScheduleWorld,default
SyncEvolution client: SyncEvolutionClient, SyncEvolution
Description: this is a just a descriptive string not used for matching.
GetServerTemplates is changed to add another "devices" parameter to identify
it is asking for templates for a list of "devices". Each device is a tuple
<matchstring (devicename), matchMode (server/client/all)>.
TemplateList as the return type, which is a list of class TemplateDescription
so that we can also return enough information for corresponding templates. This
list is sorted by the 3-tuple <finger, rank, name>.
Add MatchServerTemplates method which will iterating all templates inside the
folder and match against the input parameter and finally return a sorted
list of matched templates.
The atcually fuzzy match algorithm is based on a LCS (added in the following
commit).
Cmdline interface is changed accordingly:
--template ? is changed to --template ?[string], so that user use the former
case to match all templates for a tradiontial SyncML client and the latter case
to match templates related to an input string.
SyncConfig API is also renamed (Server -> Peer) because both server/client
configuration/template are handled.
The original configuration template (Funambol and ScheduleWorld) has been moved
to the new template structure (under servers), they also have a .template.ini
file added so that they can be matched and picked up. All templates for
supported servers still have built-in template support in the code as before.
Templates for SyncEvolution based server is also added.
Server side templates are added (Nokia default, Nokia_7210c and SyncEvolutionServer).
Add unit test for the new template match use case.
2010-01-19 08:01:05 +01:00
}
}
}
}
result . sort ( TemplateDescription : : compare_op ) ;
return result ;
}
2018-01-16 17:17:34 +01:00
std : : shared_ptr < SyncConfig > SyncConfig : : createPeerTemplate ( const string & server )
2008-03-19 15:35:22 +01:00
{
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
if ( server . empty ( ) ) {
// Empty template name => no such template. This check is
// necessary because otherwise we end up with SyncConfig(""),
// which is a configuration where peer-specific properties
// cannot be set, triggering an errror in config->setDevID().
2018-01-16 17:17:34 +01:00
return std : : shared_ptr < SyncConfig > ( ) ;
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
}
2009-04-08 16:32:05 +02:00
// case insensitive search for read-only file template config
Configuration templates matching: match templates based on metadata
Introduced TemplateConfig to abstracting the template configuration structure,
the template metadata used for matching is also parsed here.
The fields introduced in the metadata are:
PeerIsClient: identify whether this is a server side configuration or a client
side configuration.
Fingerprint: the matching string for this template, it is a comma separated string
with each string modeled as: "Manufacture_Model". The first substring is also
used as the name to identify this template so that user can select the template
by this name.
eg:
Nokia 7210c: Nokia_7210c
SyncEvolution server: SyncEvolutionServer, SyncEvolution
ScheduleWorld: ScheduleWorld,default
SyncEvolution client: SyncEvolutionClient, SyncEvolution
Description: this is a just a descriptive string not used for matching.
GetServerTemplates is changed to add another "devices" parameter to identify
it is asking for templates for a list of "devices". Each device is a tuple
<matchstring (devicename), matchMode (server/client/all)>.
TemplateList as the return type, which is a list of class TemplateDescription
so that we can also return enough information for corresponding templates. This
list is sorted by the 3-tuple <finger, rank, name>.
Add MatchServerTemplates method which will iterating all templates inside the
folder and match against the input parameter and finally return a sorted
list of matched templates.
The atcually fuzzy match algorithm is based on a LCS (added in the following
commit).
Cmdline interface is changed accordingly:
--template ? is changed to --template ?[string], so that user use the former
case to match all templates for a tradiontial SyncML client and the latter case
to match templates related to an input string.
SyncConfig API is also renamed (Server -> Peer) because both server/client
configuration/template are handled.
The original configuration template (Funambol and ScheduleWorld) has been moved
to the new template structure (under servers), they also have a .template.ini
file added so that they can be matched and picked up. All templates for
supported servers still have built-in template support in the code as before.
Templates for SyncEvolution based server is also added.
Server side templates are added (Nokia default, Nokia_7210c and SyncEvolutionServer).
Add unit test for the new template match use case.
2010-01-19 08:01:05 +01:00
string templateConfig ( SyncEvolutionTemplateDir ( ) ) ;
// before starting another fuzzy match process, first try to load the
// template directly taking the parameter as the path
configuration: removed builtin templates
The code for builtin templates had side effects, like always adding
all four standard sources to a template, even if the template itself
didn't have all of them defined. It also hid the problem that listing
templates didn't work for templates on disk.
Another benefit is that template files can be packaged separately. By
choosing the packages which are to be installed, a distributor of
SyncEvolution (like MeeGo) can choose which services to offer by
default.
Therefore this patch removes the "builtin templates" feature, which
was only useful in unusual use cases anyway (for example, single-binary
distribution).
Because there are no more default values for source properties, all
templates must specify the "backend" explicitly. syncevo-phone-config
was adapted accordingly, and also updated to use the current names of
the properties in the process.
As part of moving the templates into separate files, some of them
were cleaned up:
- Mobical: now points to Everdroid, its new name
- Google, Ovi: SSL verification is always enabled in the templates;
the workaround for old libsoup should no longer be
necessary for most users
- Google: renamed to "Google_Contacts", with "Google" as alias,
because there will be two Google templates soon
- Scheduleworld: use "server no longer in operation" instead of
an invalid URL
The finger print match had a special case for "default". The exact
intention of that is unknown. Perhaps it was meant to give that
template a boost when it wouldn't match the string that is getting
searched for at all.
But it had the effect that an exact match when searching for the
"default" template was not found and thus that template couldn't be
used in the command line after moving it from builtin to external.
Removed the complete check.
2011-05-18 14:11:54 +02:00
if ( server = = " none " ) {
// nothing to read from, just set some defaults below
} else if ( TemplateConfig : : isTemplateConfig ( server ) ) {
Configuration templates matching: match templates based on metadata
Introduced TemplateConfig to abstracting the template configuration structure,
the template metadata used for matching is also parsed here.
The fields introduced in the metadata are:
PeerIsClient: identify whether this is a server side configuration or a client
side configuration.
Fingerprint: the matching string for this template, it is a comma separated string
with each string modeled as: "Manufacture_Model". The first substring is also
used as the name to identify this template so that user can select the template
by this name.
eg:
Nokia 7210c: Nokia_7210c
SyncEvolution server: SyncEvolutionServer, SyncEvolution
ScheduleWorld: ScheduleWorld,default
SyncEvolution client: SyncEvolutionClient, SyncEvolution
Description: this is a just a descriptive string not used for matching.
GetServerTemplates is changed to add another "devices" parameter to identify
it is asking for templates for a list of "devices". Each device is a tuple
<matchstring (devicename), matchMode (server/client/all)>.
TemplateList as the return type, which is a list of class TemplateDescription
so that we can also return enough information for corresponding templates. This
list is sorted by the 3-tuple <finger, rank, name>.
Add MatchServerTemplates method which will iterating all templates inside the
folder and match against the input parameter and finally return a sorted
list of matched templates.
The atcually fuzzy match algorithm is based on a LCS (added in the following
commit).
Cmdline interface is changed accordingly:
--template ? is changed to --template ?[string], so that user use the former
case to match all templates for a tradiontial SyncML client and the latter case
to match templates related to an input string.
SyncConfig API is also renamed (Server -> Peer) because both server/client
configuration/template are handled.
The original configuration template (Funambol and ScheduleWorld) has been moved
to the new template structure (under servers), they also have a .template.ini
file added so that they can be matched and picked up. All templates for
supported servers still have built-in template support in the code as before.
Templates for SyncEvolution based server is also added.
Server side templates are added (Nokia default, Nokia_7210c and SyncEvolutionServer).
Add unit test for the new template match use case.
2010-01-19 08:01:05 +01:00
templateConfig = server ;
2009-04-17 14:09:17 +02:00
} else {
2010-01-21 14:39:09 +01:00
SyncConfig : : DeviceList devices ;
2010-02-23 05:06:05 +01:00
devices . push_back ( DeviceDescription ( " " , server , MATCH_ALL ) ) ;
2009-04-17 14:09:17 +02:00
templateConfig = " " ;
2010-01-21 14:39:09 +01:00
TemplateList templates = matchPeerTemplates ( devices , false ) ;
if ( ! templates . empty ( ) ) {
templateConfig = templates . front ( ) - > m_path ;
Configuration templates matching: match templates based on metadata
Introduced TemplateConfig to abstracting the template configuration structure,
the template metadata used for matching is also parsed here.
The fields introduced in the metadata are:
PeerIsClient: identify whether this is a server side configuration or a client
side configuration.
Fingerprint: the matching string for this template, it is a comma separated string
with each string modeled as: "Manufacture_Model". The first substring is also
used as the name to identify this template so that user can select the template
by this name.
eg:
Nokia 7210c: Nokia_7210c
SyncEvolution server: SyncEvolutionServer, SyncEvolution
ScheduleWorld: ScheduleWorld,default
SyncEvolution client: SyncEvolutionClient, SyncEvolution
Description: this is a just a descriptive string not used for matching.
GetServerTemplates is changed to add another "devices" parameter to identify
it is asking for templates for a list of "devices". Each device is a tuple
<matchstring (devicename), matchMode (server/client/all)>.
TemplateList as the return type, which is a list of class TemplateDescription
so that we can also return enough information for corresponding templates. This
list is sorted by the 3-tuple <finger, rank, name>.
Add MatchServerTemplates method which will iterating all templates inside the
folder and match against the input parameter and finally return a sorted
list of matched templates.
The atcually fuzzy match algorithm is based on a LCS (added in the following
commit).
Cmdline interface is changed accordingly:
--template ? is changed to --template ?[string], so that user use the former
case to match all templates for a tradiontial SyncML client and the latter case
to match templates related to an input string.
SyncConfig API is also renamed (Server -> Peer) because both server/client
configuration/template are handled.
The original configuration template (Funambol and ScheduleWorld) has been moved
to the new template structure (under servers), they also have a .template.ini
file added so that they can be matched and picked up. All templates for
supported servers still have built-in template support in the code as before.
Templates for SyncEvolution based server is also added.
Server side templates are added (Nokia default, Nokia_7210c and SyncEvolutionServer).
Add unit test for the new template match use case.
2010-01-19 08:01:05 +01:00
}
if ( templateConfig . empty ( ) ) {
configuration: removed builtin templates
The code for builtin templates had side effects, like always adding
all four standard sources to a template, even if the template itself
didn't have all of them defined. It also hid the problem that listing
templates didn't work for templates on disk.
Another benefit is that template files can be packaged separately. By
choosing the packages which are to be installed, a distributor of
SyncEvolution (like MeeGo) can choose which services to offer by
default.
Therefore this patch removes the "builtin templates" feature, which
was only useful in unusual use cases anyway (for example, single-binary
distribution).
Because there are no more default values for source properties, all
templates must specify the "backend" explicitly. syncevo-phone-config
was adapted accordingly, and also updated to use the current names of
the properties in the process.
As part of moving the templates into separate files, some of them
were cleaned up:
- Mobical: now points to Everdroid, its new name
- Google, Ovi: SSL verification is always enabled in the templates;
the workaround for old libsoup should no longer be
necessary for most users
- Google: renamed to "Google_Contacts", with "Google" as alias,
because there will be two Google templates soon
- Scheduleworld: use "server no longer in operation" instead of
an invalid URL
The finger print match had a special case for "default". The exact
intention of that is unknown. Perhaps it was meant to give that
template a boost when it wouldn't match the string that is getting
searched for at all.
But it had the effect that an exact match when searching for the
"default" template was not found and thus that template couldn't be
used in the command line after moving it from builtin to external.
Removed the complete check.
2011-05-18 14:11:54 +02:00
// return "not found"
2018-01-16 17:17:34 +01:00
return std : : shared_ptr < SyncConfig > ( ) ;
Configuration templates matching: match templates based on metadata
Introduced TemplateConfig to abstracting the template configuration structure,
the template metadata used for matching is also parsed here.
The fields introduced in the metadata are:
PeerIsClient: identify whether this is a server side configuration or a client
side configuration.
Fingerprint: the matching string for this template, it is a comma separated string
with each string modeled as: "Manufacture_Model". The first substring is also
used as the name to identify this template so that user can select the template
by this name.
eg:
Nokia 7210c: Nokia_7210c
SyncEvolution server: SyncEvolutionServer, SyncEvolution
ScheduleWorld: ScheduleWorld,default
SyncEvolution client: SyncEvolutionClient, SyncEvolution
Description: this is a just a descriptive string not used for matching.
GetServerTemplates is changed to add another "devices" parameter to identify
it is asking for templates for a list of "devices". Each device is a tuple
<matchstring (devicename), matchMode (server/client/all)>.
TemplateList as the return type, which is a list of class TemplateDescription
so that we can also return enough information for corresponding templates. This
list is sorted by the 3-tuple <finger, rank, name>.
Add MatchServerTemplates method which will iterating all templates inside the
folder and match against the input parameter and finally return a sorted
list of matched templates.
The atcually fuzzy match algorithm is based on a LCS (added in the following
commit).
Cmdline interface is changed accordingly:
--template ? is changed to --template ?[string], so that user use the former
case to match all templates for a tradiontial SyncML client and the latter case
to match templates related to an input string.
SyncConfig API is also renamed (Server -> Peer) because both server/client
configuration/template are handled.
The original configuration template (Funambol and ScheduleWorld) has been moved
to the new template structure (under servers), they also have a .template.ini
file added so that they can be matched and picked up. All templates for
supported servers still have built-in template support in the code as before.
Templates for SyncEvolution based server is also added.
Server side templates are added (Nokia default, Nokia_7210c and SyncEvolutionServer).
Add unit test for the new template match use case.
2010-01-19 08:01:05 +01:00
}
2009-04-07 20:33:18 +02:00
}
Configuration templates matching: match templates based on metadata
Introduced TemplateConfig to abstracting the template configuration structure,
the template metadata used for matching is also parsed here.
The fields introduced in the metadata are:
PeerIsClient: identify whether this is a server side configuration or a client
side configuration.
Fingerprint: the matching string for this template, it is a comma separated string
with each string modeled as: "Manufacture_Model". The first substring is also
used as the name to identify this template so that user can select the template
by this name.
eg:
Nokia 7210c: Nokia_7210c
SyncEvolution server: SyncEvolutionServer, SyncEvolution
ScheduleWorld: ScheduleWorld,default
SyncEvolution client: SyncEvolutionClient, SyncEvolution
Description: this is a just a descriptive string not used for matching.
GetServerTemplates is changed to add another "devices" parameter to identify
it is asking for templates for a list of "devices". Each device is a tuple
<matchstring (devicename), matchMode (server/client/all)>.
TemplateList as the return type, which is a list of class TemplateDescription
so that we can also return enough information for corresponding templates. This
list is sorted by the 3-tuple <finger, rank, name>.
Add MatchServerTemplates method which will iterating all templates inside the
folder and match against the input parameter and finally return a sorted
list of matched templates.
The atcually fuzzy match algorithm is based on a LCS (added in the following
commit).
Cmdline interface is changed accordingly:
--template ? is changed to --template ?[string], so that user use the former
case to match all templates for a tradiontial SyncML client and the latter case
to match templates related to an input string.
SyncConfig API is also renamed (Server -> Peer) because both server/client
configuration/template are handled.
The original configuration template (Funambol and ScheduleWorld) has been moved
to the new template structure (under servers), they also have a .template.ini
file added so that they can be matched and picked up. All templates for
supported servers still have built-in template support in the code as before.
Templates for SyncEvolution based server is also added.
Server side templates are added (Nokia default, Nokia_7210c and SyncEvolutionServer).
Add unit test for the new template match use case.
2010-01-19 08:01:05 +01:00
2018-01-16 17:17:34 +01:00
auto tree = std : : make_shared < SingleFileConfigTree > ( templateConfig ) ;
auto config = std : : make_shared < SyncConfig > ( server , tree ) ;
std : : shared_ptr < PersistentSyncSourceConfig > source ;
2008-03-19 15:35:22 +01:00
2009-04-07 20:33:18 +02:00
config - > setDefaults ( false ) ;
2010-02-19 16:13:43 +01:00
config - > setDevID ( string ( " syncevolution- " ) + UUID ( ) ) ;
2008-03-29 15:16:34 +01:00
2011-03-23 12:14:31 +01:00
// leave the rest empty for special "none" template
if ( server = = " none " ) {
return config ;
}
configuration: removed builtin templates
The code for builtin templates had side effects, like always adding
all four standard sources to a template, even if the template itself
didn't have all of them defined. It also hid the problem that listing
templates didn't work for templates on disk.
Another benefit is that template files can be packaged separately. By
choosing the packages which are to be installed, a distributor of
SyncEvolution (like MeeGo) can choose which services to offer by
default.
Therefore this patch removes the "builtin templates" feature, which
was only useful in unusual use cases anyway (for example, single-binary
distribution).
Because there are no more default values for source properties, all
templates must specify the "backend" explicitly. syncevo-phone-config
was adapted accordingly, and also updated to use the current names of
the properties in the process.
As part of moving the templates into separate files, some of them
were cleaned up:
- Mobical: now points to Everdroid, its new name
- Google, Ovi: SSL verification is always enabled in the templates;
the workaround for old libsoup should no longer be
necessary for most users
- Google: renamed to "Google_Contacts", with "Google" as alias,
because there will be two Google templates soon
- Scheduleworld: use "server no longer in operation" instead of
an invalid URL
The finger print match had a special case for "default". The exact
intention of that is unknown. Perhaps it was meant to give that
template a boost when it wouldn't match the string that is getting
searched for at all.
But it had the effect that an exact match when searching for the
"default" template was not found and thus that template couldn't be
used in the command line after moving it from builtin to external.
Removed the complete check.
2011-05-18 14:11:54 +02:00
// check for icon
if ( config - > getIconURI ( ) . empty ( ) ) {
string dirname , filename ;
splitPath ( templateConfig , dirname , filename ) ;
ReadDir dir ( getDirname ( dirname ) ) ;
2009-04-07 20:33:18 +02:00
configuration: removed builtin templates
The code for builtin templates had side effects, like always adding
all four standard sources to a template, even if the template itself
didn't have all of them defined. It also hid the problem that listing
templates didn't work for templates on disk.
Another benefit is that template files can be packaged separately. By
choosing the packages which are to be installed, a distributor of
SyncEvolution (like MeeGo) can choose which services to offer by
default.
Therefore this patch removes the "builtin templates" feature, which
was only useful in unusual use cases anyway (for example, single-binary
distribution).
Because there are no more default values for source properties, all
templates must specify the "backend" explicitly. syncevo-phone-config
was adapted accordingly, and also updated to use the current names of
the properties in the process.
As part of moving the templates into separate files, some of them
were cleaned up:
- Mobical: now points to Everdroid, its new name
- Google, Ovi: SSL verification is always enabled in the templates;
the workaround for old libsoup should no longer be
necessary for most users
- Google: renamed to "Google_Contacts", with "Google" as alias,
because there will be two Google templates soon
- Scheduleworld: use "server no longer in operation" instead of
an invalid URL
The finger print match had a special case for "default". The exact
intention of that is unknown. Perhaps it was meant to give that
template a boost when it wouldn't match the string that is getting
searched for at all.
But it had the effect that an exact match when searching for the
"default" template was not found and thus that template couldn't be
used in the command line after moving it from builtin to external.
Removed the complete check.
2011-05-18 14:11:54 +02:00
// remove last suffix, regardless what it is
size_t pos = filename . rfind ( ' . ' ) ;
if ( pos ! = filename . npos ) {
filename . resize ( pos ) ;
}
filename + = " -icon " ;
2010-05-03 17:47:18 +02:00
2018-01-16 10:58:04 +01:00
for ( const string & entry : dir ) {
configuration: removed builtin templates
The code for builtin templates had side effects, like always adding
all four standard sources to a template, even if the template itself
didn't have all of them defined. It also hid the problem that listing
templates didn't work for templates on disk.
Another benefit is that template files can be packaged separately. By
choosing the packages which are to be installed, a distributor of
SyncEvolution (like MeeGo) can choose which services to offer by
default.
Therefore this patch removes the "builtin templates" feature, which
was only useful in unusual use cases anyway (for example, single-binary
distribution).
Because there are no more default values for source properties, all
templates must specify the "backend" explicitly. syncevo-phone-config
was adapted accordingly, and also updated to use the current names of
the properties in the process.
As part of moving the templates into separate files, some of them
were cleaned up:
- Mobical: now points to Everdroid, its new name
- Google, Ovi: SSL verification is always enabled in the templates;
the workaround for old libsoup should no longer be
necessary for most users
- Google: renamed to "Google_Contacts", with "Google" as alias,
because there will be two Google templates soon
- Scheduleworld: use "server no longer in operation" instead of
an invalid URL
The finger print match had a special case for "default". The exact
intention of that is unknown. Perhaps it was meant to give that
template a boost when it wouldn't match the string that is getting
searched for at all.
But it had the effect that an exact match when searching for the
"default" template was not found and thus that template couldn't be
used in the command line after moving it from builtin to external.
Removed the complete check.
2011-05-18 14:11:54 +02:00
if ( boost : : istarts_with ( entry , filename ) ) {
config - > setIconURI ( " file:// " + dirname + " / " + entry ) ;
break ;
2009-04-07 20:33:18 +02:00
}
}
}
2011-11-17 14:30:15 +01:00
// "default" maps to SyncEvolution server template, which is not
// consumer ready. When used as "default" by the GTK sync UI,
// the UI expects the "consumer ready" flag to be set. Do that
// here. Also unset the peer name, because otherwise it shows
// up in the UI.
if ( server = = " default " ) {
config - > setConsumerReady ( true ) ;
2012-06-05 12:57:33 +02:00
config - > setUserPeerName ( InitStateString ( ) ) ;
2011-11-17 14:30:15 +01:00
}
2008-03-19 15:35:22 +01:00
return config ;
}
2008-03-18 22:45:34 +01:00
2009-10-06 17:22:47 +02:00
bool SyncConfig : : exists ( ) const
2008-03-06 23:23:13 +01:00
{
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
return m_peerPath . empty ( ) ?
m_contextNode - > exists ( ) :
m_peerNode - > exists ( ) ;
2008-03-06 23:23:13 +01:00
}
2011-01-10 15:56:53 +01:00
bool SyncConfig : : exists ( ConfigLevel level ) const
{
switch ( level ) {
case CONFIG_LEVEL_ROOT :
return m_globalNode - > exists ( ) ;
break ;
case CONFIG_LEVEL_CONTEXT :
return m_contextNode - > exists ( ) ;
break ;
case CONFIG_LEVEL_PEER :
return m_peerNode - > exists ( ) ;
break ;
default :
return false ;
}
}
2010-10-25 10:19:54 +02:00
string SyncConfig : : getContextName ( ) const
{
string peer , context ;
splitConfigString ( getConfigName ( ) , peer , context ) ;
return string ( " @ " ) + context ;
}
2011-02-01 16:29:45 +01:00
string SyncConfig : : getPeerName ( ) const
{
string peer , context ;
splitConfigString ( getConfigName ( ) , peer , context ) ;
return peer ;
}
2011-02-01 21:33:31 +01:00
list < string > SyncConfig : : getPeers ( ) const
{
list < string > res ;
if ( ! hasPeerProperties ( ) ) {
2013-09-06 10:30:30 +02:00
std : : string rootPath = getRootPath ( ) ;
if ( ! rootPath . empty ( ) ) {
FileConfigTree tree ( getRootPath ( ) , SHARED_LAYOUT ) ;
res = tree . getChildren ( " peers " ) ;
}
2011-02-01 21:33:31 +01:00
}
return res ;
}
2012-03-06 13:34:51 +01:00
void SyncConfig : : preFlush ( UserInterface & ui )
2009-09-21 10:07:05 +02:00
{
/* Iterator over all sync global and source properties
* one by one and check whether they need to save password */
/* save password in the global config node */
ConfigPropertyRegistry & registry = getRegistry ( ) ;
2018-01-16 10:58:04 +01:00
for ( const ConfigProperty * prop : registry ) {
2013-07-26 11:56:18 +02:00
prop - > savePassword ( ui , * this ) ;
2009-09-21 10:07:05 +02:00
}
/** grep each source and save their password */
list < string > configuredSources = getSyncSources ( ) ;
2018-01-16 10:58:04 +01:00
for ( const string & sourceName : configuredSources ) {
2018-01-16 17:17:34 +01:00
//std::shared_ptr<SyncSourceConfig> sc = getSyncSourceConfig(sourceName);
2009-09-21 10:07:05 +02:00
ConfigPropertyRegistry & registry = SyncSourceConfig : : getRegistry ( ) ;
SyncSourceNodes sourceNodes = getSyncSourceNodes ( sourceName ) ;
2018-01-16 10:58:04 +01:00
for ( const ConfigProperty * prop : registry ) {
2013-07-26 11:56:18 +02:00
prop - > savePassword ( ui , * this , sourceName ) ;
2009-09-21 10:07:05 +02:00
}
}
}
2009-10-06 17:22:47 +02:00
void SyncConfig : : flush ( )
2008-03-06 23:23:13 +01:00
{
2012-12-04 15:38:03 +01:00
if ( ! isEphemeral ( ) ) {
2013-09-06 10:30:30 +02:00
if ( m_fileTree & & m_layout = = SHARED_LAYOUT & & ! hasPeerProperties ( ) ) {
// Ensure that "peers" directory exists for new-style
// configs. It would not get created when flushing nodes
// for pure context configs otherwise (it's empty), and we
// need it to detect new-syle configs.
mkdir_p ( m_fileTree - > getRoot ( ) + " / " + m_contextPath + " /peers " ) ;
}
2012-12-04 15:38:03 +01:00
m_tree - > flush ( ) ;
}
2008-03-06 23:23:13 +01:00
}
2009-10-06 17:22:47 +02:00
void SyncConfig : : remove ( )
2009-04-15 14:02:09 +02:00
{
2018-01-16 17:17:34 +01:00
std : : shared_ptr < ConfigTree > tree = m_tree ;
2009-11-20 13:23:15 +01:00
// stop using the config nodes, they might get removed now
makeVolatile ( ) ;
tree - > remove ( m_peerPath . empty ( ) ?
m_contextPath :
m_peerPath ) ;
2009-04-15 14:02:09 +02:00
}
2018-01-16 17:17:34 +01:00
std : : shared_ptr < PersistentSyncSourceConfig > SyncConfig : : getSyncSourceConfig ( const string & name )
2008-03-06 23:23:13 +01:00
{
SyncSourceNodes nodes = getSyncSourceNodes ( name ) ;
2018-01-16 17:17:34 +01:00
return std : : make_shared < PersistentSyncSourceConfig > ( name , nodes ) ;
2008-03-06 23:23:13 +01:00
}
2009-10-06 17:22:47 +02:00
list < string > SyncConfig : : getSyncSources ( ) const
2008-03-06 23:23:13 +01:00
{
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
// Return *all* sources configured in this context,
// not just those configured for the peer. This
// is necessary so that sources created for some other peer
// show up for the current one, to prevent overwriting
// existing properties unintentionally.
2009-12-02 05:38:50 +01:00
// Returned sources are an union of:
// 1. contextpath/sources
// 2. peers/[one-peer]/sources
// 3. sources in source filter
2012-05-02 19:41:35 +02:00
set < string > sources ;
list < string > sourceList ;
2009-12-02 05:38:50 +01:00
if ( m_layout = = SHARED_LAYOUT ) {
// get sources in context
2012-05-02 19:41:35 +02:00
sourceList = m_tree - > getChildren ( m_contextPath + " /sources " ) ;
sources . insert ( sourceList . begin ( ) , sourceList . end ( ) ) ;
// get sources from peer if it's not empty and merge into
// full set of sources
2009-12-02 05:38:50 +01:00
if ( ! m_peerPath . empty ( ) ) {
2012-05-02 19:41:35 +02:00
sourceList = m_tree - > getChildren ( m_peerPath + " /sources " ) ;
sources . insert ( sourceList . begin ( ) , sourceList . end ( ) ) ;
2009-12-02 05:38:50 +01:00
}
} else {
// get sources from peer
2012-05-02 19:41:35 +02:00
sourceList = m_tree - > getChildren ( m_peerPath +
( m_layout = = SYNC4J_LAYOUT ?
" /spds/sources " :
" /sources " ) ) ;
sources . insert ( sourceList . begin ( ) , sourceList . end ( ) ) ;
2009-12-02 05:38:50 +01:00
}
// get sources from filter and union them into returned sources
2018-01-16 10:58:04 +01:00
for ( const auto & value : m_sourceFilters ) {
2011-01-25 11:11:53 +01:00
if ( value . first . empty ( ) ) {
// ignore filter for all sources
continue ;
}
2012-05-02 19:41:35 +02:00
sources . insert ( value . first ) ;
2009-12-02 05:38:50 +01:00
}
2012-05-02 19:41:35 +02:00
// Convert back to simple list. As a nice side-effect of
// temporarily using a set, the final list is sorted.
return list < string > ( sources . begin ( ) , sources . end ( ) ) ;
2008-03-06 23:23:13 +01:00
}
2009-10-06 17:22:47 +02:00
SyncSourceNodes SyncConfig : : getSyncSourceNodes ( const string & name ,
2009-11-13 14:52:00 +01:00
const string & changeId )
2008-03-06 23:23:13 +01:00
{
2010-10-22 11:36:08 +02:00
if ( m_nodeCache . find ( name ) ! = m_nodeCache . end ( ) ) {
// reuse existing set of nodes
return m_nodeCache [ name ] ;
}
2009-11-13 14:52:00 +01:00
/** shared source properties */
2018-01-16 17:17:34 +01:00
std : : shared_ptr < FilterConfigNode > sharedNode ;
2009-11-13 14:52:00 +01:00
/** per-peer source properties */
2018-01-16 17:17:34 +01:00
std : : shared_ptr < FilterConfigNode > peerNode ;
2009-11-13 14:52:00 +01:00
/** per-peer internal properties and meta data */
2018-01-16 17:17:34 +01:00
std : : shared_ptr < ConfigNode > hiddenPeerNode ,
2009-09-29 22:41:06 +02:00
serverNode ,
2008-03-06 23:23:13 +01:00
trackingNode ;
2010-03-04 17:50:01 +01:00
string cacheDir ;
2008-03-06 23:23:13 +01:00
2009-04-08 16:32:05 +02:00
// store configs lower case even if the UI uses mixed case
string lower = name ;
boost : : to_lower ( lower ) ;
2008-03-06 23:23:13 +01:00
2018-01-16 17:17:34 +01:00
std : : shared_ptr < ConfigNode > node ;
2009-11-13 14:52:00 +01:00
string sharedPath , peerPath ;
switch ( m_layout ) {
case SYNC4J_LAYOUT :
peerPath = m_peerPath + " /spds/sources/ " + lower ;
break ;
case HTTP_SERVER_LAYOUT :
peerPath = m_peerPath + " /sources/ " + lower ;
break ;
case SHARED_LAYOUT :
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
if ( ! m_peerPath . empty ( ) ) {
peerPath = m_peerPath + " /sources/ " + lower ;
}
2009-11-13 14:52:00 +01:00
sharedPath = m_contextPath + string ( " /sources/ " ) + lower ;
break ;
2009-09-14 21:54:43 +02:00
}
2008-03-06 23:23:13 +01:00
config: replaced overloaded "type" with "backend/databaseFormat/syncFormat/forceSyncFormat" (BMC #1023)
The meaning of "type" was horribly complex and had effects on the
backend and the peer. It was impossible to specify the sync format to
be used for a specific peer independently of the local backend and its
format, so adding a peer to a context broke the context configuration
(BMC #1023).
This is now fixed by splitting "type" into four independent properties:
- backend = plugin which interfaces with the data
- databaseFormat = data format used inside backend, only relevant for file backend
- syncFormat = data format preferred when talking to peer
- forceSyncFormat = disable format auto-negotiation, use preferred format
With that split, it is now possible to specify the format in which the
file backend stores items independently of the format in which they
are exchanged with the peer.
Old configurations with "type" can still be read. The values specified
inside it are transparently mapped to the new properties. Command line
and D-Bus API users will only see the new properties.
The command line tool still accepts "type" as an alias for the four new
properties. Using that has the same disadvantage as before: it will modify
the context even if only modifying the peer was intended.
The D-Bus API accepts only the new properties. Clients using "type"
must be adapted to the new property names. Clients not using that
continue to run unchanged.
Writing into the configuration requires a migration of the peer config
*and* the context in which it is defined. That is necessary because
the new semantic (independent database format) cannot be stored in the
old format. The migration is handled by rewriting first the context,
then all peers defined inside it.
Other user-visible changes:
- updated help texts
- the canonical "backend" value for the file backend is just "file"
instead of the long "Files in one directory", which is now an alias
(used to be the other way around); done because "type = file"
was expanded to the long name, which was a bit unexpected and showed
how unintuitive the long name is
Internal changes:
- getMimeVersion() is still present, although it hasn't been used
for a long time; FileSyncSource::getMimeVersion() now derives
the version from the supported Mime types, in case that the
function will be needed again in the future
- setSourceType() with string as argument was replaced with one
taking a SourceType instance; to emulate the old behavior if
desired, construct SourceType from an old-style string
- ConfigProperty methods need to be virtual so that derived classes
like SourceBackendConfigProperty can generate content at runtime
(a recent commit broke that feature)
- File templates were stripped down to the essential properties,
with "type" replaced by the per-peer "syncFormat". "type" would
still have been accepted (so it is not necessary to adapt
syncevo-phone-config right away), but has the original
disadvantage of modifying "backend" and "databaseFormat".
2011-02-03 12:17:24 +01:00
// Compatibility mode for reading configs which have "type" instead
// of "backend/databaseFormat/syncFormat/forceSyncFormat": determine
// the new values based on the old property, then inject the new
// values into the SyncSourceNodes by adding an intermediate layer
// of FilterConfigNodes. The top FilterConfigNode layer is the one
// which might get modified, the one underneath remains hidden and
// thus preserves the new values even if the caller does a setFilter().
bool compatMode = getConfigVersion ( CONFIG_LEVEL_CONTEXT , CONFIG_CUR_VERSION ) < 1 ;
SourceType sourceType ;
if ( compatMode ) {
node = m_tree - > open ( peerPath . empty ( ) ? sharedPath : peerPath , ConfigTree : : visible ) ;
string type ;
if ( node - > getProperty ( " type " , type ) ) {
sourceType = SourceType ( type ) ;
} else {
// not set: avoid compatibility mode
compatMode = false ;
}
}
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
if ( peerPath . empty ( ) ) {
node . reset ( new DevNullConfigNode ( m_contextPath + " without peer configuration " ) ) ;
2013-09-09 10:32:12 +02:00
peerNode = ConfigCache : : singleton ( ) . createNode ( node ) ;
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
hiddenPeerNode =
trackingNode =
serverNode = node ;
} else {
2010-03-04 17:50:01 +01:00
// Here we assume that m_tree is a FileConfigTree. Otherwise getRootPath()
2013-09-06 10:30:30 +02:00
// will not point into a normal file system. We fall back to not allowing
// the usage of a cache dir by using /dev/null in that case.
std : : string rootPath = getRootPath ( ) ;
if ( rootPath . empty ( ) ) {
cacheDir = " /dev/null " ;
} else {
cacheDir = rootPath + " / " + peerPath + " /.cache " ;
}
2010-03-04 17:50:01 +01:00
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
node = m_tree - > open ( peerPath , ConfigTree : : visible ) ;
config: replaced overloaded "type" with "backend/databaseFormat/syncFormat/forceSyncFormat" (BMC #1023)
The meaning of "type" was horribly complex and had effects on the
backend and the peer. It was impossible to specify the sync format to
be used for a specific peer independently of the local backend and its
format, so adding a peer to a context broke the context configuration
(BMC #1023).
This is now fixed by splitting "type" into four independent properties:
- backend = plugin which interfaces with the data
- databaseFormat = data format used inside backend, only relevant for file backend
- syncFormat = data format preferred when talking to peer
- forceSyncFormat = disable format auto-negotiation, use preferred format
With that split, it is now possible to specify the format in which the
file backend stores items independently of the format in which they
are exchanged with the peer.
Old configurations with "type" can still be read. The values specified
inside it are transparently mapped to the new properties. Command line
and D-Bus API users will only see the new properties.
The command line tool still accepts "type" as an alias for the four new
properties. Using that has the same disadvantage as before: it will modify
the context even if only modifying the peer was intended.
The D-Bus API accepts only the new properties. Clients using "type"
must be adapted to the new property names. Clients not using that
continue to run unchanged.
Writing into the configuration requires a migration of the peer config
*and* the context in which it is defined. That is necessary because
the new semantic (independent database format) cannot be stored in the
old format. The migration is handled by rewriting first the context,
then all peers defined inside it.
Other user-visible changes:
- updated help texts
- the canonical "backend" value for the file backend is just "file"
instead of the long "Files in one directory", which is now an alias
(used to be the other way around); done because "type = file"
was expanded to the long name, which was a bit unexpected and showed
how unintuitive the long name is
Internal changes:
- getMimeVersion() is still present, although it hasn't been used
for a long time; FileSyncSource::getMimeVersion() now derives
the version from the supported Mime types, in case that the
function will be needed again in the future
- setSourceType() with string as argument was replaced with one
taking a SourceType instance; to emulate the old behavior if
desired, construct SourceType from an old-style string
- ConfigProperty methods need to be virtual so that derived classes
like SourceBackendConfigProperty can generate content at runtime
(a recent commit broke that feature)
- File templates were stripped down to the essential properties,
with "type" replaced by the per-peer "syncFormat". "type" would
still have been accepted (so it is not necessary to adapt
syncevo-phone-config right away), but has the original
disadvantage of modifying "backend" and "databaseFormat".
2011-02-03 12:17:24 +01:00
if ( compatMode ) {
2018-01-16 17:17:34 +01:00
auto compat = std : : make_shared < FilterConfigNode > ( node ) ;
2012-06-05 12:57:33 +02:00
compat - > addFilter ( " syncFormat " ,
InitStateString ( sourceType . m_format , ! sourceType . m_format . empty ( ) ) ) ;
compat - > addFilter ( " forceSyncFormat " ,
sourceType . m_forceFormat ?
InitStateString ( " 1 " , true ) :
InitStateString ( " 0 " , false ) ) ;
config: replaced overloaded "type" with "backend/databaseFormat/syncFormat/forceSyncFormat" (BMC #1023)
The meaning of "type" was horribly complex and had effects on the
backend and the peer. It was impossible to specify the sync format to
be used for a specific peer independently of the local backend and its
format, so adding a peer to a context broke the context configuration
(BMC #1023).
This is now fixed by splitting "type" into four independent properties:
- backend = plugin which interfaces with the data
- databaseFormat = data format used inside backend, only relevant for file backend
- syncFormat = data format preferred when talking to peer
- forceSyncFormat = disable format auto-negotiation, use preferred format
With that split, it is now possible to specify the format in which the
file backend stores items independently of the format in which they
are exchanged with the peer.
Old configurations with "type" can still be read. The values specified
inside it are transparently mapped to the new properties. Command line
and D-Bus API users will only see the new properties.
The command line tool still accepts "type" as an alias for the four new
properties. Using that has the same disadvantage as before: it will modify
the context even if only modifying the peer was intended.
The D-Bus API accepts only the new properties. Clients using "type"
must be adapted to the new property names. Clients not using that
continue to run unchanged.
Writing into the configuration requires a migration of the peer config
*and* the context in which it is defined. That is necessary because
the new semantic (independent database format) cannot be stored in the
old format. The migration is handled by rewriting first the context,
then all peers defined inside it.
Other user-visible changes:
- updated help texts
- the canonical "backend" value for the file backend is just "file"
instead of the long "Files in one directory", which is now an alias
(used to be the other way around); done because "type = file"
was expanded to the long name, which was a bit unexpected and showed
how unintuitive the long name is
Internal changes:
- getMimeVersion() is still present, although it hasn't been used
for a long time; FileSyncSource::getMimeVersion() now derives
the version from the supported Mime types, in case that the
function will be needed again in the future
- setSourceType() with string as argument was replaced with one
taking a SourceType instance; to emulate the old behavior if
desired, construct SourceType from an old-style string
- ConfigProperty methods need to be virtual so that derived classes
like SourceBackendConfigProperty can generate content at runtime
(a recent commit broke that feature)
- File templates were stripped down to the essential properties,
with "type" replaced by the per-peer "syncFormat". "type" would
still have been accepted (so it is not necessary to adapt
syncevo-phone-config right away), but has the original
disadvantage of modifying "backend" and "databaseFormat".
2011-02-03 12:17:24 +01:00
if ( sharedPath . empty ( ) ) {
2012-06-05 12:57:33 +02:00
compat - > addFilter ( " databaseFormat " ,
InitStateString ( sourceType . m_localFormat , ! sourceType . m_localFormat . empty ( ) ) ) ;
compat - > addFilter ( " backend " ,
InitStateString ( sourceType . m_backend , ! sourceType . m_backend . empty ( ) ) ) ;
config: replaced overloaded "type" with "backend/databaseFormat/syncFormat/forceSyncFormat" (BMC #1023)
The meaning of "type" was horribly complex and had effects on the
backend and the peer. It was impossible to specify the sync format to
be used for a specific peer independently of the local backend and its
format, so adding a peer to a context broke the context configuration
(BMC #1023).
This is now fixed by splitting "type" into four independent properties:
- backend = plugin which interfaces with the data
- databaseFormat = data format used inside backend, only relevant for file backend
- syncFormat = data format preferred when talking to peer
- forceSyncFormat = disable format auto-negotiation, use preferred format
With that split, it is now possible to specify the format in which the
file backend stores items independently of the format in which they
are exchanged with the peer.
Old configurations with "type" can still be read. The values specified
inside it are transparently mapped to the new properties. Command line
and D-Bus API users will only see the new properties.
The command line tool still accepts "type" as an alias for the four new
properties. Using that has the same disadvantage as before: it will modify
the context even if only modifying the peer was intended.
The D-Bus API accepts only the new properties. Clients using "type"
must be adapted to the new property names. Clients not using that
continue to run unchanged.
Writing into the configuration requires a migration of the peer config
*and* the context in which it is defined. That is necessary because
the new semantic (independent database format) cannot be stored in the
old format. The migration is handled by rewriting first the context,
then all peers defined inside it.
Other user-visible changes:
- updated help texts
- the canonical "backend" value for the file backend is just "file"
instead of the long "Files in one directory", which is now an alias
(used to be the other way around); done because "type = file"
was expanded to the long name, which was a bit unexpected and showed
how unintuitive the long name is
Internal changes:
- getMimeVersion() is still present, although it hasn't been used
for a long time; FileSyncSource::getMimeVersion() now derives
the version from the supported Mime types, in case that the
function will be needed again in the future
- setSourceType() with string as argument was replaced with one
taking a SourceType instance; to emulate the old behavior if
desired, construct SourceType from an old-style string
- ConfigProperty methods need to be virtual so that derived classes
like SourceBackendConfigProperty can generate content at runtime
(a recent commit broke that feature)
- File templates were stripped down to the essential properties,
with "type" replaced by the per-peer "syncFormat". "type" would
still have been accepted (so it is not necessary to adapt
syncevo-phone-config right away), but has the original
disadvantage of modifying "backend" and "databaseFormat".
2011-02-03 12:17:24 +01:00
}
node = compat ;
}
2013-09-09 10:32:12 +02:00
peerNode = ConfigCache : : singleton ( ) . createNode ( node , m_sourceFilters . createSourceFilter ( name ) ) ;
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
hiddenPeerNode = m_tree - > open ( peerPath , ConfigTree : : hidden ) ;
trackingNode = m_tree - > open ( peerPath , ConfigTree : : other , changeId ) ;
serverNode = m_tree - > open ( peerPath , ConfigTree : : server , changeId ) ;
2009-11-13 14:52:00 +01:00
}
2012-12-04 15:38:03 +01:00
if ( isEphemeral ( ) ) {
// Throw away meta data.
trackingNode . reset ( new VolatileConfigNode ) ;
hiddenPeerNode . reset ( new VolatileConfigNode ) ;
serverNode . reset ( new VolatileConfigNode ) ;
} else if ( ! m_redirectPeerRootPath . empty ( ) ) {
2010-12-09 12:23:35 +01:00
// Local sync: overwrite per-peer nodes with nodes inside the
// parents tree. Otherwise different configs syncing locally
// against the same context end up sharing .internal.ini and
// .other.ini files inside that context.
string path = m_redirectPeerRootPath + " /sources/ " + lower ;
2012-06-05 10:27:29 +02:00
trackingNode . reset ( new IniHashConfigNode ( path ,
" .other.ini " ,
false ) ) ;
2010-12-09 12:23:35 +01:00
trackingNode = m_tree - > add ( path + " /.other.ini " , trackingNode ) ;
if ( peerPath . empty ( ) ) {
hiddenPeerNode = peerNode ;
2014-01-07 10:53:41 +01:00
} else {
2018-01-16 17:17:34 +01:00
hiddenPeerNode = std : : static_pointer_cast < FilterConfigNode > ( m_tree - > add ( path + " /.internal.ini " , peerNode ) ) ;
2010-12-09 12:23:35 +01:00
}
}
2009-11-13 14:52:00 +01:00
if ( sharedPath . empty ( ) ) {
sharedNode = peerNode ;
} else {
node = m_tree - > open ( sharedPath , ConfigTree : : visible ) ;
config: replaced overloaded "type" with "backend/databaseFormat/syncFormat/forceSyncFormat" (BMC #1023)
The meaning of "type" was horribly complex and had effects on the
backend and the peer. It was impossible to specify the sync format to
be used for a specific peer independently of the local backend and its
format, so adding a peer to a context broke the context configuration
(BMC #1023).
This is now fixed by splitting "type" into four independent properties:
- backend = plugin which interfaces with the data
- databaseFormat = data format used inside backend, only relevant for file backend
- syncFormat = data format preferred when talking to peer
- forceSyncFormat = disable format auto-negotiation, use preferred format
With that split, it is now possible to specify the format in which the
file backend stores items independently of the format in which they
are exchanged with the peer.
Old configurations with "type" can still be read. The values specified
inside it are transparently mapped to the new properties. Command line
and D-Bus API users will only see the new properties.
The command line tool still accepts "type" as an alias for the four new
properties. Using that has the same disadvantage as before: it will modify
the context even if only modifying the peer was intended.
The D-Bus API accepts only the new properties. Clients using "type"
must be adapted to the new property names. Clients not using that
continue to run unchanged.
Writing into the configuration requires a migration of the peer config
*and* the context in which it is defined. That is necessary because
the new semantic (independent database format) cannot be stored in the
old format. The migration is handled by rewriting first the context,
then all peers defined inside it.
Other user-visible changes:
- updated help texts
- the canonical "backend" value for the file backend is just "file"
instead of the long "Files in one directory", which is now an alias
(used to be the other way around); done because "type = file"
was expanded to the long name, which was a bit unexpected and showed
how unintuitive the long name is
Internal changes:
- getMimeVersion() is still present, although it hasn't been used
for a long time; FileSyncSource::getMimeVersion() now derives
the version from the supported Mime types, in case that the
function will be needed again in the future
- setSourceType() with string as argument was replaced with one
taking a SourceType instance; to emulate the old behavior if
desired, construct SourceType from an old-style string
- ConfigProperty methods need to be virtual so that derived classes
like SourceBackendConfigProperty can generate content at runtime
(a recent commit broke that feature)
- File templates were stripped down to the essential properties,
with "type" replaced by the per-peer "syncFormat". "type" would
still have been accepted (so it is not necessary to adapt
syncevo-phone-config right away), but has the original
disadvantage of modifying "backend" and "databaseFormat".
2011-02-03 12:17:24 +01:00
if ( compatMode ) {
2018-01-16 17:17:34 +01:00
auto compat = std : : make_shared < FilterConfigNode > ( node ) ;
2012-06-05 12:57:33 +02:00
compat - > addFilter ( " databaseFormat " ,
InitStateString ( sourceType . m_localFormat , ! sourceType . m_localFormat . empty ( ) ) ) ;
compat - > addFilter ( " backend " ,
InitStateString ( sourceType . m_backend , ! sourceType . m_backend . empty ( ) ) ) ;
config: replaced overloaded "type" with "backend/databaseFormat/syncFormat/forceSyncFormat" (BMC #1023)
The meaning of "type" was horribly complex and had effects on the
backend and the peer. It was impossible to specify the sync format to
be used for a specific peer independently of the local backend and its
format, so adding a peer to a context broke the context configuration
(BMC #1023).
This is now fixed by splitting "type" into four independent properties:
- backend = plugin which interfaces with the data
- databaseFormat = data format used inside backend, only relevant for file backend
- syncFormat = data format preferred when talking to peer
- forceSyncFormat = disable format auto-negotiation, use preferred format
With that split, it is now possible to specify the format in which the
file backend stores items independently of the format in which they
are exchanged with the peer.
Old configurations with "type" can still be read. The values specified
inside it are transparently mapped to the new properties. Command line
and D-Bus API users will only see the new properties.
The command line tool still accepts "type" as an alias for the four new
properties. Using that has the same disadvantage as before: it will modify
the context even if only modifying the peer was intended.
The D-Bus API accepts only the new properties. Clients using "type"
must be adapted to the new property names. Clients not using that
continue to run unchanged.
Writing into the configuration requires a migration of the peer config
*and* the context in which it is defined. That is necessary because
the new semantic (independent database format) cannot be stored in the
old format. The migration is handled by rewriting first the context,
then all peers defined inside it.
Other user-visible changes:
- updated help texts
- the canonical "backend" value for the file backend is just "file"
instead of the long "Files in one directory", which is now an alias
(used to be the other way around); done because "type = file"
was expanded to the long name, which was a bit unexpected and showed
how unintuitive the long name is
Internal changes:
- getMimeVersion() is still present, although it hasn't been used
for a long time; FileSyncSource::getMimeVersion() now derives
the version from the supported Mime types, in case that the
function will be needed again in the future
- setSourceType() with string as argument was replaced with one
taking a SourceType instance; to emulate the old behavior if
desired, construct SourceType from an old-style string
- ConfigProperty methods need to be virtual so that derived classes
like SourceBackendConfigProperty can generate content at runtime
(a recent commit broke that feature)
- File templates were stripped down to the essential properties,
with "type" replaced by the per-peer "syncFormat". "type" would
still have been accepted (so it is not necessary to adapt
syncevo-phone-config right away), but has the original
disadvantage of modifying "backend" and "databaseFormat".
2011-02-03 12:17:24 +01:00
node = compat ;
}
2013-09-09 10:32:12 +02:00
sharedNode = ConfigCache : : singleton ( ) . createNode ( node , m_sourceFilters . createSourceFilter ( name ) ) ;
2009-11-13 14:52:00 +01:00
}
2010-10-22 11:36:08 +02:00
SyncSourceNodes nodes ( ! peerPath . empty ( ) , sharedNode , peerNode , hiddenPeerNode , trackingNode , serverNode , cacheDir ) ;
m_nodeCache . insert ( make_pair ( name , nodes ) ) ;
return nodes ;
2008-03-06 23:23:13 +01:00
}
2009-10-06 17:22:47 +02:00
ConstSyncSourceNodes SyncConfig : : getSyncSourceNodes ( const string & name ,
2009-11-13 14:52:00 +01:00
const string & changeId ) const
2008-03-20 23:05:10 +01:00
{
2009-10-06 17:22:47 +02:00
return const_cast < SyncConfig * > ( this ) - > getSyncSourceNodes ( name , changeId ) ;
2008-03-20 23:05:10 +01:00
}
2010-06-16 13:51:50 +02:00
SyncSourceNodes SyncConfig : : getSyncSourceNodesNoTracking ( const string & name )
{
SyncSourceNodes nodes = getSyncSourceNodes ( name ) ;
2018-01-16 17:17:34 +01:00
auto dummy = std : : make_shared < VolatileConfigNode > ( ) ;
2010-06-16 13:51:50 +02:00
return SyncSourceNodes ( nodes . m_havePeerNode ,
nodes . m_sharedNode ,
nodes . m_peerNode ,
nodes . m_hiddenPeerNode ,
dummy ,
nodes . m_serverNode ,
nodes . m_cacheDir ) ;
}
2008-03-06 23:23:13 +01:00
static ConfigProperty syncPropSyncURL ( " syncURL " ,
OBEX Client Transport: in-process OBEX client (binding over Bluetooth, #5188)
Outgoing OBEX connection implementation, only binds over Bluetooth now.
Integrates with gmainloop so that the opertaions in the transport will not
block the whole application.
It uses Bluetooth sdp to automatically discovery the corresponding service
channel providing SyncML service; the process is asynchronous. Callback
sdp_source_cb and sdp_callback are used for this purpose. sdp_source_cb is a
GIOChannel watch event callback which poll the underlying sdp socket, the
sdp_callback is invoked by Bluez during processing sdp packets.
Callback obex_fd_source and obex_callback are related to the OBEX processing
(Connect, Put, Get, Disconnect). obex_fd_source is a GIOChannel event source
callback which poll the underlying OBEX interface, the obex_callback is
invoked by libopenobex when it needs to delivering events to the application.
Connect is splited by several steps, see CONNECT_STATUS for more detail.
Disconnect will be invoked when shutDown is called or processing in
obex_fd_source_cb is failed, timeout occurs or user suspention. It will first
try to send a "Disconnect" command to server and waiting for response. If
such opertaion is failed it will disconnect anyway. It is important to call
wait after shutdown to ensure the transport is properly cleaned up.
Each callback function is protected by a "Try-catch" block to ensure no
exception is thrown in the C stack. This is important otherwise the application
will abort if an exception is really thrown.
Using several smart pointers to avoid potential resource leak. After initialized
the resource is held by ObexTransportAgent. Copy the smart pointer to the local
stack entering a function and return to ObexTransportAgent if the whole
process is correct and we want to continue. First, it ensures the resource is
released at least during ObexTransportAgent destructing; Second, it can also
try to release the resource as early as possible. For example cxxptr<ObexEvent>
will release the resource during each wait() so that the underlying poll will
not be processed if no transport activity is expected by the application.
"SyncURL" is used consistently for the address of the remote peer to
contact with.
2009-11-13 06:13:12 +01:00
" Identifies how to contact the peer, \n "
2011-10-19 17:15:50 +02:00
" best explained with some examples. \n \n "
" HTTP(S) SyncML servers:: \n \n "
2014-07-28 15:29:41 +02:00
" http://example.com/sync \n \n "
2009-11-17 07:37:14 +01:00
" OBEX over Bluetooth uses the MAC address, with \n "
2011-10-19 17:15:50 +02:00
" the channel chosen automatically:: \n \n "
" obex-bt://00:0A:94:03:F3:7E \n \n "
" If the automatism fails, the channel can also be specified:: \n \n "
" obex-bt://00:0A:94:03:F3:7E+16 \n \n "
2010-02-04 09:29:28 +01:00
" For peers contacting us via Bluetooth, the MAC address is \n "
" used to identify it before the sync starts. Multiple \n "
2011-10-19 17:15:50 +02:00
" urls can be specified in one syncURL property:: \n \n "
" obex-bt://00:0A:94:03:F3:7E obex-bt://00:01:02:03:04:05 \n \n "
2010-02-04 09:29:28 +01:00
" In the future this might be used to contact the peer \n "
" via one of several transports; right now, only the first \n "
" one is tried. " // MB #9446
2010-01-29 06:27:06 +01:00
) ;
2009-11-17 07:37:14 +01:00
2008-03-06 23:23:13 +01:00
static ConfigProperty syncPropDevID ( " deviceId " ,
2008-07-12 22:02:09 +02:00
" The SyncML server gets this string and will use it to keep track of \n "
2008-03-06 23:23:13 +01:00
" changes that still need to be synchronized with this particular \n "
2008-03-30 20:39:15 +02:00
" client; it must be set to something unique (like the pseudo-random \n "
2008-07-12 22:02:09 +02:00
" string created automatically for new configurations) among all clients \n "
" accessing the same server. \n "
" myFUNAMBOL also requires that the string starts with sc-pim- " ) ;
2008-03-06 23:23:13 +01:00
static ConfigProperty syncPropUsername ( " username " ,
2008-04-03 22:01:56 +02:00
" user name used for authorization with the SyncML server " ,
2009-09-29 22:31:56 +02:00
" " ) ;
2013-07-26 10:22:11 +02:00
2013-09-04 16:58:11 +02:00
static BoolConfigProperty syncPropPeerIsClient ( " PeerIsClient " ,
" Indicates whether this configuration is about a \n "
" client peer or server peer. \n " ,
" FALSE " ) ;
static SafeConfigProperty syncPropRemoteDevID ( " remoteDeviceId " ,
" SyncML ID of our peer, empty if unknown; must be set only when \n "
" the peer is a SyncML client contacting us via HTTP. \n "
" Clients contacting us via OBEX/Bluetooth can be identified \n "
" either via this remoteDeviceId property or by their MAC \n "
" address, if that was set in the syncURL property. \n "
" \n "
" If this property is empty and the peer synchronizes with \n "
" this configuration chosen by some other means, then its ID \n "
" is recorded here automatically and later used to verify that \n "
" the configuration is not accidentally used by a different \n "
" peer. " ) ;
2013-07-26 10:22:11 +02:00
static class SyncPasswordConfigProperty : public PasswordConfigProperty
{
public :
SyncPasswordConfigProperty ( ) :
PasswordConfigProperty ( " password " ,
" password used for authorization with the peer; \n "
" in addition to specifying it directly as plain text, it can \n "
" also be read from the standard input or from an environment \n "
" variable of your choice:: \n \n "
" plain text : password = <insert your password here> \n "
" ask : password = - \n "
" env variable: password = ${<name of environment variable>} \n " )
{ }
2013-07-26 11:56:18 +02:00
2013-07-26 10:22:11 +02:00
virtual void checkPassword ( UserInterface & ui ,
2013-07-26 11:56:18 +02:00
SyncConfig & config ,
2013-07-29 13:57:46 +02:00
int flags ,
2013-07-26 11:56:18 +02:00
const std : : string & sourceName = " " ) const {
2013-07-29 13:57:46 +02:00
PasswordConfigProperty : : checkPassword ( ui , config , flags , syncPropUsername , sourceName ) ;
2013-07-26 10:22:11 +02:00
}
2013-07-26 16:19:40 +02:00
virtual void savePassword ( UserInterface & ui ,
SyncConfig & config ,
const std : : string & sourceName = " " ) const {
PasswordConfigProperty : : savePassword ( ui , config , syncPropUsername , sourceName ) ;
}
2013-07-26 10:22:11 +02:00
ConfigPasswordKey getPasswordKey ( const string & descr ,
const string & serverName ,
FilterConfigNode & globalConfigNode ,
const string & sourceName ,
2018-01-16 17:17:34 +01:00
const std : : shared_ptr < FilterConfigNode > & sourceConfigNode ) const {
2013-07-26 10:22:11 +02:00
ConfigPasswordKey key ;
2013-09-04 16:58:11 +02:00
bool peerIsClient = syncPropPeerIsClient . getPropertyValue ( globalConfigNode ) ;
2013-07-26 10:22:11 +02:00
key . server = syncPropSyncURL . getProperty ( globalConfigNode ) ;
2013-08-09 18:16:55 +02:00
key . description = StringPrintf ( " sync password for %s " , descr . c_str ( ) ) ;
2013-09-04 16:58:11 +02:00
if ( peerIsClient & & key . server . empty ( ) ) {
/**
* Fall back to username / remoteDeviceId as key .
*/
key . server = syncPropRemoteDevID . getProperty ( globalConfigNode ) ;
} else {
/**
* Here we use server sync url without protocol prefix and
* user account name as the key in the keyring .
* The URL must not be empty , otherwise we end up
* overwriting the password of some other service just
* because it happens to have the same username .
*/
size_t start = key . server . find ( " :// " ) ;
/* we don't preserve protocol prefix for it may change */
if ( start ! = key . server . npos ) {
key . server = key . server . substr ( start + 3 ) ;
}
2013-07-26 10:22:11 +02:00
}
key . user = getUsername ( syncPropUsername , globalConfigNode ) ;
2014-07-23 20:21:14 +02:00
// User domain part of a username which looks like an email address
// as server name if we don't have something better. Needed for
// WebDAV configs using just an email address to locate the server.
if ( key . server . empty ( ) ) {
size_t offset = key . user . find ( ' @ ' ) ;
if ( offset ! = key . user . npos & &
offset ! = key . user . size ( ) - 1 ) {
key . server = key . user . substr ( offset + 1 ) ;
key . user . resize ( offset ) ;
}
}
2013-07-26 10:22:11 +02:00
return key ;
}
} syncPropPassword ;
2010-01-22 16:14:29 +01:00
static BoolConfigProperty syncPropPreventSlowSync ( " preventSlowSync " ,
" During a slow sync, the SyncML server must match all items \n "
" of the client with its own items and detect which ones it \n "
" already has based on properties of the items. This is slow \n "
" (client must send all its data) and can lead to duplicates \n "
" (when the server fails to match correctly). \n "
" It is therefore sometimes desirable to wipe out data on one \n "
" side with a refresh-from-client/server sync instead of doing \n "
" a slow sync. \n "
" When this option is enabled, slow syncs that could cause problems \n "
2014-07-28 15:29:41 +02:00
" are not allowed to proceed. Instead, the affected datastores are \n "
2010-01-22 16:14:29 +01:00
" skipped, allowing the user to choose a suitable sync mode in \n "
" the next run (slow sync selected explicitly, refresh sync). \n "
2011-10-19 17:15:50 +02:00
" The following situations are handled: \n \n "
2010-01-22 16:14:29 +01:00
" - running as client with no local data => unproblematic, \n "
" slow sync is allowed to proceed automatically \n "
" - running as client with local data => client has no \n "
" information about server, so slow sync might be problematic \n "
" and is prevented \n "
" - client has data, server asks for slow sync because all its data \n "
" was deleted (done by Memotoo and Mobical, because they treat \n "
" this as 'user wants to start from scratch') => the sync would \n "
" recreate all the client's data, even if the user really wanted \n "
2011-10-19 17:15:50 +02:00
" to have it deleted, therefore slow sync is prevented \n " ,
" TRUE " ) ;
2008-03-06 23:23:13 +01:00
static BoolConfigProperty syncPropUseProxy ( " useProxy " ,
2009-05-08 10:33:06 +02:00
" set to T to choose an HTTP proxy explicitly; otherwise the default \n "
2009-11-27 19:47:47 +01:00
" proxy settings of the underlying HTTP transport mechanism are used; \n "
2011-10-19 17:15:50 +02:00
" only relevant when contacting the peer via HTTP " ,
" FALSE " ) ;
2008-03-06 23:23:13 +01:00
static ConfigProperty syncPropProxyHost ( " proxyHost " ,
2011-10-19 17:15:50 +02:00
" proxy URL (``http://<host>:<port>``) " ) ;
2008-03-09 17:57:03 +01:00
static ConfigProperty syncPropProxyUsername ( " proxyUsername " ,
2008-04-03 22:01:56 +02:00
" authentication for proxy: username " ) ;
2013-07-26 10:22:11 +02:00
static class ProxyPasswordConfigProperty : public PasswordConfigProperty {
public :
ProxyPasswordConfigProperty ( ) :
PasswordConfigProperty ( " proxyPassword " ,
" proxy password, can be specified in different ways, \n "
" see SyncML server password for details \n " ,
" " ,
" proxy " )
{ }
/**
* re - implement this function for it is necessary to do a check
* before retrieving proxy password
*/
virtual void checkPassword ( UserInterface & ui ,
2013-07-26 11:56:18 +02:00
SyncConfig & config ,
2013-07-29 13:57:46 +02:00
int flags ,
2013-07-26 11:56:18 +02:00
const std : : string & sourceName = std : : string ( ) ) const {
2013-07-26 10:22:11 +02:00
/* if useProxy is set 'true', then check proxypassword */
2013-07-26 11:56:18 +02:00
if ( config . getUseProxy ( ) ) {
2013-07-29 13:57:46 +02:00
PasswordConfigProperty : : checkPassword ( ui , config , flags , syncPropProxyUsername , sourceName ) ;
2013-07-26 10:22:11 +02:00
}
}
2013-07-26 16:19:40 +02:00
virtual void savePassword ( UserInterface & ui ,
SyncConfig & config ,
const std : : string & sourceName = std : : string ( ) ) const {
PasswordConfigProperty : : savePassword ( ui , config , syncPropProxyUsername , sourceName ) ;
}
2013-07-26 10:22:11 +02:00
virtual ConfigPasswordKey getPasswordKey ( const std : : string & descr ,
const std : : string & serverName ,
FilterConfigNode & globalConfigNode ,
const std : : string & sourceName ,
2018-01-16 17:17:34 +01:00
const std : : shared_ptr < FilterConfigNode > & sourceConfigNode ) const {
2013-07-26 10:22:11 +02:00
ConfigPasswordKey key ;
key . server = syncPropProxyHost . getProperty ( globalConfigNode ) ;
key . user = getUsername ( syncPropProxyUsername , globalConfigNode ) ;
2013-08-09 18:16:55 +02:00
key . description = StringPrintf ( " proxy password for %s " , descr . c_str ( ) ) ;
2013-07-26 10:22:11 +02:00
return key ;
}
} syncPropProxyPassword ;
2008-03-10 23:45:36 +01:00
static StringConfigProperty syncPropClientAuthType ( " clientAuthType " ,
2008-03-19 12:29:14 +01:00
" - empty or \" md5 \" for secure method (recommended) \n "
2009-06-10 15:28:23 +02:00
" - \" basic \" for insecure method \n "
" \n "
" This setting is only for debugging purpose and only \n "
" has an effect during the initial sync of a client. \n "
" Later it remembers the method that was supported by \n "
2009-11-27 19:47:47 +01:00
" the server and uses that. When acting as server, \n "
" clients contacting us can use both basic and md5 \n "
" authentication. \n " ,
2008-03-10 23:45:36 +01:00
" md5 " ,
2009-09-21 10:07:05 +02:00
" " ,
2008-03-10 23:45:36 +01:00
Values ( ) +
2009-06-10 14:27:16 +02:00
( Aliases ( " basic " ) + " syncml:auth-basic " ) +
( Aliases ( " md5 " ) + " syncml:auth-md5 " + " " ) ) ;
2014-09-01 12:43:08 +02:00
static ULongConfigProperty syncPropMaxMsgSize ( SyncMaxMsgSize ,
2008-03-06 23:23:13 +01:00
" The maximum size of each message can be set (maxMsgSize) and the \n "
2009-11-27 19:47:47 +01:00
" peer can be told to never sent items larger than a certain \n "
" threshold (maxObjSize). Presumably the peer has to truncate or \n "
2009-06-10 13:32:49 +02:00
" skip larger items. Sizes are specified as number of bytes. " ,
2010-02-19 15:59:48 +01:00
" 150000 " ) ;
2009-06-10 13:32:49 +02:00
static UIntConfigProperty syncPropMaxObjSize ( " maxObjSize " , " " , " 4000000 " ) ;
2008-03-09 20:08:34 +01:00
2009-03-17 14:16:49 +01:00
static BoolConfigProperty syncPropWBXML ( " enableWBXML " ,
2009-11-27 19:47:47 +01:00
" use the more compact binary XML (WBXML) for messages between client and server; \n "
" not applicable when the peer is a SyncML client, because then the client \n "
" chooses the encoding " ,
2009-06-25 11:06:07 +02:00
" TRUE " ) ;
2012-06-11 14:48:02 +02:00
static BoolConfigProperty syncPropRefreshSync ( " enableRefreshSync " ,
" Use the more advanced refresh-from-server sync mode to \n "
" implement the refresh-from-remote operation. Some SyncML \n "
" servers do not support this. Therefore the default is to \n "
" delete local data before doing a slow sync, which has the \n "
" same effect. However, some servers work better when they \n "
" are told explicitly that the sync is a refresh sync. For \n "
" example, Funambol's One Media server rejects too many slow \n "
" syncs in a row with a 417 'retry later' error. \n " ,
" FALSE " ) ;
2008-03-06 23:23:13 +01:00
static ConfigProperty syncPropLogDir ( " logdir " ,
" full path to directory where automatic backups and logs \n "
2009-04-16 17:22:31 +02:00
" are stored for all synchronizations; if unset, then \n "
2009-06-10 15:34:38 +02:00
" \" ${XDG_CACHE_HOME}/syncevolution/<server> \" (which \n "
" usually expands to ${HOME}/.cache/...) will be used; \n "
2008-03-06 23:23:13 +01:00
" if \" none \" , then no backups of the databases are made and any \n "
2009-04-16 17:22:31 +02:00
" output is printed directly to the screen " ) ;
2010-03-22 17:38:54 +01:00
static UIntConfigProperty syncPropMaxLogDirs ( " maxlogdirs " ,
2012-08-07 09:09:18 +02:00
" Controls how many session directories are kept at most in the logdir. \n "
" Unless set to zero, SyncEvolution will remove old directories and \n "
" all their content to prevent the number of log directories from \n "
" growing beyond the given limit. It tries to be intelligent and will \n "
" remove sessions in which nothing interesting happened (no errors, \n "
" no data changes) in favor of keeping sessions where something \n "
" happened, even if those sessions are older. " ,
" 10 " ) ;
2010-03-22 17:38:54 +01:00
static UIntConfigProperty syncPropLogLevel ( " loglevel " ,
2008-03-06 23:23:13 +01:00
" level of detail for log messages: \n "
" - 0 (or unset) = INFO messages without log file, DEBUG with log file \n "
" - 1 = only ERROR messages \n "
" - 2 = also INFO messages \n "
2009-06-03 20:39:16 +02:00
" - 3 = also DEBUG messages \n "
" > 3 = increasing amounts of debug messages for developers " ) ;
2012-05-22 10:05:11 +02:00
static UIntConfigProperty syncPropNotifyLevel ( " notifyLevel " ,
" Level of detail for desktop notifications. Currently such \n "
" notifications are generated only for automatically started \n "
" sync sessions. \n "
" \n "
" 0 - suppress all notifications \n "
" 1 - show only errors \n "
" 2 - show information about changes and errors (in practice currently the same as level 3) \n "
" 3 - show all notifications, including starting a sync \n " ,
" 3 " ) ;
2009-04-21 11:22:32 +02:00
static BoolConfigProperty syncPropPrintChanges ( " printChanges " ,
" enables or disables the detailed (and sometimes slow) comparison \n "
" of database content before and after a sync session " ,
2011-10-19 17:15:50 +02:00
" TRUE " ) ;
2010-10-29 16:00:50 +02:00
static BoolConfigProperty syncPropDumpData ( " dumpData " ,
" enables or disables the automatic backup of database content \n "
" before and after a sync session (always enabled if printChanges is enabled) " ,
2011-10-19 17:15:50 +02:00
" TRUE " ) ;
2010-03-22 17:45:03 +01:00
static SecondsConfigProperty syncPropRetryDuration ( " RetryDuration " ,
2011-04-15 13:30:51 +02:00
" The total amount of time in seconds in which the SyncML \n "
" client tries to get a response from the server. \n "
2009-09-21 06:20:03 +02:00
" During this time, the client will resend messages \n "
" in regular intervals (RetryInterval) if no response \n "
2009-10-13 21:43:16 +02:00
" is received or the message could not be delivered due \n "
2009-09-21 06:20:03 +02:00
" to transport problems. When this time is exceeded \n "
" without a response, the synchronization aborts without \n "
2009-11-27 19:47:47 +01:00
" sending further messages to the server. \n "
" \n "
" When acting as server, this setting controls how long \n "
" a client is allowed to not send a message before the \n "
" synchronization is aborted. "
2010-03-22 17:45:03 +01:00
, " 5M " ) ;
2010-03-25 17:50:21 +01:00
static SecondsConfigProperty syncPropRetryInterval ( " RetryInterval " ,
2011-04-15 13:30:51 +02:00
" The number of seconds between the start of SyncML message sending \n "
2009-10-13 21:43:16 +02:00
" and the start of the retransmission. If the interval has \n "
2009-09-21 06:20:03 +02:00
" already passed when a message send returns, the \n "
2009-10-13 21:43:16 +02:00
" message is resent immediately. Resending without \n "
" any delay will never succeed and therefore specifying 0 \n "
2009-11-27 19:47:47 +01:00
" disables retries. \n "
" \n "
" Servers cannot resend messages, so this setting has no \n "
2011-04-15 13:30:51 +02:00
" effect in that case. \n "
" \n "
" The WebDAV backend also resends messages after a temporary \n "
" network error. It uses exponential backoff to determine when \n "
" the server is available again. This setting is divided by 24 \n "
" to obtain the initial delay (default: 2m => 5s), which is then \n "
" doubled for each retry. "
2010-04-19 13:56:07 +02:00
, " 2M " ) ;
2010-01-13 18:05:45 +01:00
static SafeConfigProperty syncPropPeerName ( " PeerName " ,
" An arbitrary name for the peer referenced by this config. \n "
" Might be used by a GUI. The command line tool always uses the \n "
" the configuration name. " ) ;
2012-11-06 10:49:26 +01:00
static ConfigProperty syncPropSyncMLVersion ( " SyncMLVersion " ,
" On a client, the latest commonly supported SyncML version \n "
" is used when contacting a server. One of '1.0/1.1/1.2' can \n "
" be used to pick a specific version explicitly. \n "
" \n "
" On a server, this option controls what kind of Server Alerted \n "
" Notification is sent to the client to start a synchronization. \n "
" By default, first the format from 1.2 is tried, then in case \n "
" of failure, the older one from 1.1. 1.2/1.1 can be set \n "
" explicitly, which disables the automatism. \n "
" \n "
" Instead or in adddition to the version, several keywords can \n "
" be set in this property (separated by spaces or commas): \n "
" \n "
2013-04-24 12:00:45 +02:00
" - NOCTCAP - avoid sending CtCap meta information \n "
" - NORESTART - disable the sync mode extension that SyncEvolution \n "
2012-11-06 10:49:26 +01:00
" client and server use to negotiate whether both sides support \n "
" running multiple sync iterations in the same session \n "
2013-04-24 12:00:45 +02:00
" - REQUESTMAXTIME=<time> - override the rate at which the \n "
" SyncML server sends preliminary replies while preparing \n "
" local storages in the background. This helps to avoid timeouts \n "
" in the SyncML client. Depends on multithreading. \n "
# ifdef HAVE_THREAD_SUPPORT
// test-dbus.py checks for 'is thread-safe'!
" This SyncEvolution binary is thread-safe and thus this feature \n "
" is enabled by default for HTTP servers, with a delay of 2 minutes \n "
" between messages. Other servers (Bluetooth, local sync) should not \n "
" need preliminary replies and the feature is disabled, although \n "
" it can be enabled by setting the time explicitly. \n "
# else
" This SyncEvolution binary is not thread-safe and thus this feature \n "
" is disabled by default, although it can be enabled if absolutely \n "
" needed by setting the time explicitly. \n "
# endif
" <time> can be specified like other durations in the config, \n "
" for example as REQUESTMAXTIME=2m. \n "
2012-11-06 10:49:26 +01:00
" \n "
" Setting these flags should only be necessary as workaround for \n "
" broken peers. \n "
) ;
2010-02-26 11:20:52 +01:00
2009-11-13 05:31:06 +01:00
static ConfigProperty syncPropRemoteIdentifier ( " remoteIdentifier " ,
2009-11-18 06:35:04 +01:00
" the identifier sent to the remote peer for a server initiated sync. \n "
" if not set, deviceId will be used instead \n " ,
2009-11-13 05:31:06 +01:00
" " ) ;
2008-04-05 11:17:58 +02:00
static ConfigProperty syncPropSSLServerCertificates ( " SSLServerCertificates " ,
" A string specifying the location of the certificates \n "
" used to authenticate the server. When empty, the \n "
2009-11-27 19:47:47 +01:00
" system's default location will be searched. \n "
" \n "
" SSL support when acting as HTTP server is implemented \n "
" by the HTTP server frontend, not with these properties. " ,
2009-07-09 18:58:21 +02:00
SYNCEVOLUTION_SSL_SERVER_CERTIFICATES ) ;
2008-04-05 11:17:58 +02:00
static BoolConfigProperty syncPropSSLVerifyServer ( " SSLVerifyServer " ,
" The client refuses to establish the connection unless \n "
" the server presents a valid certificate. Disabling this \n "
" option considerably reduces the security of SSL \n "
" (man-in-the-middle attacks become possible) and is not \n "
" recommended. \n " ,
2011-10-19 17:15:50 +02:00
" TRUE " ) ;
2008-04-05 11:17:58 +02:00
static BoolConfigProperty syncPropSSLVerifyHost ( " SSLVerifyHost " ,
" The client refuses to establish the connection unless the \n "
" server's certificate matches its host name. In cases where \n "
" the certificate still seems to be valid it might make sense \n "
" to disable this option and allow such connections. \n " ,
2011-10-19 17:15:50 +02:00
" TRUE " ) ;
2008-03-06 23:23:13 +01:00
2009-04-07 20:33:18 +02:00
static ConfigProperty syncPropWebURL ( " WebURL " ,
" The URL of a web page with further information about the server. \n "
" Used only by the GUI. "
" " ) ;
static ConfigProperty syncPropIconURI ( " IconURI " ,
" The URI of an icon representing the server graphically. \n "
" Should be a 48x48 pixmap or a SVG (preferred). \n "
" Used only by the GUI. " ) ;
2009-06-29 20:32:26 +02:00
static BoolConfigProperty syncPropConsumerReady ( " ConsumerReady " ,
" Set to true in a configuration template to indicate \n "
" that the server works well enough and is available \n "
" for normal users. Used by the GUI to limit the choice \n "
" of configurations offered to users. \n "
" Has no effect in a user's server configuration. \n " ,
2011-10-19 17:15:50 +02:00
" FALSE " ) ;
2009-06-29 20:32:26 +02:00
2011-05-18 17:20:56 +02:00
/**
* Some guidelines for peerType = WebDAV :
2011-06-29 03:42:43 +02:00
* - Such templates may only be used to create the ' target - config @ < target > .
2011-05-18 17:20:56 +02:00
* configurations . Typically < target > can be the same as the template ' s
* name .
* - Because determining the default database in WebDAV can be difficult ,
* the GUI should allow the user to choose and set the " uri "
* properties accordingly .
* - A GUI should also create a < target > configuration for synchronizing
* against the WebDAV backends .
*/
static ConfigProperty syncPropPeerType ( " peerType " ,
" Defines what a configuration is meant to be used for. \n "
" Used in templates and the resulting configs to tell a GUI \n "
" that special handling may be necessary. GUIs should ignore \n "
" unknown types. \n "
" The traditional SyncML configs use an empty value. \n "
" \" WebDAV \" is used for the WebDAV side in a local synchronization. \n " ) ;
2009-06-18 18:02:55 +02:00
static ULongConfigProperty syncPropHashCode ( " HashCode " , " used by the SyncML library internally; do not modify " ) ;
static ConfigProperty syncPropConfigDate ( " ConfigDate " , " used by the SyncML library internally; do not modify " ) ;
2009-10-25 22:46:09 +01:00
static SafeConfigProperty syncPropNonce ( " lastNonce " ,
" MD5 nonce of our peer, empty if not set yet; do not edit, used internally " ) ;
2009-11-12 21:19:03 +01:00
// used both as source and sync property, internal in both cases
static SafeConfigProperty syncPropDeviceData ( " deviceData " ,
2009-11-26 11:53:43 +01:00
" information about the peer in the format described in the \n "
" Synthesis SDK manual under 'Session_SaveDeviceInfo' " ) ;
2009-10-25 22:46:09 +01:00
password handling: fixed KWallet support, global configuration option
KWallet support was broken: syncevo-dbus-server checked
KDE_FULL_SESSION to determine whether it should use KWallet instead of
GNOME Keyring. That did not work, because the env variable was not set
for D-Bus daemons.
Automatically detecting KDE users is not possible at the
moment. Instead KDE users have to manually set the new "keyring"
global config property to "KDE" (case insensitive) if the
SyncEvolution installation supports both, because GNOME Keyring is the
default to avoid surprises for traditional users. If only KWallet
support is enabled, then this is not necessary.
"GNOME" and "true/false/1/0/yes/no" can also be set. This has the
advantage that keyring usage can be enabled permanently for the
command line in --daemon=no mode; normally keyrings are not used in
that mode because accessing them can bring up UI dialogs.
It also becomes possible to disable keyring usage in syncevo-dbus-server,
something which couldn't be done before.
The --keyring command line option is still supported, as an alias for
"[--sync-property] keyring=<value>". The default value for --keyring
is true, to match the traditional behavior. In contrast to other sync
properties, setting "keyring" does not require an explicit --run
parameter. Again this is done to mirror traditional usage.
Reading a password also (unintentionally) checked all supported
storages while searching for the password. Now it uses exactly
one storage and falls back to asking for the password directly.
The commit itself also cleans up the code a bit (reformatted, fixed
comments). Choosing the right slot in the password signals is done via
a new InitStateTri parameter which contains the "keyring" setting.
Error checking (unsupported keyring string, --keyring=yes and no
keyring enabled) is done in additional slots which run after all the
regular ones.
Parameter parsing for --sync and --keyring were unified. However,
there is the difference that --keyring has an implicit default value
("yes") and never has an additional parameter, in contrast to --sync,
which always is followed by one.
The new CmdlineTest::testKeyring covers different ways of using
--keyring. It relies on actually invoking keyring backends, something
not done by the default SyncContext UI. Therefore
CmdlineSyncClient+KeyringSyncCmdline were moved into libsyncevolution,
to be used by CmdlineTest.
2012-05-29 18:14:13 +02:00
static SafeConfigProperty globalPropDefaultPeer ( " defaultPeer " ,
" the peer which is used by default in some frontends, like the sync-UI " ) ;
static ConfigProperty globalPropKeyring ( " keyring " ,
" Explicitly selects a certain safe password storage. \n "
" Depending on how SyncEvolution was compiled and installed \n "
" the following values are possible: \n "
" \n "
" GNOME \n GNOME Keyring \n "
" KDE \n KWallet \n "
" yes/true/1 \n pick one automatically \n "
" no/false/0 \n store passwords in SyncEvolution config files \n "
" \n "
2013-09-05 17:27:51 +02:00
" If unset, the default is to pick one automatically if support \n "
" for any kind of password storage was enabled and use the config files \n "
" otherwise. When choosing automatically, GNOME keyring is tried \n "
" first because distinguishing between KDE and GNOME sessions \n "
" automatically is tricky. \n "
password handling: fixed KWallet support, global configuration option
KWallet support was broken: syncevo-dbus-server checked
KDE_FULL_SESSION to determine whether it should use KWallet instead of
GNOME Keyring. That did not work, because the env variable was not set
for D-Bus daemons.
Automatically detecting KDE users is not possible at the
moment. Instead KDE users have to manually set the new "keyring"
global config property to "KDE" (case insensitive) if the
SyncEvolution installation supports both, because GNOME Keyring is the
default to avoid surprises for traditional users. If only KWallet
support is enabled, then this is not necessary.
"GNOME" and "true/false/1/0/yes/no" can also be set. This has the
advantage that keyring usage can be enabled permanently for the
command line in --daemon=no mode; normally keyrings are not used in
that mode because accessing them can bring up UI dialogs.
It also becomes possible to disable keyring usage in syncevo-dbus-server,
something which couldn't be done before.
The --keyring command line option is still supported, as an alias for
"[--sync-property] keyring=<value>". The default value for --keyring
is true, to match the traditional behavior. In contrast to other sync
properties, setting "keyring" does not require an explicit --run
parameter. Again this is done to mirror traditional usage.
Reading a password also (unintentionally) checked all supported
storages while searching for the password. Now it uses exactly
one storage and falls back to asking for the password directly.
The commit itself also cleans up the code a bit (reformatted, fixed
comments). Choosing the right slot in the password signals is done via
a new InitStateTri parameter which contains the "keyring" setting.
Error checking (unsupported keyring string, --keyring=yes and no
keyring enabled) is done in additional slots which run after all the
regular ones.
Parameter parsing for --sync and --keyring were unified. However,
there is the difference that --keyring has an implicit default value
("yes") and never has an additional parameter, in contrast to --sync,
which always is followed by one.
The new CmdlineTest::testKeyring covers different ways of using
--keyring. It relies on actually invoking keyring backends, something
not done by the default SyncContext UI. Therefore
CmdlineSyncClient+KeyringSyncCmdline were moved into libsyncevolution,
to be used by CmdlineTest.
2012-05-29 18:14:13 +02:00
" \n "
" Note that using this option applies to *all* passwords in \n "
" a configuration and that the --keyring command line option \n "
" is merely an alias for setting the global property, so setting \n "
" a single password as follows sets both `keyring` and \n "
" `proxyPasswords`, and also moves the other passwords into the \n "
" keyring, even if they were not stored there already: \n "
" \n "
" --keyring --configure proxyPassword=foo \n "
" \n "
2013-09-05 17:27:51 +02:00
" When passwords were stored in a safe storage, their value is set to a single \n "
password handling: fixed KWallet support, global configuration option
KWallet support was broken: syncevo-dbus-server checked
KDE_FULL_SESSION to determine whether it should use KWallet instead of
GNOME Keyring. That did not work, because the env variable was not set
for D-Bus daemons.
Automatically detecting KDE users is not possible at the
moment. Instead KDE users have to manually set the new "keyring"
global config property to "KDE" (case insensitive) if the
SyncEvolution installation supports both, because GNOME Keyring is the
default to avoid surprises for traditional users. If only KWallet
support is enabled, then this is not necessary.
"GNOME" and "true/false/1/0/yes/no" can also be set. This has the
advantage that keyring usage can be enabled permanently for the
command line in --daemon=no mode; normally keyrings are not used in
that mode because accessing them can bring up UI dialogs.
It also becomes possible to disable keyring usage in syncevo-dbus-server,
something which couldn't be done before.
The --keyring command line option is still supported, as an alias for
"[--sync-property] keyring=<value>". The default value for --keyring
is true, to match the traditional behavior. In contrast to other sync
properties, setting "keyring" does not require an explicit --run
parameter. Again this is done to mirror traditional usage.
Reading a password also (unintentionally) checked all supported
storages while searching for the password. Now it uses exactly
one storage and falls back to asking for the password directly.
The commit itself also cleans up the code a bit (reformatted, fixed
comments). Choosing the right slot in the password signals is done via
a new InitStateTri parameter which contains the "keyring" setting.
Error checking (unsupported keyring string, --keyring=yes and no
keyring enabled) is done in additional slots which run after all the
regular ones.
Parameter parsing for --sync and --keyring were unified. However,
there is the difference that --keyring has an implicit default value
("yes") and never has an additional parameter, in contrast to --sync,
which always is followed by one.
The new CmdlineTest::testKeyring covers different ways of using
--keyring. It relies on actually invoking keyring backends, something
not done by the default SyncContext UI. Therefore
CmdlineSyncClient+KeyringSyncCmdline were moved into libsyncevolution,
to be used by CmdlineTest.
2012-05-29 18:14:13 +02:00
" hyphen ( \" - \" ) in the configuration. This means that when running a \n "
2013-09-05 17:27:51 +02:00
" synchronization without using the storage, the password has to be \n "
password handling: fixed KWallet support, global configuration option
KWallet support was broken: syncevo-dbus-server checked
KDE_FULL_SESSION to determine whether it should use KWallet instead of
GNOME Keyring. That did not work, because the env variable was not set
for D-Bus daemons.
Automatically detecting KDE users is not possible at the
moment. Instead KDE users have to manually set the new "keyring"
global config property to "KDE" (case insensitive) if the
SyncEvolution installation supports both, because GNOME Keyring is the
default to avoid surprises for traditional users. If only KWallet
support is enabled, then this is not necessary.
"GNOME" and "true/false/1/0/yes/no" can also be set. This has the
advantage that keyring usage can be enabled permanently for the
command line in --daemon=no mode; normally keyrings are not used in
that mode because accessing them can bring up UI dialogs.
It also becomes possible to disable keyring usage in syncevo-dbus-server,
something which couldn't be done before.
The --keyring command line option is still supported, as an alias for
"[--sync-property] keyring=<value>". The default value for --keyring
is true, to match the traditional behavior. In contrast to other sync
properties, setting "keyring" does not require an explicit --run
parameter. Again this is done to mirror traditional usage.
Reading a password also (unintentionally) checked all supported
storages while searching for the password. Now it uses exactly
one storage and falls back to asking for the password directly.
The commit itself also cleans up the code a bit (reformatted, fixed
comments). Choosing the right slot in the password signals is done via
a new InitStateTri parameter which contains the "keyring" setting.
Error checking (unsupported keyring string, --keyring=yes and no
keyring enabled) is done in additional slots which run after all the
regular ones.
Parameter parsing for --sync and --keyring were unified. However,
there is the difference that --keyring has an implicit default value
("yes") and never has an additional parameter, in contrast to --sync,
which always is followed by one.
The new CmdlineTest::testKeyring covers different ways of using
--keyring. It relies on actually invoking keyring backends, something
not done by the default SyncContext UI. Therefore
CmdlineSyncClient+KeyringSyncCmdline were moved into libsyncevolution,
to be used by CmdlineTest.
2012-05-29 18:14:13 +02:00
" entered interactively. The --print-config output always shows \" - \" instead \n "
" of retrieving the password from the keyring. \n " ,
2013-09-05 17:27:51 +02:00
# ifdef HAVE_KEYRING
" yes "
# else
" no "
# endif
) ;
2009-11-13 17:25:30 +01:00
2010-02-23 08:57:44 +01:00
static StringConfigProperty syncPropAutoSync ( " autoSync " ,
" Controls automatic synchronization. Currently, \n "
" automatic synchronization is done by running \n "
" a synchronization at regular intervals. This \n "
" may drain the battery, in particular when \n "
" using Bluetooth! \n "
" Because a peer might be reachable via different \n "
" transports at some point, this option provides \n "
" detailed control over which transports may \n "
2011-10-19 17:15:50 +02:00
" be used for automatic synchronization: \n \n "
" 0 \n don't do auto sync \n "
" 1 \n do automatic sync, using whatever transport \n "
2010-02-23 08:57:44 +01:00
" is available \n "
2011-10-19 17:15:50 +02:00
" http \n only via HTTP transport \n "
" obex-bt \n only via Bluetooth transport \n "
" http,obex-bt \n pick one of these \n " ,
2010-02-23 08:57:44 +01:00
" 0 " ) ;
2010-03-22 17:45:03 +01:00
static SecondsConfigProperty syncPropAutoSyncInterval ( " autoSyncInterval " ,
2014-01-17 14:16:03 +01:00
" This is the minimum number of seconds since the start of \n "
" the last synchronization that has to pass before starting \n "
2010-03-22 17:45:03 +01:00
" an automatic synchronization. Can be specified using \n "
" a 1h30m5s format. \n "
" \n "
" Before reducing this interval, consider that it will \n "
" increase resource consumption on the local and remote \n "
" side. Some SyncML server operators only allow a \n "
" certain number of sessions per day. \n "
" The value 0 has the effect of only running automatic \n "
" synchronization when changes are detected (not \n "
" implemented yet, therefore it basically disables \n "
" automatic synchronization). \n " ,
" 30M " ) ;
static SecondsConfigProperty syncPropAutoSyncDelay ( " autoSyncDelay " ,
" An automatic sync will not be started unless the peer \n "
" has been available for this duration, specified in seconds \n "
" or 1h30m5s format. \n "
" \n "
" This prevents running a sync when network connectivity \n "
" is unreliable or was recently established for some \n "
" other purpose. It is also a heuristic that attempts \n "
" to predict how long connectivity be available in the \n "
" future, because it should better be available long \n "
" enough to complete the synchronization. \n " ,
" 5M " ) ;
2010-02-23 08:57:44 +01:00
2011-01-10 15:56:53 +01:00
/* config and on-disk file versionsing */
password handling: fixed KWallet support, global configuration option
KWallet support was broken: syncevo-dbus-server checked
KDE_FULL_SESSION to determine whether it should use KWallet instead of
GNOME Keyring. That did not work, because the env variable was not set
for D-Bus daemons.
Automatically detecting KDE users is not possible at the
moment. Instead KDE users have to manually set the new "keyring"
global config property to "KDE" (case insensitive) if the
SyncEvolution installation supports both, because GNOME Keyring is the
default to avoid surprises for traditional users. If only KWallet
support is enabled, then this is not necessary.
"GNOME" and "true/false/1/0/yes/no" can also be set. This has the
advantage that keyring usage can be enabled permanently for the
command line in --daemon=no mode; normally keyrings are not used in
that mode because accessing them can bring up UI dialogs.
It also becomes possible to disable keyring usage in syncevo-dbus-server,
something which couldn't be done before.
The --keyring command line option is still supported, as an alias for
"[--sync-property] keyring=<value>". The default value for --keyring
is true, to match the traditional behavior. In contrast to other sync
properties, setting "keyring" does not require an explicit --run
parameter. Again this is done to mirror traditional usage.
Reading a password also (unintentionally) checked all supported
storages while searching for the password. Now it uses exactly
one storage and falls back to asking for the password directly.
The commit itself also cleans up the code a bit (reformatted, fixed
comments). Choosing the right slot in the password signals is done via
a new InitStateTri parameter which contains the "keyring" setting.
Error checking (unsupported keyring string, --keyring=yes and no
keyring enabled) is done in additional slots which run after all the
regular ones.
Parameter parsing for --sync and --keyring were unified. However,
there is the difference that --keyring has an implicit default value
("yes") and never has an additional parameter, in contrast to --sync,
which always is followed by one.
The new CmdlineTest::testKeyring covers different ways of using
--keyring. It relies on actually invoking keyring backends, something
not done by the default SyncContext UI. Therefore
CmdlineSyncClient+KeyringSyncCmdline were moved into libsyncevolution,
to be used by CmdlineTest.
2012-05-29 18:14:13 +02:00
static IntConfigProperty propRootMinVersion ( " rootMinVersion " , " " ) ;
static IntConfigProperty propRootCurVersion ( " rootCurVersion " , " " ) ;
static IntConfigProperty propContextMinVersion ( " contextMinVersion " , " " ) ;
static IntConfigProperty propContextCurVersion ( " contextCurVersion " , " " ) ;
static IntConfigProperty propPeerMinVersion ( " peerMinVersion " , " " ) ;
static IntConfigProperty propPeerCurVersion ( " peerCurVersion " , " " ) ;
2011-01-10 15:56:53 +01:00
static const IntConfigProperty * configVersioning [ CONFIG_LEVEL_MAX ] [ CONFIG_VERSION_MAX ] = {
password handling: fixed KWallet support, global configuration option
KWallet support was broken: syncevo-dbus-server checked
KDE_FULL_SESSION to determine whether it should use KWallet instead of
GNOME Keyring. That did not work, because the env variable was not set
for D-Bus daemons.
Automatically detecting KDE users is not possible at the
moment. Instead KDE users have to manually set the new "keyring"
global config property to "KDE" (case insensitive) if the
SyncEvolution installation supports both, because GNOME Keyring is the
default to avoid surprises for traditional users. If only KWallet
support is enabled, then this is not necessary.
"GNOME" and "true/false/1/0/yes/no" can also be set. This has the
advantage that keyring usage can be enabled permanently for the
command line in --daemon=no mode; normally keyrings are not used in
that mode because accessing them can bring up UI dialogs.
It also becomes possible to disable keyring usage in syncevo-dbus-server,
something which couldn't be done before.
The --keyring command line option is still supported, as an alias for
"[--sync-property] keyring=<value>". The default value for --keyring
is true, to match the traditional behavior. In contrast to other sync
properties, setting "keyring" does not require an explicit --run
parameter. Again this is done to mirror traditional usage.
Reading a password also (unintentionally) checked all supported
storages while searching for the password. Now it uses exactly
one storage and falls back to asking for the password directly.
The commit itself also cleans up the code a bit (reformatted, fixed
comments). Choosing the right slot in the password signals is done via
a new InitStateTri parameter which contains the "keyring" setting.
Error checking (unsupported keyring string, --keyring=yes and no
keyring enabled) is done in additional slots which run after all the
regular ones.
Parameter parsing for --sync and --keyring were unified. However,
there is the difference that --keyring has an implicit default value
("yes") and never has an additional parameter, in contrast to --sync,
which always is followed by one.
The new CmdlineTest::testKeyring covers different ways of using
--keyring. It relies on actually invoking keyring backends, something
not done by the default SyncContext UI. Therefore
CmdlineSyncClient+KeyringSyncCmdline were moved into libsyncevolution,
to be used by CmdlineTest.
2012-05-29 18:14:13 +02:00
{ & propRootMinVersion , & propRootCurVersion } ,
{ & propContextMinVersion , & propContextCurVersion } ,
{ & propPeerMinVersion , & propPeerCurVersion }
2011-01-10 15:56:53 +01:00
} ;
static const IntConfigProperty & getConfigVersionProp ( ConfigLevel level , ConfigLimit limit )
{
if ( level < 0 | | level > = CONFIG_LEVEL_MAX | |
limit < 0 | | limit > = CONFIG_VERSION_MAX ) {
SE_THROW ( " getConfigVersionProp: invalid args " ) ;
}
return * configVersioning [ level ] [ limit ] ;
}
int SyncConfig : : getConfigVersion ( ConfigLevel level , ConfigLimit limit ) const
{
const IntConfigProperty & prop = getConfigVersionProp ( level , limit ) ;
return prop . getPropertyValue ( * getNode ( prop ) ) ;
}
void SyncConfig : : setConfigVersion ( ConfigLevel level , ConfigLimit limit , int version )
{
if ( m_layout ! = SHARED_LAYOUT ) {
// old-style layouts have version 0 by default, no need
// (and sometimes no possibility) to set this explicitly
if ( version ! = 0 ) {
SE_THROW ( StringPrintf ( " cannot bump config version in old-style config %s " , m_peer . c_str ( ) ) ) ;
}
} else {
const IntConfigProperty & prop = getConfigVersionProp ( level , limit ) ;
prop . setProperty ( * getNode ( prop ) , version ) ;
}
}
2011-07-26 03:12:58 +02:00
2011-07-11 11:37:09 +02:00
/**
* This constructor updates some of the properties above and then adds
* them to the registry . This cannot be done inside getRegistry ( )
* itself because that function may be invoked by other global
* instances before the properties above were constructed ( BMC
* # 19464 ) .
*/
static class RegisterSyncConfigProperties
2008-03-06 23:23:13 +01:00
{
2011-07-11 11:37:09 +02:00
public :
RegisterSyncConfigProperties ( )
{
ConfigPropertyRegistry & registry = SyncConfig : : getRegistry ( ) ;
2008-03-06 23:23:13 +01:00
2011-08-12 21:03:34 +02:00
// temporarily move existing properties away so that the important
// standard properties come first when using the traditional
// push_back() way of adding them
ConfigPropertyRegistry tmp ;
std : : swap ( registry , tmp ) ;
2008-03-06 23:23:13 +01:00
registry . push_back ( & syncPropSyncURL ) ;
registry . push_back ( & syncPropUsername ) ;
registry . push_back ( & syncPropPassword ) ;
registry . push_back ( & syncPropLogDir ) ;
registry . push_back ( & syncPropLogLevel ) ;
2012-05-22 10:05:11 +02:00
registry . push_back ( & syncPropNotifyLevel ) ;
2009-04-21 11:22:32 +02:00
registry . push_back ( & syncPropPrintChanges ) ;
2010-10-29 16:00:50 +02:00
registry . push_back ( & syncPropDumpData ) ;
2008-03-06 23:23:13 +01:00
registry . push_back ( & syncPropMaxLogDirs ) ;
2010-03-02 06:34:42 +01:00
registry . push_back ( & syncPropAutoSync ) ;
registry . push_back ( & syncPropAutoSyncInterval ) ;
registry . push_back ( & syncPropAutoSyncDelay ) ;
2010-01-22 16:14:29 +01:00
registry . push_back ( & syncPropPreventSlowSync ) ;
2008-03-06 23:23:13 +01:00
registry . push_back ( & syncPropUseProxy ) ;
registry . push_back ( & syncPropProxyHost ) ;
registry . push_back ( & syncPropProxyUsername ) ;
registry . push_back ( & syncPropProxyPassword ) ;
registry . push_back ( & syncPropClientAuthType ) ;
2009-09-21 06:20:03 +02:00
registry . push_back ( & syncPropRetryDuration ) ;
registry . push_back ( & syncPropRetryInterval ) ;
2009-11-13 05:31:06 +01:00
registry . push_back ( & syncPropRemoteIdentifier ) ;
registry . push_back ( & syncPropPeerIsClient ) ;
2010-02-26 11:20:52 +01:00
registry . push_back ( & syncPropSyncMLVersion ) ;
2010-01-13 18:05:45 +01:00
registry . push_back ( & syncPropPeerName ) ;
2008-03-30 20:39:15 +02:00
registry . push_back ( & syncPropDevID ) ;
2009-11-27 19:47:47 +01:00
registry . push_back ( & syncPropRemoteDevID ) ;
2009-03-17 14:16:49 +01:00
registry . push_back ( & syncPropWBXML ) ;
2012-06-11 14:48:02 +02:00
registry . push_back ( & syncPropRefreshSync ) ;
2008-03-06 23:23:13 +01:00
registry . push_back ( & syncPropMaxMsgSize ) ;
registry . push_back ( & syncPropMaxObjSize ) ;
2008-04-05 11:17:58 +02:00
registry . push_back ( & syncPropSSLServerCertificates ) ;
registry . push_back ( & syncPropSSLVerifyServer ) ;
registry . push_back ( & syncPropSSLVerifyHost ) ;
2009-04-07 20:33:18 +02:00
registry . push_back ( & syncPropWebURL ) ;
registry . push_back ( & syncPropIconURI ) ;
2009-06-29 20:32:26 +02:00
registry . push_back ( & syncPropConsumerReady ) ;
2011-05-18 17:20:56 +02:00
registry . push_back ( & syncPropPeerType ) ;
2009-06-18 18:02:55 +02:00
registry . push_back ( & syncPropHashCode ) ;
registry . push_back ( & syncPropConfigDate ) ;
2009-10-25 22:46:09 +01:00
registry . push_back ( & syncPropNonce ) ;
2009-11-12 21:19:03 +01:00
registry . push_back ( & syncPropDeviceData ) ;
password handling: fixed KWallet support, global configuration option
KWallet support was broken: syncevo-dbus-server checked
KDE_FULL_SESSION to determine whether it should use KWallet instead of
GNOME Keyring. That did not work, because the env variable was not set
for D-Bus daemons.
Automatically detecting KDE users is not possible at the
moment. Instead KDE users have to manually set the new "keyring"
global config property to "KDE" (case insensitive) if the
SyncEvolution installation supports both, because GNOME Keyring is the
default to avoid surprises for traditional users. If only KWallet
support is enabled, then this is not necessary.
"GNOME" and "true/false/1/0/yes/no" can also be set. This has the
advantage that keyring usage can be enabled permanently for the
command line in --daemon=no mode; normally keyrings are not used in
that mode because accessing them can bring up UI dialogs.
It also becomes possible to disable keyring usage in syncevo-dbus-server,
something which couldn't be done before.
The --keyring command line option is still supported, as an alias for
"[--sync-property] keyring=<value>". The default value for --keyring
is true, to match the traditional behavior. In contrast to other sync
properties, setting "keyring" does not require an explicit --run
parameter. Again this is done to mirror traditional usage.
Reading a password also (unintentionally) checked all supported
storages while searching for the password. Now it uses exactly
one storage and falls back to asking for the password directly.
The commit itself also cleans up the code a bit (reformatted, fixed
comments). Choosing the right slot in the password signals is done via
a new InitStateTri parameter which contains the "keyring" setting.
Error checking (unsupported keyring string, --keyring=yes and no
keyring enabled) is done in additional slots which run after all the
regular ones.
Parameter parsing for --sync and --keyring were unified. However,
there is the difference that --keyring has an implicit default value
("yes") and never has an additional parameter, in contrast to --sync,
which always is followed by one.
The new CmdlineTest::testKeyring covers different ways of using
--keyring. It relies on actually invoking keyring backends, something
not done by the default SyncContext UI. Therefore
CmdlineSyncClient+KeyringSyncCmdline were moved into libsyncevolution,
to be used by CmdlineTest.
2012-05-29 18:14:13 +02:00
registry . push_back ( & globalPropDefaultPeer ) ;
registry . push_back ( & globalPropKeyring ) ;
2009-11-13 14:52:00 +01:00
2011-01-10 15:56:53 +01:00
#if 0
// Must not be registered! Not valid for --sync-property and
// must not be copied between configs.
registry . push_back ( & syncPropRootMinVersion ) ;
registry . push_back ( & syncPropRootCurVersion ) ;
registry . push_back ( & syncPropContextMinVersion ) ;
registry . push_back ( & syncPropContextCurVersion ) ;
registry . push_back ( & syncPropPeerMinVersion ) ;
registry . push_back ( & syncPropPeerCurVersion ) ;
# endif
2018-01-16 10:58:04 +01:00
for ( const ConfigProperty * prop : tmp ) {
2011-08-12 21:03:34 +02:00
registry . push_back ( prop ) ;
}
2009-11-13 14:52:00 +01:00
// obligatory sync properties
2011-03-23 12:14:31 +01:00
//
// username/password used to be
// considered obligatory, but are not anymore because there are
// cases where they are not needed (local sync, Bluetooth)
// syncPropUsername.setObligatory(true);
// syncPropPassword.setObligatory(true);
//
// created if not given:
// syncPropDevID.setObligatory(true);
2009-11-13 14:52:00 +01:00
syncPropSyncURL . setObligatory ( true ) ;
// hidden sync properties
syncPropHashCode . setHidden ( true ) ;
syncPropConfigDate . setHidden ( true ) ;
syncPropNonce . setHidden ( true ) ;
2009-11-12 21:19:03 +01:00
syncPropDeviceData . setHidden ( true ) ;
password handling: fixed KWallet support, global configuration option
KWallet support was broken: syncevo-dbus-server checked
KDE_FULL_SESSION to determine whether it should use KWallet instead of
GNOME Keyring. That did not work, because the env variable was not set
for D-Bus daemons.
Automatically detecting KDE users is not possible at the
moment. Instead KDE users have to manually set the new "keyring"
global config property to "KDE" (case insensitive) if the
SyncEvolution installation supports both, because GNOME Keyring is the
default to avoid surprises for traditional users. If only KWallet
support is enabled, then this is not necessary.
"GNOME" and "true/false/1/0/yes/no" can also be set. This has the
advantage that keyring usage can be enabled permanently for the
command line in --daemon=no mode; normally keyrings are not used in
that mode because accessing them can bring up UI dialogs.
It also becomes possible to disable keyring usage in syncevo-dbus-server,
something which couldn't be done before.
The --keyring command line option is still supported, as an alias for
"[--sync-property] keyring=<value>". The default value for --keyring
is true, to match the traditional behavior. In contrast to other sync
properties, setting "keyring" does not require an explicit --run
parameter. Again this is done to mirror traditional usage.
Reading a password also (unintentionally) checked all supported
storages while searching for the password. Now it uses exactly
one storage and falls back to asking for the password directly.
The commit itself also cleans up the code a bit (reformatted, fixed
comments). Choosing the right slot in the password signals is done via
a new InitStateTri parameter which contains the "keyring" setting.
Error checking (unsupported keyring string, --keyring=yes and no
keyring enabled) is done in additional slots which run after all the
regular ones.
Parameter parsing for --sync and --keyring were unified. However,
there is the difference that --keyring has an implicit default value
("yes") and never has an additional parameter, in contrast to --sync,
which always is followed by one.
The new CmdlineTest::testKeyring covers different ways of using
--keyring. It relies on actually invoking keyring backends, something
not done by the default SyncContext UI. Therefore
CmdlineSyncClient+KeyringSyncCmdline were moved into libsyncevolution,
to be used by CmdlineTest.
2012-05-29 18:14:13 +02:00
propRootMinVersion . setHidden ( true ) ;
propRootCurVersion . setHidden ( true ) ;
propContextMinVersion . setHidden ( true ) ;
propContextCurVersion . setHidden ( true ) ;
propPeerMinVersion . setHidden ( true ) ;
propPeerCurVersion . setHidden ( true ) ;
2009-11-13 14:52:00 +01:00
// global sync properties
password handling: fixed KWallet support, global configuration option
KWallet support was broken: syncevo-dbus-server checked
KDE_FULL_SESSION to determine whether it should use KWallet instead of
GNOME Keyring. That did not work, because the env variable was not set
for D-Bus daemons.
Automatically detecting KDE users is not possible at the
moment. Instead KDE users have to manually set the new "keyring"
global config property to "KDE" (case insensitive) if the
SyncEvolution installation supports both, because GNOME Keyring is the
default to avoid surprises for traditional users. If only KWallet
support is enabled, then this is not necessary.
"GNOME" and "true/false/1/0/yes/no" can also be set. This has the
advantage that keyring usage can be enabled permanently for the
command line in --daemon=no mode; normally keyrings are not used in
that mode because accessing them can bring up UI dialogs.
It also becomes possible to disable keyring usage in syncevo-dbus-server,
something which couldn't be done before.
The --keyring command line option is still supported, as an alias for
"[--sync-property] keyring=<value>". The default value for --keyring
is true, to match the traditional behavior. In contrast to other sync
properties, setting "keyring" does not require an explicit --run
parameter. Again this is done to mirror traditional usage.
Reading a password also (unintentionally) checked all supported
storages while searching for the password. Now it uses exactly
one storage and falls back to asking for the password directly.
The commit itself also cleans up the code a bit (reformatted, fixed
comments). Choosing the right slot in the password signals is done via
a new InitStateTri parameter which contains the "keyring" setting.
Error checking (unsupported keyring string, --keyring=yes and no
keyring enabled) is done in additional slots which run after all the
regular ones.
Parameter parsing for --sync and --keyring were unified. However,
there is the difference that --keyring has an implicit default value
("yes") and never has an additional parameter, in contrast to --sync,
which always is followed by one.
The new CmdlineTest::testKeyring covers different ways of using
--keyring. It relies on actually invoking keyring backends, something
not done by the default SyncContext UI. Therefore
CmdlineSyncClient+KeyringSyncCmdline were moved into libsyncevolution,
to be used by CmdlineTest.
2012-05-29 18:14:13 +02:00
globalPropDefaultPeer . setSharing ( ConfigProperty : : GLOBAL_SHARING ) ;
globalPropKeyring . setSharing ( ConfigProperty : : GLOBAL_SHARING ) ;
propRootMinVersion . setSharing ( ConfigProperty : : GLOBAL_SHARING ) ;
propRootCurVersion . setSharing ( ConfigProperty : : GLOBAL_SHARING ) ;
2009-11-13 14:52:00 +01:00
// peer independent sync properties
syncPropLogDir . setSharing ( ConfigProperty : : SOURCE_SET_SHARING ) ;
syncPropMaxLogDirs . setSharing ( ConfigProperty : : SOURCE_SET_SHARING ) ;
2009-11-21 18:17:17 +01:00
syncPropDevID . setSharing ( ConfigProperty : : SOURCE_SET_SHARING ) ;
password handling: fixed KWallet support, global configuration option
KWallet support was broken: syncevo-dbus-server checked
KDE_FULL_SESSION to determine whether it should use KWallet instead of
GNOME Keyring. That did not work, because the env variable was not set
for D-Bus daemons.
Automatically detecting KDE users is not possible at the
moment. Instead KDE users have to manually set the new "keyring"
global config property to "KDE" (case insensitive) if the
SyncEvolution installation supports both, because GNOME Keyring is the
default to avoid surprises for traditional users. If only KWallet
support is enabled, then this is not necessary.
"GNOME" and "true/false/1/0/yes/no" can also be set. This has the
advantage that keyring usage can be enabled permanently for the
command line in --daemon=no mode; normally keyrings are not used in
that mode because accessing them can bring up UI dialogs.
It also becomes possible to disable keyring usage in syncevo-dbus-server,
something which couldn't be done before.
The --keyring command line option is still supported, as an alias for
"[--sync-property] keyring=<value>". The default value for --keyring
is true, to match the traditional behavior. In contrast to other sync
properties, setting "keyring" does not require an explicit --run
parameter. Again this is done to mirror traditional usage.
Reading a password also (unintentionally) checked all supported
storages while searching for the password. Now it uses exactly
one storage and falls back to asking for the password directly.
The commit itself also cleans up the code a bit (reformatted, fixed
comments). Choosing the right slot in the password signals is done via
a new InitStateTri parameter which contains the "keyring" setting.
Error checking (unsupported keyring string, --keyring=yes and no
keyring enabled) is done in additional slots which run after all the
regular ones.
Parameter parsing for --sync and --keyring were unified. However,
there is the difference that --keyring has an implicit default value
("yes") and never has an additional parameter, in contrast to --sync,
which always is followed by one.
The new CmdlineTest::testKeyring covers different ways of using
--keyring. It relies on actually invoking keyring backends, something
not done by the default SyncContext UI. Therefore
CmdlineSyncClient+KeyringSyncCmdline were moved into libsyncevolution,
to be used by CmdlineTest.
2012-05-29 18:14:13 +02:00
propContextMinVersion . setSharing ( ConfigProperty : : SOURCE_SET_SHARING ) ;
propContextCurVersion . setSharing ( ConfigProperty : : SOURCE_SET_SHARING ) ;
2008-03-06 23:23:13 +01:00
}
2011-07-11 11:37:09 +02:00
} RegisterSyncConfigProperties ;
2008-03-06 23:23:13 +01:00
2011-07-11 11:37:09 +02:00
ConfigPropertyRegistry & SyncConfig : : getRegistry ( )
{
static ConfigPropertyRegistry registry ;
2008-03-06 23:23:13 +01:00
return registry ;
}
2013-07-26 10:22:11 +02:00
UserIdentity SyncConfig : : getSyncUser ( ) const {
InitStateString user = syncPropUsername . getProperty ( * getNode ( syncPropUsername ) ) ;
UserIdentity id ( UserIdentity : : fromString ( user ) ) ;
return id ;
}
2011-04-11 12:55:13 +02:00
void SyncConfig : : setSyncUsername ( const string & value , bool temporarily ) { syncPropUsername . setProperty ( * getNode ( syncPropUsername ) , value , temporarily ) ; }
2011-11-21 16:37:53 +01:00
InitStateString SyncConfig : : getSyncPassword ( ) const {
2013-07-25 17:23:34 +02:00
return syncPropPassword . getProperty ( * getNode ( syncPropPassword ) ) ;
2008-04-03 22:01:56 +02:00
}
2012-03-06 13:34:51 +01:00
void PasswordConfigProperty : : checkPassword ( UserInterface & ui ,
2013-07-26 11:56:18 +02:00
SyncConfig & config ,
2013-07-29 13:57:46 +02:00
int flags ,
2013-07-26 10:22:11 +02:00
const ConfigProperty & usernameProperty ,
2013-07-26 11:56:18 +02:00
const std : : string & sourceName ) const
2013-08-02 22:02:03 +02:00
{
2013-07-26 11:56:18 +02:00
std : : string serverName = config . getConfigName ( ) ;
2018-01-16 17:17:34 +01:00
std : : shared_ptr < FilterConfigNode > globalConfigNode = config . getProperties ( ) ;
std : : shared_ptr < FilterConfigNode > sourceConfigNode ;
2013-07-26 11:56:18 +02:00
if ( ! sourceName . empty ( ) ) {
sourceConfigNode = config . getSyncSourceNodes ( sourceName ) . getNode ( * this ) ;
}
2013-07-26 16:19:40 +02:00
FilterConfigNode & configNode = sourceConfigNode ? * sourceConfigNode : * globalConfigNode ;
InitStateString username = usernameProperty . getProperty ( configNode ) ;
2013-09-04 17:02:14 +02:00
if ( sourceName . empty ( ) ) {
SE_LOG_DEBUG ( NULL , " checking password property '%s' in config '%s' with user identity '%s' " ,
getMainName ( ) . c_str ( ) ,
serverName . c_str ( ) ,
username . c_str ( ) ) ;
} else {
2014-07-28 15:29:41 +02:00
SE_LOG_DEBUG ( NULL , " checking password property '%s' in datastore '%s' of config '%s' with user identity '%s' " ,
2013-09-04 17:02:14 +02:00
getMainName ( ) . c_str ( ) ,
sourceName . c_str ( ) ,
serverName . c_str ( ) ,
username . c_str ( ) ) ;
}
2013-07-26 10:22:11 +02:00
UserIdentity identity ( UserIdentity : : fromString ( username ) ) ;
2013-07-26 16:19:40 +02:00
InitStateString passwordToSave ;
InitStateString usernameToSave ;
2013-07-26 10:22:11 +02:00
if ( identity . m_provider = = USER_IDENTITY_SYNC_CONFIG ) {
2013-07-26 16:19:40 +02:00
const std : : string & credConfigName = identity . m_identity ;
SE_LOG_INFO ( NULL , " using %s/%s from config '%s' as credentials for %s%s%s " ,
syncPropUsername . getMainName ( ) . c_str ( ) ,
syncPropPassword . getMainName ( ) . c_str ( ) ,
credConfigName . c_str ( ) ,
serverName . c_str ( ) ,
sourceName . empty ( ) ? " " : " / " ,
sourceName . c_str ( ) ) ;
// Actual username/password are stored in a different config. Go find it...
SyncConfig : : Layout layout = config . getLayout ( ) ;
if ( layout ! = SyncConfig : : SHARED_LAYOUT ) {
SE_THROW ( StringPrintf ( " %s = %s: only supported in configs using the current config storage, please migrate config %s " ,
usernameProperty . getMainName ( ) . c_str ( ) ,
username . c_str ( ) ,
config . getConfigName ( ) . c_str ( ) ) ) ;
}
2018-01-16 17:17:34 +01:00
auto credConfig = std : : make_shared < SyncConfig > ( credConfigName ) ;
2013-07-26 16:19:40 +02:00
if ( ! credConfig - > exists ( ) ) {
SE_THROW ( StringPrintf ( " %s = %s: config '%s' not found, cannot look up credentials " ,
usernameProperty . getMainName ( ) . c_str ( ) ,
username . c_str ( ) ,
credConfigName . c_str ( ) ) ) ;
}
2013-07-29 13:57:46 +02:00
syncPropPassword . checkPassword ( ui , * credConfig , flags ) ;
2013-07-26 16:19:40 +02:00
// Always store the new values.
passwordToSave = InitStateString ( credConfig - > getSyncPassword ( ) , true ) ;
usernameToSave = InitStateString ( credConfig - > getSyncUser ( ) . toString ( ) , true ) ;
} else if ( identity . m_provider ! = USER_IDENTITY_PLAIN_TEXT ) {
2013-07-26 10:22:11 +02:00
// Can some provider give us the plain text password? Not at the moment,
// so we've got nothing to do here.
2013-08-02 22:02:03 +02:00
} else {
2013-07-26 16:19:40 +02:00
// Default, internal password handling.
InitStateString password = getProperty ( configNode ) ;
string descr = getDescr ( serverName , * globalConfigNode , sourceName , sourceConfigNode ) ;
if ( password = = " - " ) {
ConfigPasswordKey key = getPasswordKey ( descr , serverName , * globalConfigNode , sourceName , sourceConfigNode ) ;
2013-09-04 17:02:14 +02:00
SE_LOG_DEBUG ( NULL , " loading password from keyring with key %s " , key . toString ( ) . c_str ( ) ) ;
2013-07-26 16:19:40 +02:00
std : : string uiPassword = ui . askPassword ( getMainName ( ) , descr , key ) ;
// Empty means "no response". askPassword() pre-dates the
// InitStateString class, and probably should be changed
// to use it to avoid this kind of ambiguity, but for now
// keep this semantic. Therefore don't use the result if
// empty.
if ( ! uiPassword . empty ( ) ) {
passwordToSave = uiPassword ;
}
} else if ( boost : : starts_with ( password , " ${ " ) & &
boost : : ends_with ( password , " } " ) ) {
string envname = password . substr ( 2 , password . size ( ) - 3 ) ;
const char * envval = getenv ( envname . c_str ( ) ) ;
2013-09-04 17:02:14 +02:00
SE_LOG_DEBUG ( NULL , " using password from env var %s " , envname . c_str ( ) ) ;
2013-07-26 16:19:40 +02:00
if ( ! envval ) {
2014-04-02 14:57:56 +02:00
Exception : : throwError ( SE_HERE , string ( " the environment variable ' " ) +
2013-07-26 16:19:40 +02:00
envname +
" ' for the ' " +
descr +
" ' password is not set " ) ;
} else {
passwordToSave = envval ;
}
2013-07-26 16:19:40 +02:00
}
2013-08-02 22:02:03 +02:00
}
2013-07-26 16:19:40 +02:00
// If we found a password, then set it in the config node
// temporarily. That way, all following "get password" calls will
// be able to return it without having to make all callers away of
// password handling.
2013-07-29 13:57:46 +02:00
if ( passwordToSave . wasSet ( ) & & ( flags & CHECK_PASSWORD_RESOLVE_PASSWORD ) ) {
2013-07-26 16:19:40 +02:00
configNode . addFilter ( getMainName ( ) , InitStateString ( passwordToSave , true ) ) ;
}
2013-07-29 13:57:46 +02:00
if ( usernameToSave . wasSet ( ) & & ( flags & CHECK_PASSWORD_RESOLVE_USERNAME ) ) {
2013-07-26 16:19:40 +02:00
configNode . addFilter ( usernameProperty . getMainName ( ) , InitStateString ( usernameToSave , true ) ) ;
2013-08-02 22:02:03 +02:00
}
}
2013-07-26 10:22:11 +02:00
2013-07-29 13:57:46 +02:00
void PasswordConfigProperty : : checkPasswords ( UserInterface & ui ,
SyncConfig & config ,
int flags ,
const std : : list < std : : string > & sourceNames )
{
if ( flags & CHECK_PASSWORD_SYNC ) {
ConfigPropertyRegistry & registry = SyncConfig : : getRegistry ( ) ;
2018-01-16 10:58:04 +01:00
for ( const ConfigProperty * prop : registry ) {
2013-07-29 13:57:46 +02:00
prop - > checkPassword ( ui , config , flags ) ;
}
}
if ( flags & CHECK_PASSWORD_SOURCE ) {
2018-01-16 10:58:04 +01:00
for ( const std : : string & sourceName : sourceNames ) {
2013-07-29 13:57:46 +02:00
ConfigPropertyRegistry & registry = SyncSourceConfig : : getRegistry ( ) ;
2018-01-16 10:58:04 +01:00
for ( const ConfigProperty * prop : registry ) {
2013-07-29 13:57:46 +02:00
prop - > checkPassword ( ui , config , flags , sourceName ) ;
}
}
}
}
2013-07-26 10:22:11 +02:00
std : : string PasswordConfigProperty : : getUsername ( const ConfigProperty & usernameProperty ,
const FilterConfigNode & node )
{
InitStateString username = usernameProperty . getProperty ( node ) ;
UserIdentity id ( UserIdentity : : fromString ( username ) ) ;
return id . m_identity ;
}
2013-08-02 22:02:03 +02:00
void PasswordConfigProperty : : savePassword ( UserInterface & ui ,
2013-07-26 11:56:18 +02:00
SyncConfig & config ,
2013-07-26 16:19:40 +02:00
const ConfigProperty & usernameProperty ,
2013-07-26 11:56:18 +02:00
const std : : string & sourceName ) const
2013-08-02 22:02:03 +02:00
{
2013-07-26 11:56:18 +02:00
std : : string serverName = config . getConfigName ( ) ;
2018-01-16 17:17:34 +01:00
std : : shared_ptr < FilterConfigNode > globalConfigNode = config . getProperties ( ) ;
std : : shared_ptr < FilterConfigNode > sourceConfigNode ;
2013-07-26 11:56:18 +02:00
if ( ! sourceName . empty ( ) ) {
sourceConfigNode = config . getSyncSourceNodes ( sourceName ) . getNode ( * this ) ;
}
2013-07-26 16:19:40 +02:00
FilterConfigNode & configNode = sourceConfigNode ? * sourceConfigNode : * globalConfigNode ;
InitStateString username = usernameProperty . getProperty ( configNode ) ;
2013-07-29 13:57:46 +02:00
// In checkPassword() we retrieve from background storage and store as temporary value.
// Here we use the temporary value and move it in the background storage.
2013-09-04 17:02:14 +02:00
// We allow empty passwords to be stored in the config although
// that might leak some information, because that is how SyncEvolution
// traditionally worked. Changing this now breaks tests and possibly
// causes problems for users depending on the old behavior.
2013-07-29 13:57:46 +02:00
InitStateString password = getProperty ( configNode ) ;
2013-09-04 17:02:14 +02:00
if ( ! password . wasSet ( ) | | password . empty ( ) ) {
2013-07-29 13:57:46 +02:00
return ;
}
2013-09-04 17:02:14 +02:00
if ( sourceName . empty ( ) ) {
SE_LOG_DEBUG ( NULL , " possibly saving password property '%s' in config '%s' with user identity '%s' " ,
getMainName ( ) . c_str ( ) ,
serverName . c_str ( ) ,
username . c_str ( ) ) ;
} else {
2014-07-28 15:29:41 +02:00
SE_LOG_DEBUG ( NULL , " possibly saving password property '%s' in datastore '%s' of config '%s' with user identity '%s' " ,
2013-09-04 17:02:14 +02:00
getMainName ( ) . c_str ( ) ,
sourceName . c_str ( ) ,
serverName . c_str ( ) ,
username . c_str ( ) ) ;
}
2013-07-26 16:19:40 +02:00
UserIdentity identity ( UserIdentity : : fromString ( username ) ) ;
2013-07-26 11:56:18 +02:00
2013-07-26 10:22:11 +02:00
2013-07-26 16:19:40 +02:00
bool updatePassword = false ;
InitStateString passwordToSave ;
if ( identity . m_provider = = USER_IDENTITY_SYNC_CONFIG ) {
// Store in the other config and unset it here.
updatePassword = true ;
const std : : string & credConfigName = identity . m_identity ;
SE_LOG_INFO ( NULL , " setting %s in config '%s' as part of credentials for %s%s%s " ,
syncPropPassword . getMainName ( ) . c_str ( ) ,
credConfigName . c_str ( ) ,
serverName . c_str ( ) ,
sourceName . empty ( ) ? " " : " / " ,
sourceName . c_str ( ) ) ;
// Actual username/password are stored in a different config. Go find it...
SyncConfig : : Layout layout = config . getLayout ( ) ;
if ( layout ! = SyncConfig : : SHARED_LAYOUT ) {
SE_THROW ( StringPrintf ( " %s = %s: only supported in configs using the current config storage, please migrate config %s " ,
usernameProperty . getMainName ( ) . c_str ( ) ,
username . c_str ( ) ,
config . getConfigName ( ) . c_str ( ) ) ) ;
}
2018-01-16 17:17:34 +01:00
auto credConfig = std : : make_shared < SyncConfig > ( credConfigName ) ;
2013-07-26 16:19:40 +02:00
if ( ! credConfig - > exists ( ) ) {
SE_THROW ( StringPrintf ( " %s = %s: config '%s' not found, cannot look up credentials " ,
usernameProperty . getMainName ( ) . c_str ( ) ,
username . c_str ( ) ,
credConfigName . c_str ( ) ) ) ;
}
credConfig - > setSyncPassword ( password , false ) ;
syncPropPassword . savePassword ( ui , * credConfig ) ;
2009-09-21 10:07:05 +02:00
} else {
2013-07-26 16:19:40 +02:00
if ( password = = " - " | | password = = " " | |
( boost : : starts_with ( password , " ${ " ) & & boost : : ends_with ( password , " } " ) ) ) {
// Nothing to do, leave it as is.
2013-09-04 17:02:14 +02:00
SE_LOG_DEBUG ( NULL , " no need to save, interactive or env var password " ) ;
2013-08-02 22:02:03 +02:00
} else {
2013-07-26 16:19:40 +02:00
string descr = getDescr ( serverName , * globalConfigNode , sourceName , sourceConfigNode ) ;
ConfigPasswordKey key = getPasswordKey ( descr , serverName , * globalConfigNode , sourceName , sourceConfigNode ) ;
2013-09-04 17:02:14 +02:00
SE_LOG_DEBUG ( NULL , " saving password in keyring with key %s " , key . toString ( ) . c_str ( ) ) ;
2013-07-26 16:19:40 +02:00
if ( ui . savePassword ( getMainName ( ) , password , key ) ) {
passwordToSave = " - " ;
updatePassword = true ;
}
2013-08-02 22:02:03 +02:00
}
2009-09-21 10:07:05 +02:00
}
2013-07-26 16:19:40 +02:00
if ( updatePassword ) {
setProperty ( configNode , passwordToSave ) ;
}
2009-09-21 10:07:05 +02:00
}
2013-07-26 10:22:11 +02:00
2013-07-25 17:23:34 +02:00
void SyncConfig : : setSyncPassword ( const string & value , bool temporarily ) { syncPropPassword . setProperty ( * getNode ( syncPropPassword ) , value , temporarily ) ; }
2009-12-15 14:19:57 +01:00
2011-11-21 16:37:53 +01:00
InitState < bool > SyncConfig : : getPreventSlowSync ( ) const {
return syncPropPreventSlowSync . getPropertyValue ( * getNode ( syncPropPreventSlowSync ) ) ;
}
2010-01-22 16:14:29 +01:00
void SyncConfig : : setPreventSlowSync ( bool value , bool temporarily ) { syncPropPreventSlowSync . setProperty ( * getNode ( syncPropPreventSlowSync ) , value , temporarily ) ; }
2009-12-15 14:19:57 +01:00
static const char * ProxyString = " http_proxy " ;
/* Reads http_proxy from environment, if not available returns configured value */
2011-11-21 16:37:53 +01:00
InitState < bool > SyncConfig : : getUseProxy ( ) const {
2012-10-12 21:04:02 +02:00
InitState < bool > res = syncPropUseProxy . getPropertyValue ( * getNode ( syncPropUseProxy ) ) ;
if ( ! res . wasSet ( ) ) {
// Not configured. Check environment.
char * proxy = getenv ( ProxyString ) ;
if ( proxy & & * proxy ) {
// Environment has it. Assume that it applies to us and
// use it. TODO: check no_proxy against our sync URL.
res = InitState < bool > ( true , true ) ;
}
2009-12-15 14:19:57 +01:00
}
2012-10-12 21:04:02 +02:00
return res ;
2009-12-15 14:19:57 +01:00
}
2009-11-13 14:52:00 +01:00
void SyncConfig : : setUseProxy ( bool value , bool temporarily ) { syncPropUseProxy . setProperty ( * getNode ( syncPropUseProxy ) , value , temporarily ) ; }
2009-12-15 14:19:57 +01:00
/* If http_proxy set in the environment returns it, otherwise configured value */
2011-11-21 16:37:53 +01:00
InitStateString SyncConfig : : getProxyHost ( ) const {
2009-12-15 14:19:57 +01:00
char * proxy = getenv ( ProxyString ) ;
if ( ! proxy ) {
2011-01-18 15:07:46 +01:00
return syncPropProxyHost . getProperty ( * getNode ( syncPropUseProxy ) ) ;
2009-12-15 14:19:57 +01:00
} else {
2011-11-21 16:37:53 +01:00
return InitStateString ( proxy , true ) ;
2009-12-15 14:19:57 +01:00
}
}
2009-11-13 14:52:00 +01:00
void SyncConfig : : setProxyHost ( const string & value , bool temporarily ) { syncPropProxyHost . setProperty ( * getNode ( syncPropProxyHost ) , value , temporarily ) ; }
2010-01-19 16:01:10 +01:00
2013-07-26 10:22:11 +02:00
UserIdentity SyncConfig : : getProxyUser ( ) const {
InitStateString username = syncPropProxyUsername . getProperty ( * getNode ( syncPropProxyUsername ) ) ;
UserIdentity id ( UserIdentity : : fromString ( username ) ) ;
return id ;
}
2009-11-13 14:52:00 +01:00
void SyncConfig : : setProxyUsername ( const string & value , bool temporarily ) { syncPropProxyUsername . setProperty ( * getNode ( syncPropProxyUsername ) , value , temporarily ) ; }
2010-01-19 16:01:10 +01:00
2011-11-21 16:37:53 +01:00
InitStateString SyncConfig : : getProxyPassword ( ) const {
2013-07-25 17:23:34 +02:00
return syncPropProxyPassword . getProperty ( * getNode ( syncPropProxyPassword ) ) ;
2008-04-03 22:01:56 +02:00
}
2013-07-25 17:23:34 +02:00
void SyncConfig : : setProxyPassword ( const string & value , bool temporarily ) { syncPropProxyPassword . setProperty ( * getNode ( syncPropProxyPassword ) , value , temporarily ) ; }
2012-09-13 16:59:24 +02:00
InitState < vector < string > > SyncConfig : : getSyncURL ( ) const {
2011-11-21 16:37:53 +01:00
InitStateString s = syncPropSyncURL . getProperty ( * getNode ( syncPropSyncURL ) ) ;
2010-01-29 06:27:06 +01:00
vector < string > urls ;
2010-03-04 03:54:54 +01:00
if ( ! s . empty ( ) ) {
// workaround for g++ 4.3/4.4:
// http://stackoverflow.com/questions/1168525/c-gcc4-4-warning-array-subscript-is-above-array-bounds
static const string sep ( " \t " ) ;
2011-11-21 16:37:53 +01:00
boost : : split ( urls , s . get ( ) , boost : : is_any_of ( sep ) ) ;
2010-03-04 03:54:54 +01:00
}
2012-09-13 16:59:24 +02:00
return InitState < vector < string > > ( urls , s . wasSet ( ) ) ;
2010-01-29 06:27:06 +01:00
}
2009-11-13 14:52:00 +01:00
void SyncConfig : : setSyncURL ( const string & value , bool temporarily ) { syncPropSyncURL . setProperty ( * getNode ( syncPropSyncURL ) , value , temporarily ) ; }
2010-01-29 06:27:06 +01:00
void SyncConfig : : setSyncURL ( const vector < string > & value , bool temporarily ) {
stringstream urls ;
2018-01-16 10:58:04 +01:00
for ( string url : value ) {
2010-01-29 06:27:06 +01:00
urls < < url < < " " ;
}
return setSyncURL ( urls . str ( ) , temporarily ) ;
}
2011-11-21 16:37:53 +01:00
InitStateString SyncConfig : : getClientAuthType ( ) const { return syncPropClientAuthType . getProperty ( * getNode ( syncPropClientAuthType ) ) ; }
2009-11-13 14:52:00 +01:00
void SyncConfig : : setClientAuthType ( const string & value , bool temporarily ) { syncPropClientAuthType . setProperty ( * getNode ( syncPropClientAuthType ) , value , temporarily ) ; }
2014-09-08 10:52:00 +02:00
template < class T > InitState < T > EnsureMinSize ( const InitState < T > & current , T min )
{
if ( current > = min ) {
return current ;
} else {
return InitState < T > ( min ) ;
}
}
InitState < unsigned long > SyncConfig : : getMaxMsgSize ( ) const {
// Sanitize value: don't run with buffer sizes smaller than 10KB.
return EnsureMinSize ( syncPropMaxMsgSize . getPropertyValue ( * getNode ( syncPropMaxMsgSize ) ) ,
10 * 1024ul ) ;
}
2009-11-13 14:52:00 +01:00
void SyncConfig : : setMaxMsgSize ( unsigned long value , bool temporarily ) { syncPropMaxMsgSize . setProperty ( * getNode ( syncPropMaxMsgSize ) , value , temporarily ) ; }
2014-09-08 10:52:00 +02:00
InitState < unsigned int > SyncConfig : : getMaxObjSize ( ) const {
return EnsureMinSize ( syncPropMaxObjSize . getPropertyValue ( * getNode ( syncPropMaxObjSize ) ) ,
1024u ) ;
}
2009-11-13 14:52:00 +01:00
void SyncConfig : : setMaxObjSize ( unsigned int value , bool temporarily ) { syncPropMaxObjSize . setProperty ( * getNode ( syncPropMaxObjSize ) , value , temporarily ) ; }
2011-11-21 16:37:53 +01:00
InitStateString SyncConfig : : getDevID ( ) const { return syncPropDevID . getProperty ( * getNode ( syncPropDevID ) ) ; }
2009-11-13 14:52:00 +01:00
void SyncConfig : : setDevID ( const string & value , bool temporarily ) { syncPropDevID . setProperty ( * getNode ( syncPropDevID ) , value , temporarily ) ; }
2011-11-21 16:37:53 +01:00
InitState < bool > SyncConfig : : getWBXML ( ) const { return syncPropWBXML . getPropertyValue ( * getNode ( syncPropWBXML ) ) ; }
2009-11-13 14:52:00 +01:00
void SyncConfig : : setWBXML ( bool value , bool temporarily ) { syncPropWBXML . setProperty ( * getNode ( syncPropWBXML ) , value , temporarily ) ; }
2012-06-11 14:48:02 +02:00
InitState < bool > SyncConfig : : getRefreshSync ( ) const { return syncPropRefreshSync . getPropertyValue ( * getNode ( syncPropRefreshSync ) ) ; }
void SyncConfig : : setRefreshSync ( bool value , bool temporarily ) { syncPropRefreshSync . setProperty ( * getNode ( syncPropRefreshSync ) , value , temporarily ) ; }
2011-11-21 16:37:53 +01:00
InitStateString SyncConfig : : getLogDir ( ) const { return syncPropLogDir . getProperty ( * getNode ( syncPropLogDir ) ) ; }
2009-11-13 14:52:00 +01:00
void SyncConfig : : setLogDir ( const string & value , bool temporarily ) { syncPropLogDir . setProperty ( * getNode ( syncPropLogDir ) , value , temporarily ) ; }
2011-11-21 16:37:53 +01:00
InitState < unsigned int > SyncConfig : : getMaxLogDirs ( ) const { return syncPropMaxLogDirs . getPropertyValue ( * getNode ( syncPropMaxLogDirs ) ) ; }
void SyncConfig : : setMaxLogDirs ( unsigned int value , bool temporarily ) { syncPropMaxLogDirs . setProperty ( * getNode ( syncPropMaxLogDirs ) , value , temporarily ) ; }
InitState < unsigned int > SyncConfig : : getLogLevel ( ) const { return syncPropLogLevel . getPropertyValue ( * getNode ( syncPropLogLevel ) ) ; }
void SyncConfig : : setLogLevel ( unsigned int value , bool temporarily ) { syncPropLogLevel . setProperty ( * getNode ( syncPropLogLevel ) , value , temporarily ) ; }
2012-05-22 10:05:11 +02:00
InitState < SyncConfig : : NotifyLevel > SyncConfig : : getNotifyLevel ( ) const {
InitState < unsigned int > res = syncPropNotifyLevel . getPropertyValue ( * getNode ( syncPropNotifyLevel ) ) ;
return InitState < SyncConfig : : NotifyLevel > ( static_cast < SyncConfig : : NotifyLevel > ( res . get ( ) ) , res . wasSet ( ) ) ;
}
void SyncConfig : : setNotifyLevel ( SyncConfig : : NotifyLevel value , bool temporarily ) { syncPropNotifyLevel . setProperty ( * getNode ( syncPropNotifyLevel ) , value , temporarily ) ; }
2011-11-21 16:37:53 +01:00
InitState < unsigned int > SyncConfig : : getRetryDuration ( ) const { return syncPropRetryDuration . getPropertyValue ( * getNode ( syncPropRetryDuration ) ) ; }
void SyncConfig : : setRetryDuration ( unsigned int value , bool temporarily ) { syncPropRetryDuration . setProperty ( * getNode ( syncPropRetryDuration ) , value , temporarily ) ; }
InitState < unsigned int > SyncConfig : : getRetryInterval ( ) const { return syncPropRetryInterval . getPropertyValue ( * getNode ( syncPropRetryInterval ) ) ; }
void SyncConfig : : setRetryInterval ( unsigned int value , bool temporarily ) { return syncPropRetryInterval . setProperty ( * getNode ( syncPropRetryInterval ) , value , temporarily ) ; }
2009-11-13 05:31:06 +01:00
/* used by Server Alerted Sync */
2011-11-21 16:37:53 +01:00
InitStateString SyncConfig : : getRemoteIdentifier ( ) const { return syncPropRemoteIdentifier . getProperty ( * getNode ( syncPropRemoteIdentifier ) ) ; }
2009-11-13 14:52:00 +01:00
void SyncConfig : : setRemoteIdentifier ( const string & value , bool temporarily ) { return syncPropRemoteIdentifier . setProperty ( * getNode ( syncPropRemoteIdentifier ) , value , temporarily ) ; }
2011-11-21 16:37:53 +01:00
InitState < bool > SyncConfig : : getPeerIsClient ( ) const { return syncPropPeerIsClient . getPropertyValue ( * getNode ( syncPropPeerIsClient ) ) ; }
2009-11-13 14:52:00 +01:00
void SyncConfig : : setPeerIsClient ( bool value , bool temporarily ) { syncPropPeerIsClient . setProperty ( * getNode ( syncPropPeerIsClient ) , value , temporarily ) ; }
2012-11-06 10:49:26 +01:00
InitStateString SyncConfig : : getSyncMLVersion ( ) const {
InitState < std : : set < std : : string > > flags = getSyncMLFlags ( ) ;
static const char * const versions [ ] = { " 1.2 " , " 1.1 " , " 1.0 " } ;
2018-01-16 10:58:04 +01:00
for ( const char * version : versions ) {
2012-11-06 10:49:26 +01:00
if ( flags . find ( version ) ! = flags . end ( ) ) {
return InitStateString ( version , flags . wasSet ( ) ) ;
}
}
return InitStateString ( " " , flags . wasSet ( ) ) ;
}
2013-04-24 12:00:45 +02:00
InitState < unsigned int > SyncConfig : : getRequestMaxTime ( ) const {
InitState < unsigned int > requestmaxtime ;
InitState < std : : set < std : : string > > flags = getSyncMLFlags ( ) ;
2018-01-16 10:58:04 +01:00
for ( const std : : string & flag : flags ) {
2013-04-24 12:00:45 +02:00
size_t offset = flag . find ( ' = ' ) ;
if ( offset ! = flag . npos ) {
std : : string key = flag . substr ( 0 , offset ) ;
if ( boost : : iequals ( key , " RequestMaxTime " ) ) {
std : : string value = flag . substr ( offset + 1 ) ;
unsigned int seconds ;
std : : string error ;
if ( ! SecondsConfigProperty : : parseDuration ( value , error , seconds ) ) {
SE_THROW ( " invalid RequestMaxTime value in SyncMLVersion property: " + error ) ;
}
requestmaxtime = seconds ;
break ;
}
}
}
return requestmaxtime ;
}
2012-11-06 10:49:26 +01:00
InitState < std : : set < std : : string > > SyncConfig : : getSyncMLFlags ( ) const {
InitStateString value = syncPropSyncMLVersion . getProperty ( * getNode ( syncPropSyncMLVersion ) ) ;
std : : list < std : : string > keywords ;
// Work around g++ 4.4 + "array out of bounds" when using is_any_of() on plain string.
static const std : : string delim ( " , " ) ;
boost : : split ( keywords , value , boost : : is_any_of ( delim ) ) ;
std : : set < std : : string > flags ;
2018-01-16 10:58:04 +01:00
for ( std : : string & keyword : keywords ) {
2012-11-06 10:49:26 +01:00
boost : : to_lower ( keyword ) ;
flags . insert ( keyword ) ;
}
return InitState < std : : set < std : : string > > ( flags , value . wasSet ( ) ) ;
}
2010-02-26 11:20:52 +01:00
2011-11-21 16:37:53 +01:00
InitStateString SyncConfig : : getUserPeerName ( ) const { return syncPropPeerName . getProperty ( * getNode ( syncPropPeerName ) ) ; }
2012-06-05 12:57:33 +02:00
void SyncConfig : : setUserPeerName ( const InitStateString & name ) { syncPropPeerName . setProperty ( * getNode ( syncPropPeerName ) , name ) ; }
2010-01-13 18:05:45 +01:00
2011-11-21 16:37:53 +01:00
InitState < bool > SyncConfig : : getPrintChanges ( ) const { return syncPropPrintChanges . getPropertyValue ( * getNode ( syncPropPrintChanges ) ) ; }
2009-11-13 14:52:00 +01:00
void SyncConfig : : setPrintChanges ( bool value , bool temporarily ) { syncPropPrintChanges . setProperty ( * getNode ( syncPropPrintChanges ) , value , temporarily ) ; }
2011-11-21 16:37:53 +01:00
InitState < bool > SyncConfig : : getDumpData ( ) const { return syncPropDumpData . getPropertyValue ( * getNode ( syncPropDumpData ) ) ; }
2010-10-29 16:00:50 +02:00
void SyncConfig : : setDumpData ( bool value , bool temporarily ) { syncPropDumpData . setProperty ( * getNode ( syncPropDumpData ) , value , temporarily ) ; }
2011-11-21 16:37:53 +01:00
InitStateString SyncConfig : : getWebURL ( ) const { return syncPropWebURL . getProperty ( * getNode ( syncPropWebURL ) ) ; }
2009-11-13 14:52:00 +01:00
void SyncConfig : : setWebURL ( const std : : string & url , bool temporarily ) { syncPropWebURL . setProperty ( * getNode ( syncPropWebURL ) , url , temporarily ) ; }
2011-11-21 16:37:53 +01:00
InitStateString SyncConfig : : getIconURI ( ) const { return syncPropIconURI . getProperty ( * getNode ( syncPropIconURI ) ) ; }
InitState < bool > SyncConfig : : getConsumerReady ( ) const { return syncPropConsumerReady . getPropertyValue ( * getNode ( syncPropConsumerReady ) ) ; }
2009-11-13 14:52:00 +01:00
void SyncConfig : : setConsumerReady ( bool ready ) { return syncPropConsumerReady . setProperty ( * getNode ( syncPropConsumerReady ) , ready ) ; }
void SyncConfig : : setIconURI ( const std : : string & uri , bool temporarily ) { syncPropIconURI . setProperty ( * getNode ( syncPropIconURI ) , uri , temporarily ) ; }
2011-11-21 16:37:53 +01:00
InitState < unsigned long > SyncConfig : : getHashCode ( ) const { return syncPropHashCode . getPropertyValue ( * getNode ( syncPropHashCode ) ) ; }
2009-11-13 14:52:00 +01:00
void SyncConfig : : setHashCode ( unsigned long code ) { syncPropHashCode . setProperty ( * getNode ( syncPropHashCode ) , code ) ; }
2011-11-21 16:37:53 +01:00
InitStateString SyncConfig : : getConfigDate ( ) const { return syncPropConfigDate . getProperty ( * getNode ( syncPropConfigDate ) ) ; }
2009-10-06 17:22:47 +02:00
void SyncConfig : : setConfigDate ( ) {
2009-06-18 18:02:55 +02:00
/* Set current timestamp as configdate */
char buffer [ 17 ] ;
2018-01-30 17:00:24 +01:00
time_t ts = time ( nullptr ) ;
2009-06-18 18:02:55 +02:00
strftime ( buffer , sizeof ( buffer ) , " %Y%m%dT%H%M%SZ " , gmtime ( & ts ) ) ;
const std : : string date ( buffer ) ;
2009-11-13 14:52:00 +01:00
syncPropConfigDate . setProperty ( * getNode ( syncPropConfigDate ) , date ) ;
2009-06-18 18:02:55 +02:00
}
2009-11-13 14:52:00 +01:00
2011-11-21 16:37:53 +01:00
InitStateString SyncConfig : : getSSLServerCertificates ( ) const { return syncPropSSLServerCertificates . getProperty ( * getNode ( syncPropSSLServerCertificates ) ) ; }
2009-11-13 14:52:00 +01:00
void SyncConfig : : setSSLServerCertificates ( const string & value , bool temporarily ) { syncPropSSLServerCertificates . setProperty ( * getNode ( syncPropSSLServerCertificates ) , value , temporarily ) ; }
2011-11-21 16:37:53 +01:00
InitState < bool > SyncConfig : : getSSLVerifyServer ( ) const { return syncPropSSLVerifyServer . getPropertyValue ( * getNode ( syncPropSSLVerifyServer ) ) ; }
2009-11-13 14:52:00 +01:00
void SyncConfig : : setSSLVerifyServer ( bool value , bool temporarily ) { syncPropSSLVerifyServer . setProperty ( * getNode ( syncPropSSLVerifyServer ) , value , temporarily ) ; }
2011-11-21 16:37:53 +01:00
InitState < bool > SyncConfig : : getSSLVerifyHost ( ) const { return syncPropSSLVerifyHost . getPropertyValue ( * getNode ( syncPropSSLVerifyHost ) ) ; }
2009-11-13 14:52:00 +01:00
void SyncConfig : : setSSLVerifyHost ( bool value , bool temporarily ) { syncPropSSLVerifyHost . setProperty ( * getNode ( syncPropSSLVerifyHost ) , value , temporarily ) ; }
2011-11-21 16:37:53 +01:00
InitStateString SyncConfig : : getRemoteDevID ( ) const { return syncPropRemoteDevID . getProperty ( * getNode ( syncPropRemoteDevID ) ) ; }
2009-11-13 14:52:00 +01:00
void SyncConfig : : setRemoteDevID ( const string & value ) { syncPropRemoteDevID . setProperty ( * getNode ( syncPropRemoteDevID ) , value ) ; }
2011-11-21 16:37:53 +01:00
InitStateString SyncConfig : : getNonce ( ) const { return syncPropNonce . getProperty ( * getNode ( syncPropNonce ) ) ; }
2009-11-13 14:52:00 +01:00
void SyncConfig : : setNonce ( const string & value ) { syncPropNonce . setProperty ( * getNode ( syncPropNonce ) , value ) ; }
2011-11-21 16:37:53 +01:00
InitStateString SyncConfig : : getDeviceData ( ) const { return syncPropDeviceData . getProperty ( * getNode ( syncPropDeviceData ) ) ; }
2009-11-13 14:52:00 +01:00
void SyncConfig : : setDeviceData ( const string & value ) { syncPropDeviceData . setProperty ( * getNode ( syncPropDeviceData ) , value ) ; }
password handling: fixed KWallet support, global configuration option
KWallet support was broken: syncevo-dbus-server checked
KDE_FULL_SESSION to determine whether it should use KWallet instead of
GNOME Keyring. That did not work, because the env variable was not set
for D-Bus daemons.
Automatically detecting KDE users is not possible at the
moment. Instead KDE users have to manually set the new "keyring"
global config property to "KDE" (case insensitive) if the
SyncEvolution installation supports both, because GNOME Keyring is the
default to avoid surprises for traditional users. If only KWallet
support is enabled, then this is not necessary.
"GNOME" and "true/false/1/0/yes/no" can also be set. This has the
advantage that keyring usage can be enabled permanently for the
command line in --daemon=no mode; normally keyrings are not used in
that mode because accessing them can bring up UI dialogs.
It also becomes possible to disable keyring usage in syncevo-dbus-server,
something which couldn't be done before.
The --keyring command line option is still supported, as an alias for
"[--sync-property] keyring=<value>". The default value for --keyring
is true, to match the traditional behavior. In contrast to other sync
properties, setting "keyring" does not require an explicit --run
parameter. Again this is done to mirror traditional usage.
Reading a password also (unintentionally) checked all supported
storages while searching for the password. Now it uses exactly
one storage and falls back to asking for the password directly.
The commit itself also cleans up the code a bit (reformatted, fixed
comments). Choosing the right slot in the password signals is done via
a new InitStateTri parameter which contains the "keyring" setting.
Error checking (unsupported keyring string, --keyring=yes and no
keyring enabled) is done in additional slots which run after all the
regular ones.
Parameter parsing for --sync and --keyring were unified. However,
there is the difference that --keyring has an implicit default value
("yes") and never has an additional parameter, in contrast to --sync,
which always is followed by one.
The new CmdlineTest::testKeyring covers different ways of using
--keyring. It relies on actually invoking keyring backends, something
not done by the default SyncContext UI. Therefore
CmdlineSyncClient+KeyringSyncCmdline were moved into libsyncevolution,
to be used by CmdlineTest.
2012-05-29 18:14:13 +02:00
InitStateString SyncConfig : : getDefaultPeer ( ) const { return globalPropDefaultPeer . getProperty ( * getNode ( globalPropDefaultPeer ) ) ; }
void SyncConfig : : setDefaultPeer ( const string & value ) { globalPropDefaultPeer . setProperty ( * getNode ( globalPropDefaultPeer ) , value ) ; }
InitStateTri SyncConfig : : getKeyring ( ) const { return globalPropKeyring . getProperty ( * getNode ( globalPropKeyring ) ) ; }
void SyncConfig : : setKeyring ( const string & value ) { globalPropKeyring . setProperty ( * getNode ( globalPropKeyring ) , value ) ; }
2008-03-09 17:57:03 +01:00
2011-11-21 16:37:53 +01:00
InitStateString SyncConfig : : getAutoSync ( ) const { return syncPropAutoSync . getProperty ( * getNode ( syncPropAutoSync ) ) ; }
2010-02-23 08:57:44 +01:00
void SyncConfig : : setAutoSync ( const string & value , bool temporarily ) { syncPropAutoSync . setProperty ( * getNode ( syncPropAutoSync ) , value , temporarily ) ; }
2011-11-21 16:37:53 +01:00
InitState < unsigned int > SyncConfig : : getAutoSyncInterval ( ) const { return syncPropAutoSyncInterval . getPropertyValue ( * getNode ( syncPropAutoSyncInterval ) ) ; }
2010-02-23 08:57:44 +01:00
void SyncConfig : : setAutoSyncInterval ( unsigned int value , bool temporarily ) { syncPropAutoSyncInterval . setProperty ( * getNode ( syncPropAutoSyncInterval ) , value , temporarily ) ; }
2011-11-21 16:37:53 +01:00
InitState < unsigned int > SyncConfig : : getAutoSyncDelay ( ) const { return syncPropAutoSyncDelay . getPropertyValue ( * getNode ( syncPropAutoSyncDelay ) ) ; }
2010-02-23 08:57:44 +01:00
void SyncConfig : : setAutoSyncDelay ( unsigned int value , bool temporarily ) { syncPropAutoSyncDelay . setProperty ( * getNode ( syncPropAutoSyncDelay ) , value , temporarily ) ; }
2009-10-07 17:57:38 +02:00
std : : string SyncConfig : : findSSLServerCertificate ( )
{
std : : string paths = getSSLServerCertificates ( ) ;
std : : vector < std : : string > files ;
boost : : split ( files , paths , boost : : is_any_of ( " : " ) ) ;
2018-01-16 10:58:04 +01:00
for ( std : : string file : files ) {
2009-10-07 17:57:38 +02:00
if ( ! file . empty ( ) & & ! access ( file . c_str ( ) , R_OK ) ) {
return file ;
}
}
return " " ;
}
2009-11-21 17:03:54 +01:00
void SyncConfig : : setConfigFilter ( bool sync ,
const std : : string & source ,
const FilterConfigNode : : ConfigFilter & filter )
{
if ( sync ) {
m_peerNode - > setFilter ( filter ) ;
if ( m_peerNode ! = m_contextNode ) {
m_contextNode - > setFilter ( filter ) ;
}
if ( m_globalNode ! = m_contextNode ) {
m_globalNode - > setFilter ( filter ) ;
}
} else {
2010-10-22 11:36:08 +02:00
m_nodeCache . clear ( ) ;
2009-11-21 17:03:54 +01:00
m_sourceFilters [ source ] = filter ;
}
}
2018-01-16 17:17:34 +01:00
std : : shared_ptr < FilterConfigNode >
2009-11-13 14:52:00 +01:00
SyncConfig : : getNode ( const ConfigProperty & prop )
{
switch ( prop . getSharing ( ) ) {
case ConfigProperty : : GLOBAL_SHARING :
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
if ( prop . isHidden ( ) ) {
2018-01-16 17:17:34 +01:00
return std : : make_shared < FilterConfigNode > ( m_globalHiddenNode ) ;
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
} else {
return m_globalNode ;
}
2009-11-13 14:52:00 +01:00
break ;
case ConfigProperty : : SOURCE_SET_SHARING :
if ( prop . isHidden ( ) ) {
2018-01-16 17:17:34 +01:00
return std : : make_shared < FilterConfigNode > ( m_contextHiddenNode ) ;
2009-11-13 14:52:00 +01:00
} else {
return m_contextNode ;
}
break ;
case ConfigProperty : : NO_SHARING :
if ( prop . isHidden ( ) ) {
2018-01-16 17:17:34 +01:00
return std : : make_shared < FilterConfigNode > ( m_hiddenPeerNode ) ;
2009-11-13 14:52:00 +01:00
} else {
return m_peerNode ;
}
break ;
}
// should not be reached
2018-01-16 17:17:34 +01:00
return std : : make_shared < FilterConfigNode > ( std : : static_pointer_cast < ConfigNode > ( std : : make_shared < DevNullConfigNode > ( " unknown sharing state of property " ) ) ) ;
2009-11-13 14:52:00 +01:00
}
2018-01-16 17:17:34 +01:00
std : : shared_ptr < FilterConfigNode >
2011-03-02 13:24:39 +01:00
SyncConfig : : getNode ( const std : : string & propName )
{
ConfigPropertyRegistry & registry = getRegistry ( ) ;
const ConfigProperty * prop = registry . find ( propName ) ;
if ( prop ) {
return getNode ( * prop ) ;
} else {
2018-01-16 17:17:34 +01:00
return std : : shared_ptr < FilterConfigNode > ( ) ;
2011-03-02 13:24:39 +01:00
}
}
2008-03-30 23:50:51 +02:00
static void setDefaultProps ( const ConfigPropertyRegistry & registry ,
2018-01-16 17:17:34 +01:00
const std : : shared_ptr < FilterConfigNode > & node ,
2009-10-09 05:16:44 +02:00
bool force ,
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
bool unshared ,
2009-10-09 05:16:44 +02:00
bool useObligatory = true )
2008-03-06 23:23:13 +01:00
{
2018-01-16 10:58:04 +01:00
for ( const ConfigProperty * prop : registry ) {
2011-11-21 16:37:53 +01:00
InitStateString value = prop - > getProperty ( * node ) ;
2009-04-07 20:33:18 +02:00
if ( ! prop - > isHidden ( ) & &
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
( unshared | | prop - > getSharing ( ) ! = ConfigProperty : : NO_SHARING ) & &
2011-11-21 16:37:53 +01:00
( force | | ! value . wasSet ( ) ) ) {
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
if ( useObligatory ) {
2009-10-09 05:16:44 +02:00
prop - > setDefaultProperty ( * node , prop - > isObligatory ( ) ) ;
} else {
prop - > setDefaultProperty ( * node , false ) ;
}
2008-03-09 20:08:34 +01:00
}
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
}
2008-03-30 23:50:51 +02:00
}
2009-10-06 17:22:47 +02:00
void SyncConfig : : setDefaults ( bool force )
2008-03-30 23:50:51 +02:00
{
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
setDefaultProps ( getRegistry ( ) , getProperties ( ) ,
force ,
! m_peerPath . empty ( ) ) ;
2008-03-06 23:23:13 +01:00
}
2009-10-06 17:22:47 +02:00
void SyncConfig : : setSourceDefaults ( const string & name , bool force )
2008-03-06 23:23:13 +01:00
{
2008-03-09 20:08:34 +01:00
SyncSourceNodes nodes = getSyncSourceNodes ( name ) ;
redesigned SyncSource base class + API
The main motivation for this change is that it allows the implementor
of a backend to choose the implementations for the different aspects
of a datasource (change tracking, item import/export, logging, ...)
independently of each other. For example, change tracking via revision
strings can now be combined with exchanging data with the Synthesis
engine via a single string (the traditional method in SyncEvolution)
and with direct access to the Synthesis field list (now possible for
the first time).
The new backend API is based on the concept of providing
implementations for certain functionality via function objects instead
of implementing certain virtual methods. The advantage is that
implementors can define their own, custom interfaces and mix and match
implementations of the different groups of functionality.
Logging (see SyncSourceLogging in a later commit) can be done by
wrapping some arbitrary other item import/export function objects
(decorator design pattern).
The class hierarchy is now this:
- SyncSourceBase: interface for common utility code, all other
classes are derived from it and thus can use that code
- SyncSource: base class which implements SyncSourceBase and
hooks a datasource into the SyncEvolution core;
its "struct Operations" holds the function objects which
can be implemented in different ways
- TestingSyncSource: combines some of the following classes
into an interface that is expected by the client-test
program; backends only have to derive from (and implement this)
if they want to use the automated testing
- TrackingSyncSource: provides the same functionality as
before (change tracking via revision strings, item import/export
as string) in a single interface; the description of the pure
virtual methods are duplicated so that developers can go through
this class and find everything they need to know to implement
it
The following classes contain the code that was previously
found in the EvolutionSyncSource base class. Implementors
can derive from them and call the init() methods to inherit
and activate the functionality:
- SyncSourceSession: binds Synthesis session callbacks to
virtual methods beginSync(), endSync()
- SyncSourceChanges: implements Synthesis item tracking callbacks
with set of LUIDs that the user of the class has to fill
- SyncSourceDelete: binds Synthesis delete callback to
virtual method
- SyncSourceRaw: read and write items in the backends format,
used for testing and backup/restore
- SyncSourceSerialize: exchanges items with Synthesis engine
using a string representation of the data; this is how
EvolutionSyncSource has traditionally worked, so much of the
same virtual methods are now in this class
- SyncSourceRevisions: utility class which does change tracking
via some kind of "revision" string which changes each time
an item is modified; this code was previously in the
TrackingSyncSource
2009-08-25 09:27:46 +02:00
setDefaultProps ( SyncSourceConfig : : getRegistry ( ) ,
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
nodes . getProperties ( ) ,
force ,
! m_peerPath . empty ( ) ) ;
2008-03-06 23:23:13 +01:00
}
2009-10-09 05:16:44 +02:00
void SyncConfig : : removeSyncSource ( const string & name )
{
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
string lower = name ;
boost : : to_lower ( lower ) ;
string pathName ;
if ( m_layout = = SHARED_LAYOUT ) {
2009-11-20 13:23:15 +01:00
if ( m_peerPath . empty ( ) ) {
// removed shared source properties...
pathName = m_contextPath + " /sources/ " + lower ;
m_tree - > remove ( pathName ) ;
// ... and the peer-specific ones of *all* peers
2021-02-06 15:39:12 +01:00
for ( const std : : string & peer : m_tree - > getChildren ( m_contextPath + " /peers " ) ) {
2010-01-13 18:01:21 +01:00
m_tree - > remove ( m_contextPath + " /peers/ " + peer + " /sources/ " + lower ) ;
2009-11-20 13:23:15 +01:00
}
} else {
// remove only inside the selected peer
m_tree - > remove ( m_peerPath + " /sources/ " + lower ) ;
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
}
} else {
// remove the peer-specific ones
pathName = m_peerPath +
( m_layout = = SYNC4J_LAYOUT ? " spds/sources/ " : " sources/ " ) +
lower ;
2009-11-20 13:23:15 +01:00
m_tree - > remove ( pathName ) ;
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
}
2009-10-09 05:16:44 +02:00
}
void SyncConfig : : clearSyncSourceProperties ( const string & name )
{
SyncSourceNodes nodes = getSyncSourceNodes ( name ) ;
setDefaultProps ( SyncSourceConfig : : getRegistry ( ) ,
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
nodes . getProperties ( ) ,
true ,
! m_peerPath . empty ( ) ,
false ) ;
2009-10-09 05:16:44 +02:00
}
void SyncConfig : : clearSyncProperties ( )
{
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
setDefaultProps ( getRegistry ( ) , getProperties ( ) ,
true ,
! m_peerPath . empty ( ) ,
false ) ;
2009-10-09 05:16:44 +02:00
}
2008-03-20 23:05:10 +01:00
static void copyProperties ( const ConfigNode & fromProps ,
ConfigNode & toProps ,
bool hidden ,
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
bool unshared ,
2008-03-20 23:05:10 +01:00
const ConfigPropertyRegistry & allProps )
{
2018-01-16 10:58:04 +01:00
for ( const ConfigProperty * prop : allProps ) {
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
if ( prop - > isHidden ( ) = = hidden & &
2010-03-02 16:30:10 +01:00
( unshared | |
2011-02-03 13:00:22 +01:00
prop - > getSharing ( ) ! = ConfigProperty : : NO_SHARING ) ) {
2011-11-21 16:37:53 +01:00
InitStateString value = prop - > getProperty ( fromProps ) ;
configuration: added possibility to define property name aliases
The goal is to allow multiple names for properties. This will be used
to replace legacy names like "evolutionsource", but it could also be
used to allow abbreviations on the command line.
First the patch replaces the single ConfigProperty::m_name with a list
of names, of which the first one is the current name of the
property.
The name that is to be used depends on the node which is to be
manipulated: if it already has a property under an alias, that alias
is read and also written, so existing configuration continue to use
the old config name (avoids the problem of having to remove the old
name and insert the new one at the same spot in a .ini file). Old
configs continue to parse okay. Writing into node which has none of
the names set, as in migrating into a fresh config, uses the new
names.
Most of the patch deals with the removal of a single, unique name,
either by picking the name so that it matches a node, using the
default name or simply hard-coding a property name ("sync").
The command line accepts all aliases, then uses the main name for
overriding configuration options.
2011-01-18 15:18:21 +01:00
string name = prop - > getName ( toProps ) ;
2012-06-05 12:57:33 +02:00
toProps . setProperty ( name ,
value ,
prop - > getComment ( ) ) ;
2008-03-20 23:05:10 +01:00
}
}
}
static void copyProperties ( const ConfigNode & fromProps ,
ConfigNode & toProps )
{
2009-11-21 18:10:18 +01:00
ConfigProps props ;
2008-04-10 21:54:02 +02:00
fromProps . readProperties ( props ) ;
2009-11-21 18:10:18 +01:00
toProps . writeProperties ( props ) ;
2008-03-20 23:05:10 +01:00
}
2009-10-06 17:22:47 +02:00
void SyncConfig : : copy ( const SyncConfig & other ,
2009-12-03 16:01:32 +01:00
const set < string > * sourceSet )
2008-03-20 23:05:10 +01:00
{
for ( int i = 0 ; i < 2 ; i + + ) {
2018-01-16 17:17:34 +01:00
std : : shared_ptr < const FilterConfigNode > fromSyncProps ( other . getProperties ( i ) ) ;
std : : shared_ptr < FilterConfigNode > toSyncProps ( this - > getProperties ( i ) ) ;
2009-11-13 14:52:00 +01:00
copyProperties ( * fromSyncProps ,
* toSyncProps ,
i ,
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
! m_peerPath . empty ( ) ,
2009-11-13 14:52:00 +01:00
SyncConfig : : getRegistry ( ) ) ;
2008-03-20 23:05:10 +01:00
}
2009-12-03 16:01:32 +01:00
list < string > sources ;
if ( ! sourceSet ) {
sources = other . getSyncSources ( ) ;
} else {
2018-01-16 10:58:04 +01:00
for ( const string & sourceName : * sourceSet ) {
2009-12-03 16:01:32 +01:00
sources . push_back ( sourceName ) ;
}
}
2018-01-16 10:58:04 +01:00
for ( const string & sourceName : sources ) {
2009-12-03 16:01:32 +01:00
ConstSyncSourceNodes fromNodes = other . getSyncSourceNodes ( sourceName ) ;
SyncSourceNodes toNodes = this - > getSyncSourceNodes ( sourceName ) ;
for ( int i = 0 ; i < 2 ; i + + ) {
copyProperties ( * fromNodes . getProperties ( i ) ,
* toNodes . getProperties ( i ) ,
i ,
! m_peerPath . empty ( ) ,
SyncSourceConfig : : getRegistry ( ) ) ;
2008-03-20 23:05:10 +01:00
}
2009-12-03 16:01:32 +01:00
copyProperties ( * fromNodes . getTrackingNode ( ) ,
* toNodes . getTrackingNode ( ) ) ;
copyProperties ( * fromNodes . getServerNode ( ) ,
* toNodes . getServerNode ( ) ) ;
2008-03-20 23:05:10 +01:00
}
}
2011-11-21 16:37:53 +01:00
InitStateString SyncConfig : : getSwv ( ) const { return VERSION ; }
InitStateString SyncConfig : : getDevType ( ) const { return DEVICE_TYPE ; }
2008-03-06 23:23:13 +01:00
redesigned SyncSource base class + API
The main motivation for this change is that it allows the implementor
of a backend to choose the implementations for the different aspects
of a datasource (change tracking, item import/export, logging, ...)
independently of each other. For example, change tracking via revision
strings can now be combined with exchanging data with the Synthesis
engine via a single string (the traditional method in SyncEvolution)
and with direct access to the Synthesis field list (now possible for
the first time).
The new backend API is based on the concept of providing
implementations for certain functionality via function objects instead
of implementing certain virtual methods. The advantage is that
implementors can define their own, custom interfaces and mix and match
implementations of the different groups of functionality.
Logging (see SyncSourceLogging in a later commit) can be done by
wrapping some arbitrary other item import/export function objects
(decorator design pattern).
The class hierarchy is now this:
- SyncSourceBase: interface for common utility code, all other
classes are derived from it and thus can use that code
- SyncSource: base class which implements SyncSourceBase and
hooks a datasource into the SyncEvolution core;
its "struct Operations" holds the function objects which
can be implemented in different ways
- TestingSyncSource: combines some of the following classes
into an interface that is expected by the client-test
program; backends only have to derive from (and implement this)
if they want to use the automated testing
- TrackingSyncSource: provides the same functionality as
before (change tracking via revision strings, item import/export
as string) in a single interface; the description of the pure
virtual methods are duplicated so that developers can go through
this class and find everything they need to know to implement
it
The following classes contain the code that was previously
found in the EvolutionSyncSource base class. Implementors
can derive from them and call the init() methods to inherit
and activate the functionality:
- SyncSourceSession: binds Synthesis session callbacks to
virtual methods beginSync(), endSync()
- SyncSourceChanges: implements Synthesis item tracking callbacks
with set of LUIDs that the user of the class has to fill
- SyncSourceDelete: binds Synthesis delete callback to
virtual method
- SyncSourceRaw: read and write items in the backends format,
used for testing and backup/restore
- SyncSourceSerialize: exchanges items with Synthesis engine
using a string representation of the data; this is how
EvolutionSyncSource has traditionally worked, so much of the
same virtual methods are now in this class
- SyncSourceRevisions: utility class which does change tracking
via some kind of "revision" string which changes each time
an item is modified; this code was previously in the
TrackingSyncSource
2009-08-25 09:27:46 +02:00
SyncSourceConfig : : SyncSourceConfig ( const string & name , const SyncSourceNodes & nodes ) :
2008-03-06 23:23:13 +01:00
m_name ( name ) ,
m_nodes ( nodes )
{
}
redesigned SyncSource base class + API
The main motivation for this change is that it allows the implementor
of a backend to choose the implementations for the different aspects
of a datasource (change tracking, item import/export, logging, ...)
independently of each other. For example, change tracking via revision
strings can now be combined with exchanging data with the Synthesis
engine via a single string (the traditional method in SyncEvolution)
and with direct access to the Synthesis field list (now possible for
the first time).
The new backend API is based on the concept of providing
implementations for certain functionality via function objects instead
of implementing certain virtual methods. The advantage is that
implementors can define their own, custom interfaces and mix and match
implementations of the different groups of functionality.
Logging (see SyncSourceLogging in a later commit) can be done by
wrapping some arbitrary other item import/export function objects
(decorator design pattern).
The class hierarchy is now this:
- SyncSourceBase: interface for common utility code, all other
classes are derived from it and thus can use that code
- SyncSource: base class which implements SyncSourceBase and
hooks a datasource into the SyncEvolution core;
its "struct Operations" holds the function objects which
can be implemented in different ways
- TestingSyncSource: combines some of the following classes
into an interface that is expected by the client-test
program; backends only have to derive from (and implement this)
if they want to use the automated testing
- TrackingSyncSource: provides the same functionality as
before (change tracking via revision strings, item import/export
as string) in a single interface; the description of the pure
virtual methods are duplicated so that developers can go through
this class and find everything they need to know to implement
it
The following classes contain the code that was previously
found in the EvolutionSyncSource base class. Implementors
can derive from them and call the init() methods to inherit
and activate the functionality:
- SyncSourceSession: binds Synthesis session callbacks to
virtual methods beginSync(), endSync()
- SyncSourceChanges: implements Synthesis item tracking callbacks
with set of LUIDs that the user of the class has to fill
- SyncSourceDelete: binds Synthesis delete callback to
virtual method
- SyncSourceRaw: read and write items in the backends format,
used for testing and backup/restore
- SyncSourceSerialize: exchanges items with Synthesis engine
using a string representation of the data; this is how
EvolutionSyncSource has traditionally worked, so much of the
same virtual methods are now in this class
- SyncSourceRevisions: utility class which does change tracking
via some kind of "revision" string which changes each time
an item is modified; this code was previously in the
TrackingSyncSource
2009-08-25 09:27:46 +02:00
StringConfigProperty SyncSourceConfig : : m_sourcePropSync ( " sync " ,
2011-10-19 17:15:50 +02:00
" Requests a certain synchronization mode when initiating a sync: \n \n "
" two-way \n "
" only send/receive changes since last sync \n "
" slow \n "
" exchange all items \n "
2011-10-24 19:52:01 +02:00
" refresh-from-remote \n "
" discard all local items and replace with \n "
" the items on the peer \n "
" refresh-from-local \n "
" discard all items on the peer and replace \n "
" with the local items \n "
" one-way-from-remote \n "
" transmit changes from peer \n "
" one-way-from-local \n "
" transmit local changes \n "
engine: local cache sync mode
This patch introduces support for true one-way syncing ("caching"):
the local datastore is meant to be an exact copy of the data on the
remote side. The assumption is that no modifications are ever made
locally outside of syncing. This is different from one-way sync modes,
which allows local changes and only temporarily disables sending them
to the remote side.
Another goal of the new mode is to avoid data writes as much as
possible.
This new mode only works on the server side of a sync, where the
engine has enough control over the data flow.
Most of the changes are in libsynthesis. SyncEvolution only needs to
enable the new mode, which is done via an extension of the "sync"
property:
- "local-cache-incremental" will do an incremental sync (if possible)
or a slow sync (otherwise). This is usually the right mode to use,
and thus has "local-cache" as alias.
- "local-cache-slow" will always do a slow sync. Useful for
debugging or after (accidentally) making changes on the server side.
An incremental sync will ignore such changes because they are not
meant to happen and thus leave client and sync out-of-sync!
Both modes are recorded in the sync report of the local side. The
target side is the client and records the normal "two-way" or "slow"
sync modes.
With the current SyncEvolution contact field list, first, middle and
last name are used to find matches during any kind of slow sync. The
organization field is ignored for matching during the initial slow
sync and used in all following ones. That's okay, the difference won't
matter in practice because the initial slow sync in PBAP caching will
be done with no local data. The test achieve the same result in both
cases by keeping the organization set in the reduced data set.
It's also okay to include the property in the comparison, because it
might help to distinguish between "John Doe" in different companies.
It might be worthwhile to add more fields as match criteria, for
example the birthday. Currently they are excluded, probably because
they are not trusted to be supported by SyncML peers. In caching mode
the situation is different, because all our data came from the peer.
The downside is that in cases where matching has to be done all the
time because change detection is not supported (PBAP), including the
birthday as criteria will cause unnecessary contact removed/added
events (and thus disk IO) when a contact was originally created
without birthday locally and then a birthday gets added on the phone.
Testing is done as part of the D-Bus testing framework, because usually
this functionality will be used as part of the D-Bus server and writing
tests in Python is easier.
A new test class "TestLocalCache" contains the new tests. They include
tests for removing extra items during a slow sync (testItemRemoval),
adding new client items under various conditions (testItemAdd*) and
updating/removing an item during incremental syncing
(testItemUpdate/Delete*). Doing these changes during a slow sync could
also be tested (not currently covered).
The tests for removing properties (testPropertyRemoval*) cover
removing almost all contact properties during an initial slow sync, a
second slow sync (which is treated differently in libsynthesis, see
merge=always and merge=slowsync), and an incremental sync.
2012-08-23 14:25:55 +02:00
" local-cache-slow (server only) \n "
" mirror remote data locally, transferring all data \n "
" local-cache-incremental (server only) \n "
" mirror remote data locally, transferring only changes; \n "
" falls back to local-cache-slow automatically if necessary \n "
2011-10-19 17:15:50 +02:00
" disabled (or none) \n "
2011-10-24 19:52:01 +02:00
" synchronization disabled \n "
" \n "
" refresh/one-way-from-server/client are also supported. Their use is \n "
" discouraged because the direction of the data transfer depends \n "
" on the role of the local side (can be server or client), which is \n "
" not always obvious. \n "
" \n "
2010-09-07 16:56:58 +02:00
" When accepting a sync session in a SyncML server (HTTP server), only \n "
2014-07-28 15:29:41 +02:00
" datastores with sync != disabled are made available to the client, \n "
2010-09-07 16:56:58 +02:00
" which chooses the final sync mode based on its own configuration. \n "
" When accepting a sync session in a SyncML client (local sync with \n "
" the server contacting SyncEvolution on a device), the sync mode \n "
" specified in the client is typically overriden by the server. \n " ,
2010-01-29 21:16:00 +01:00
" disabled " ,
2009-09-21 10:07:05 +02:00
" " ,
2008-03-19 12:29:14 +01:00
Values ( ) +
( Aliases ( " two-way " ) ) +
( Aliases ( " slow " ) ) +
2011-10-24 19:52:01 +02:00
( Aliases ( " refresh-from-local " ) ) +
( Aliases ( " refresh-from-remote " ) + " refresh " ) +
( Aliases ( " one-way-from-local " ) ) +
( Aliases ( " one-way-from-remote " ) + " one-way " ) +
2008-03-19 12:29:14 +01:00
( Aliases ( " refresh-from-client " ) + " refresh-client " ) +
2011-10-24 19:52:01 +02:00
( Aliases ( " refresh-from-server " ) + " refresh-server " ) +
2008-03-19 12:29:14 +01:00
( Aliases ( " one-way-from-client " ) + " one-way-client " ) +
2011-10-24 19:52:01 +02:00
( Aliases ( " one-way-from-server " ) + " one-way-server " ) +
engine: local cache sync mode
This patch introduces support for true one-way syncing ("caching"):
the local datastore is meant to be an exact copy of the data on the
remote side. The assumption is that no modifications are ever made
locally outside of syncing. This is different from one-way sync modes,
which allows local changes and only temporarily disables sending them
to the remote side.
Another goal of the new mode is to avoid data writes as much as
possible.
This new mode only works on the server side of a sync, where the
engine has enough control over the data flow.
Most of the changes are in libsynthesis. SyncEvolution only needs to
enable the new mode, which is done via an extension of the "sync"
property:
- "local-cache-incremental" will do an incremental sync (if possible)
or a slow sync (otherwise). This is usually the right mode to use,
and thus has "local-cache" as alias.
- "local-cache-slow" will always do a slow sync. Useful for
debugging or after (accidentally) making changes on the server side.
An incremental sync will ignore such changes because they are not
meant to happen and thus leave client and sync out-of-sync!
Both modes are recorded in the sync report of the local side. The
target side is the client and records the normal "two-way" or "slow"
sync modes.
With the current SyncEvolution contact field list, first, middle and
last name are used to find matches during any kind of slow sync. The
organization field is ignored for matching during the initial slow
sync and used in all following ones. That's okay, the difference won't
matter in practice because the initial slow sync in PBAP caching will
be done with no local data. The test achieve the same result in both
cases by keeping the organization set in the reduced data set.
It's also okay to include the property in the comparison, because it
might help to distinguish between "John Doe" in different companies.
It might be worthwhile to add more fields as match criteria, for
example the birthday. Currently they are excluded, probably because
they are not trusted to be supported by SyncML peers. In caching mode
the situation is different, because all our data came from the peer.
The downside is that in cases where matching has to be done all the
time because change detection is not supported (PBAP), including the
birthday as criteria will cause unnecessary contact removed/added
events (and thus disk IO) when a contact was originally created
without birthday locally and then a birthday gets added on the phone.
Testing is done as part of the D-Bus testing framework, because usually
this functionality will be used as part of the D-Bus server and writing
tests in Python is easier.
A new test class "TestLocalCache" contains the new tests. They include
tests for removing extra items during a slow sync (testItemRemoval),
adding new client items under various conditions (testItemAdd*) and
updating/removing an item during incremental syncing
(testItemUpdate/Delete*). Doing these changes during a slow sync could
also be tested (not currently covered).
The tests for removing properties (testPropertyRemoval*) cover
removing almost all contact properties during an initial slow sync, a
second slow sync (which is treated differently in libsynthesis, see
merge=always and merge=slowsync), and an incremental sync.
2012-08-23 14:25:55 +02:00
( Aliases ( " local-cache-slow " ) ) +
( Aliases ( " local-cache-incremental " ) + " local-cache " ) +
2008-03-19 12:29:14 +01:00
( Aliases ( " disabled " ) + " none " ) ) ;
config: replaced overloaded "type" with "backend/databaseFormat/syncFormat/forceSyncFormat" (BMC #1023)
The meaning of "type" was horribly complex and had effects on the
backend and the peer. It was impossible to specify the sync format to
be used for a specific peer independently of the local backend and its
format, so adding a peer to a context broke the context configuration
(BMC #1023).
This is now fixed by splitting "type" into four independent properties:
- backend = plugin which interfaces with the data
- databaseFormat = data format used inside backend, only relevant for file backend
- syncFormat = data format preferred when talking to peer
- forceSyncFormat = disable format auto-negotiation, use preferred format
With that split, it is now possible to specify the format in which the
file backend stores items independently of the format in which they
are exchanged with the peer.
Old configurations with "type" can still be read. The values specified
inside it are transparently mapped to the new properties. Command line
and D-Bus API users will only see the new properties.
The command line tool still accepts "type" as an alias for the four new
properties. Using that has the same disadvantage as before: it will modify
the context even if only modifying the peer was intended.
The D-Bus API accepts only the new properties. Clients using "type"
must be adapted to the new property names. Clients not using that
continue to run unchanged.
Writing into the configuration requires a migration of the peer config
*and* the context in which it is defined. That is necessary because
the new semantic (independent database format) cannot be stored in the
old format. The migration is handled by rewriting first the context,
then all peers defined inside it.
Other user-visible changes:
- updated help texts
- the canonical "backend" value for the file backend is just "file"
instead of the long "Files in one directory", which is now an alias
(used to be the other way around); done because "type = file"
was expanded to the long name, which was a bit unexpected and showed
how unintuitive the long name is
Internal changes:
- getMimeVersion() is still present, although it hasn't been used
for a long time; FileSyncSource::getMimeVersion() now derives
the version from the supported Mime types, in case that the
function will be needed again in the future
- setSourceType() with string as argument was replaced with one
taking a SourceType instance; to emulate the old behavior if
desired, construct SourceType from an old-style string
- ConfigProperty methods need to be virtual so that derived classes
like SourceBackendConfigProperty can generate content at runtime
(a recent commit broke that feature)
- File templates were stripped down to the essential properties,
with "type" replaced by the per-peer "syncFormat". "type" would
still have been accepted (so it is not necessary to adapt
syncevo-phone-config right away), but has the original
disadvantage of modifying "backend" and "databaseFormat".
2011-02-03 12:17:24 +01:00
static class SourceBackendConfigProperty : public StringConfigProperty {
2008-03-10 23:45:36 +01:00
public :
config: replaced overloaded "type" with "backend/databaseFormat/syncFormat/forceSyncFormat" (BMC #1023)
The meaning of "type" was horribly complex and had effects on the
backend and the peer. It was impossible to specify the sync format to
be used for a specific peer independently of the local backend and its
format, so adding a peer to a context broke the context configuration
(BMC #1023).
This is now fixed by splitting "type" into four independent properties:
- backend = plugin which interfaces with the data
- databaseFormat = data format used inside backend, only relevant for file backend
- syncFormat = data format preferred when talking to peer
- forceSyncFormat = disable format auto-negotiation, use preferred format
With that split, it is now possible to specify the format in which the
file backend stores items independently of the format in which they
are exchanged with the peer.
Old configurations with "type" can still be read. The values specified
inside it are transparently mapped to the new properties. Command line
and D-Bus API users will only see the new properties.
The command line tool still accepts "type" as an alias for the four new
properties. Using that has the same disadvantage as before: it will modify
the context even if only modifying the peer was intended.
The D-Bus API accepts only the new properties. Clients using "type"
must be adapted to the new property names. Clients not using that
continue to run unchanged.
Writing into the configuration requires a migration of the peer config
*and* the context in which it is defined. That is necessary because
the new semantic (independent database format) cannot be stored in the
old format. The migration is handled by rewriting first the context,
then all peers defined inside it.
Other user-visible changes:
- updated help texts
- the canonical "backend" value for the file backend is just "file"
instead of the long "Files in one directory", which is now an alias
(used to be the other way around); done because "type = file"
was expanded to the long name, which was a bit unexpected and showed
how unintuitive the long name is
Internal changes:
- getMimeVersion() is still present, although it hasn't been used
for a long time; FileSyncSource::getMimeVersion() now derives
the version from the supported Mime types, in case that the
function will be needed again in the future
- setSourceType() with string as argument was replaced with one
taking a SourceType instance; to emulate the old behavior if
desired, construct SourceType from an old-style string
- ConfigProperty methods need to be virtual so that derived classes
like SourceBackendConfigProperty can generate content at runtime
(a recent commit broke that feature)
- File templates were stripped down to the essential properties,
with "type" replaced by the per-peer "syncFormat". "type" would
still have been accepted (so it is not necessary to adapt
syncevo-phone-config right away), but has the original
disadvantage of modifying "backend" and "databaseFormat".
2011-02-03 12:17:24 +01:00
SourceBackendConfigProperty ( ) :
StringConfigProperty ( " backend " ,
2008-03-10 23:45:36 +01:00
" Specifies the SyncEvolution backend and thus the \n "
2014-07-28 15:29:41 +02:00
" data which is synchronized by this datastore. Each \n "
config: replaced overloaded "type" with "backend/databaseFormat/syncFormat/forceSyncFormat" (BMC #1023)
The meaning of "type" was horribly complex and had effects on the
backend and the peer. It was impossible to specify the sync format to
be used for a specific peer independently of the local backend and its
format, so adding a peer to a context broke the context configuration
(BMC #1023).
This is now fixed by splitting "type" into four independent properties:
- backend = plugin which interfaces with the data
- databaseFormat = data format used inside backend, only relevant for file backend
- syncFormat = data format preferred when talking to peer
- forceSyncFormat = disable format auto-negotiation, use preferred format
With that split, it is now possible to specify the format in which the
file backend stores items independently of the format in which they
are exchanged with the peer.
Old configurations with "type" can still be read. The values specified
inside it are transparently mapped to the new properties. Command line
and D-Bus API users will only see the new properties.
The command line tool still accepts "type" as an alias for the four new
properties. Using that has the same disadvantage as before: it will modify
the context even if only modifying the peer was intended.
The D-Bus API accepts only the new properties. Clients using "type"
must be adapted to the new property names. Clients not using that
continue to run unchanged.
Writing into the configuration requires a migration of the peer config
*and* the context in which it is defined. That is necessary because
the new semantic (independent database format) cannot be stored in the
old format. The migration is handled by rewriting first the context,
then all peers defined inside it.
Other user-visible changes:
- updated help texts
- the canonical "backend" value for the file backend is just "file"
instead of the long "Files in one directory", which is now an alias
(used to be the other way around); done because "type = file"
was expanded to the long name, which was a bit unexpected and showed
how unintuitive the long name is
Internal changes:
- getMimeVersion() is still present, although it hasn't been used
for a long time; FileSyncSource::getMimeVersion() now derives
the version from the supported Mime types, in case that the
function will be needed again in the future
- setSourceType() with string as argument was replaced with one
taking a SourceType instance; to emulate the old behavior if
desired, construct SourceType from an old-style string
- ConfigProperty methods need to be virtual so that derived classes
like SourceBackendConfigProperty can generate content at runtime
(a recent commit broke that feature)
- File templates were stripped down to the essential properties,
with "type" replaced by the per-peer "syncFormat". "type" would
still have been accepted (so it is not necessary to adapt
syncevo-phone-config right away), but has the original
disadvantage of modifying "backend" and "databaseFormat".
2011-02-03 12:17:24 +01:00
" backend may support multiple databases (see 'database' \n "
" property), different formats inside that database (see \n "
" 'databaseFormat'), and different formats when talking to \n "
" the sync peer (see 'syncFormat' and 'forceSyncFormat'). \n "
2010-01-20 11:36:19 +01:00
" \n "
2009-11-23 02:43:56 +01:00
" A special 'virtual' backend combines several other \n "
2014-07-28 15:29:41 +02:00
" datastores and presents them as one set of items \n "
2009-11-23 02:43:56 +01:00
" to the peer. For example, Nokia phones typically \n "
" exchange tasks and events as part of one set of \n "
" calendar items. \n "
" \n "
" Right now such a virtual backend is limited to \n "
2014-07-28 15:29:41 +02:00
" combining one calendar datastore with events and one \n "
" task datastore. They have to be specified in the \n "
2011-10-19 17:15:50 +02:00
" ``database`` property, typically like this: \n "
" ``calendar,todo`` \n "
2009-11-23 02:43:56 +01:00
" \n "
2014-07-28 15:29:41 +02:00
" Different datastores combined in one virtual datastore must \n "
config: replaced overloaded "type" with "backend/databaseFormat/syncFormat/forceSyncFormat" (BMC #1023)
The meaning of "type" was horribly complex and had effects on the
backend and the peer. It was impossible to specify the sync format to
be used for a specific peer independently of the local backend and its
format, so adding a peer to a context broke the context configuration
(BMC #1023).
This is now fixed by splitting "type" into four independent properties:
- backend = plugin which interfaces with the data
- databaseFormat = data format used inside backend, only relevant for file backend
- syncFormat = data format preferred when talking to peer
- forceSyncFormat = disable format auto-negotiation, use preferred format
With that split, it is now possible to specify the format in which the
file backend stores items independently of the format in which they
are exchanged with the peer.
Old configurations with "type" can still be read. The values specified
inside it are transparently mapped to the new properties. Command line
and D-Bus API users will only see the new properties.
The command line tool still accepts "type" as an alias for the four new
properties. Using that has the same disadvantage as before: it will modify
the context even if only modifying the peer was intended.
The D-Bus API accepts only the new properties. Clients using "type"
must be adapted to the new property names. Clients not using that
continue to run unchanged.
Writing into the configuration requires a migration of the peer config
*and* the context in which it is defined. That is necessary because
the new semantic (independent database format) cannot be stored in the
old format. The migration is handled by rewriting first the context,
then all peers defined inside it.
Other user-visible changes:
- updated help texts
- the canonical "backend" value for the file backend is just "file"
instead of the long "Files in one directory", which is now an alias
(used to be the other way around); done because "type = file"
was expanded to the long name, which was a bit unexpected and showed
how unintuitive the long name is
Internal changes:
- getMimeVersion() is still present, although it hasn't been used
for a long time; FileSyncSource::getMimeVersion() now derives
the version from the supported Mime types, in case that the
function will be needed again in the future
- setSourceType() with string as argument was replaced with one
taking a SourceType instance; to emulate the old behavior if
desired, construct SourceType from an old-style string
- ConfigProperty methods need to be virtual so that derived classes
like SourceBackendConfigProperty can generate content at runtime
(a recent commit broke that feature)
- File templates were stripped down to the essential properties,
with "type" replaced by the per-peer "syncFormat". "type" would
still have been accepted (so it is not necessary to adapt
syncevo-phone-config right away), but has the original
disadvantage of modifying "backend" and "databaseFormat".
2011-02-03 12:17:24 +01:00
" have a common format. As with other backends, \n "
" the preferred format can be influenced via the 'syncFormat' \n "
2009-11-23 02:43:56 +01:00
" attribute. \n "
2010-09-13 08:05:26 +02:00
" \n "
2008-03-10 23:45:36 +01:00
" Here's the full list of potentially supported backends, \n "
config: replaced overloaded "type" with "backend/databaseFormat/syncFormat/forceSyncFormat" (BMC #1023)
The meaning of "type" was horribly complex and had effects on the
backend and the peer. It was impossible to specify the sync format to
be used for a specific peer independently of the local backend and its
format, so adding a peer to a context broke the context configuration
(BMC #1023).
This is now fixed by splitting "type" into four independent properties:
- backend = plugin which interfaces with the data
- databaseFormat = data format used inside backend, only relevant for file backend
- syncFormat = data format preferred when talking to peer
- forceSyncFormat = disable format auto-negotiation, use preferred format
With that split, it is now possible to specify the format in which the
file backend stores items independently of the format in which they
are exchanged with the peer.
Old configurations with "type" can still be read. The values specified
inside it are transparently mapped to the new properties. Command line
and D-Bus API users will only see the new properties.
The command line tool still accepts "type" as an alias for the four new
properties. Using that has the same disadvantage as before: it will modify
the context even if only modifying the peer was intended.
The D-Bus API accepts only the new properties. Clients using "type"
must be adapted to the new property names. Clients not using that
continue to run unchanged.
Writing into the configuration requires a migration of the peer config
*and* the context in which it is defined. That is necessary because
the new semantic (independent database format) cannot be stored in the
old format. The migration is handled by rewriting first the context,
then all peers defined inside it.
Other user-visible changes:
- updated help texts
- the canonical "backend" value for the file backend is just "file"
instead of the long "Files in one directory", which is now an alias
(used to be the other way around); done because "type = file"
was expanded to the long name, which was a bit unexpected and showed
how unintuitive the long name is
Internal changes:
- getMimeVersion() is still present, although it hasn't been used
for a long time; FileSyncSource::getMimeVersion() now derives
the version from the supported Mime types, in case that the
function will be needed again in the future
- setSourceType() with string as argument was replaced with one
taking a SourceType instance; to emulate the old behavior if
desired, construct SourceType from an old-style string
- ConfigProperty methods need to be virtual so that derived classes
like SourceBackendConfigProperty can generate content at runtime
(a recent commit broke that feature)
- File templates were stripped down to the essential properties,
with "type" replaced by the per-peer "syncFormat". "type" would
still have been accepted (so it is not necessary to adapt
syncevo-phone-config right away), but has the original
disadvantage of modifying "backend" and "databaseFormat".
2011-02-03 12:17:24 +01:00
" valid 'backend' values for each of them, and possible \n "
2008-03-10 23:45:36 +01:00
" formats. Note that SyncEvolution installations usually \n "
" support only a subset of the backends; that's why e.g. \n "
2008-03-30 20:39:15 +02:00
" \" addressbook \" is unambiguous although there are multiple \n "
config: replaced overloaded "type" with "backend/databaseFormat/syncFormat/forceSyncFormat" (BMC #1023)
The meaning of "type" was horribly complex and had effects on the
backend and the peer. It was impossible to specify the sync format to
be used for a specific peer independently of the local backend and its
format, so adding a peer to a context broke the context configuration
(BMC #1023).
This is now fixed by splitting "type" into four independent properties:
- backend = plugin which interfaces with the data
- databaseFormat = data format used inside backend, only relevant for file backend
- syncFormat = data format preferred when talking to peer
- forceSyncFormat = disable format auto-negotiation, use preferred format
With that split, it is now possible to specify the format in which the
file backend stores items independently of the format in which they
are exchanged with the peer.
Old configurations with "type" can still be read. The values specified
inside it are transparently mapped to the new properties. Command line
and D-Bus API users will only see the new properties.
The command line tool still accepts "type" as an alias for the four new
properties. Using that has the same disadvantage as before: it will modify
the context even if only modifying the peer was intended.
The D-Bus API accepts only the new properties. Clients using "type"
must be adapted to the new property names. Clients not using that
continue to run unchanged.
Writing into the configuration requires a migration of the peer config
*and* the context in which it is defined. That is necessary because
the new semantic (independent database format) cannot be stored in the
old format. The migration is handled by rewriting first the context,
then all peers defined inside it.
Other user-visible changes:
- updated help texts
- the canonical "backend" value for the file backend is just "file"
instead of the long "Files in one directory", which is now an alias
(used to be the other way around); done because "type = file"
was expanded to the long name, which was a bit unexpected and showed
how unintuitive the long name is
Internal changes:
- getMimeVersion() is still present, although it hasn't been used
for a long time; FileSyncSource::getMimeVersion() now derives
the version from the supported Mime types, in case that the
function will be needed again in the future
- setSourceType() with string as argument was replaced with one
taking a SourceType instance; to emulate the old behavior if
desired, construct SourceType from an old-style string
- ConfigProperty methods need to be virtual so that derived classes
like SourceBackendConfigProperty can generate content at runtime
(a recent commit broke that feature)
- File templates were stripped down to the essential properties,
with "type" replaced by the per-peer "syncFormat". "type" would
still have been accepted (so it is not necessary to adapt
syncevo-phone-config right away), but has the original
disadvantage of modifying "backend" and "databaseFormat".
2011-02-03 12:17:24 +01:00
" address book backends. \n "
" \n " ,
2008-03-10 23:45:36 +01:00
" select backend " ,
2009-09-21 10:07:05 +02:00
" " ,
2008-03-10 23:45:36 +01:00
Values ( ) +
2009-11-23 02:43:56 +01:00
( Aliases ( " virtual " ) ) +
2008-03-10 23:45:36 +01:00
( Aliases ( " calendar " ) + " events " ) +
( Aliases ( " addressbook " ) + " contacts " ) +
config: replaced overloaded "type" with "backend/databaseFormat/syncFormat/forceSyncFormat" (BMC #1023)
The meaning of "type" was horribly complex and had effects on the
backend and the peer. It was impossible to specify the sync format to
be used for a specific peer independently of the local backend and its
format, so adding a peer to a context broke the context configuration
(BMC #1023).
This is now fixed by splitting "type" into four independent properties:
- backend = plugin which interfaces with the data
- databaseFormat = data format used inside backend, only relevant for file backend
- syncFormat = data format preferred when talking to peer
- forceSyncFormat = disable format auto-negotiation, use preferred format
With that split, it is now possible to specify the format in which the
file backend stores items independently of the format in which they
are exchanged with the peer.
Old configurations with "type" can still be read. The values specified
inside it are transparently mapped to the new properties. Command line
and D-Bus API users will only see the new properties.
The command line tool still accepts "type" as an alias for the four new
properties. Using that has the same disadvantage as before: it will modify
the context even if only modifying the peer was intended.
The D-Bus API accepts only the new properties. Clients using "type"
must be adapted to the new property names. Clients not using that
continue to run unchanged.
Writing into the configuration requires a migration of the peer config
*and* the context in which it is defined. That is necessary because
the new semantic (independent database format) cannot be stored in the
old format. The migration is handled by rewriting first the context,
then all peers defined inside it.
Other user-visible changes:
- updated help texts
- the canonical "backend" value for the file backend is just "file"
instead of the long "Files in one directory", which is now an alias
(used to be the other way around); done because "type = file"
was expanded to the long name, which was a bit unexpected and showed
how unintuitive the long name is
Internal changes:
- getMimeVersion() is still present, although it hasn't been used
for a long time; FileSyncSource::getMimeVersion() now derives
the version from the supported Mime types, in case that the
function will be needed again in the future
- setSourceType() with string as argument was replaced with one
taking a SourceType instance; to emulate the old behavior if
desired, construct SourceType from an old-style string
- ConfigProperty methods need to be virtual so that derived classes
like SourceBackendConfigProperty can generate content at runtime
(a recent commit broke that feature)
- File templates were stripped down to the essential properties,
with "type" replaced by the per-peer "syncFormat". "type" would
still have been accepted (so it is not necessary to adapt
syncevo-phone-config right away), but has the original
disadvantage of modifying "backend" and "databaseFormat".
2011-02-03 12:17:24 +01:00
( Aliases ( " todo " ) + " tasks " ) +
( Aliases ( " memo " ) + " memos " + " notes " ) )
2008-03-10 23:45:36 +01:00
{ }
virtual string getComment ( ) const {
stringstream enabled , disabled ;
stringstream res ;
redesigned SyncSource base class + API
The main motivation for this change is that it allows the implementor
of a backend to choose the implementations for the different aspects
of a datasource (change tracking, item import/export, logging, ...)
independently of each other. For example, change tracking via revision
strings can now be combined with exchanging data with the Synthesis
engine via a single string (the traditional method in SyncEvolution)
and with direct access to the Synthesis field list (now possible for
the first time).
The new backend API is based on the concept of providing
implementations for certain functionality via function objects instead
of implementing certain virtual methods. The advantage is that
implementors can define their own, custom interfaces and mix and match
implementations of the different groups of functionality.
Logging (see SyncSourceLogging in a later commit) can be done by
wrapping some arbitrary other item import/export function objects
(decorator design pattern).
The class hierarchy is now this:
- SyncSourceBase: interface for common utility code, all other
classes are derived from it and thus can use that code
- SyncSource: base class which implements SyncSourceBase and
hooks a datasource into the SyncEvolution core;
its "struct Operations" holds the function objects which
can be implemented in different ways
- TestingSyncSource: combines some of the following classes
into an interface that is expected by the client-test
program; backends only have to derive from (and implement this)
if they want to use the automated testing
- TrackingSyncSource: provides the same functionality as
before (change tracking via revision strings, item import/export
as string) in a single interface; the description of the pure
virtual methods are duplicated so that developers can go through
this class and find everything they need to know to implement
it
The following classes contain the code that was previously
found in the EvolutionSyncSource base class. Implementors
can derive from them and call the init() methods to inherit
and activate the functionality:
- SyncSourceSession: binds Synthesis session callbacks to
virtual methods beginSync(), endSync()
- SyncSourceChanges: implements Synthesis item tracking callbacks
with set of LUIDs that the user of the class has to fill
- SyncSourceDelete: binds Synthesis delete callback to
virtual method
- SyncSourceRaw: read and write items in the backends format,
used for testing and backup/restore
- SyncSourceSerialize: exchanges items with Synthesis engine
using a string representation of the data; this is how
EvolutionSyncSource has traditionally worked, so much of the
same virtual methods are now in this class
- SyncSourceRevisions: utility class which does change tracking
via some kind of "revision" string which changes each time
an item is modified; this code was previously in the
TrackingSyncSource
2009-08-25 09:27:46 +02:00
SourceRegistry & registry ( SyncSource : : getSourceRegistry ( ) ) ;
2018-01-16 10:58:04 +01:00
for ( const RegisterSyncSource * sourceInfos : registry ) {
2011-10-26 08:40:39 +02:00
static const std : : string whitespace ( " \t \n " ) ;
2011-10-19 17:15:50 +02:00
string comment = boost : : trim_right_copy_if ( sourceInfos - > m_typeDescr ,
2011-10-26 08:40:39 +02:00
boost : : is_any_of ( whitespace ) ) ;
2008-07-11 22:25:02 +02:00
stringstream * curr = sourceInfos - > m_enabled ? & enabled : & disabled ;
2011-10-19 17:15:50 +02:00
boost : : replace_all ( comment , " \n " , " \n " ) ;
* curr < < " " < < comment < < " \n " ;
2008-03-10 23:45:36 +01:00
}
res < < StringConfigProperty : : getComment ( ) ;
if ( enabled . str ( ) . size ( ) ) {
2011-10-19 17:15:50 +02:00
res < < " \n \n Currently active:: \n \n " < < enabled . str ( ) ;
2008-03-10 23:45:36 +01:00
}
if ( disabled . str ( ) . size ( ) ) {
2011-10-19 17:15:50 +02:00
res < < " \n \n Currently inactive:: \n \n " < < disabled . str ( ) ;
2008-03-10 23:45:36 +01:00
}
2008-03-30 21:08:19 +02:00
return boost : : trim_right_copy ( res . str ( ) ) ;
2008-03-10 23:45:36 +01:00
}
virtual Values getValues ( ) const {
Values res ( StringConfigProperty : : getValues ( ) ) ;
redesigned SyncSource base class + API
The main motivation for this change is that it allows the implementor
of a backend to choose the implementations for the different aspects
of a datasource (change tracking, item import/export, logging, ...)
independently of each other. For example, change tracking via revision
strings can now be combined with exchanging data with the Synthesis
engine via a single string (the traditional method in SyncEvolution)
and with direct access to the Synthesis field list (now possible for
the first time).
The new backend API is based on the concept of providing
implementations for certain functionality via function objects instead
of implementing certain virtual methods. The advantage is that
implementors can define their own, custom interfaces and mix and match
implementations of the different groups of functionality.
Logging (see SyncSourceLogging in a later commit) can be done by
wrapping some arbitrary other item import/export function objects
(decorator design pattern).
The class hierarchy is now this:
- SyncSourceBase: interface for common utility code, all other
classes are derived from it and thus can use that code
- SyncSource: base class which implements SyncSourceBase and
hooks a datasource into the SyncEvolution core;
its "struct Operations" holds the function objects which
can be implemented in different ways
- TestingSyncSource: combines some of the following classes
into an interface that is expected by the client-test
program; backends only have to derive from (and implement this)
if they want to use the automated testing
- TrackingSyncSource: provides the same functionality as
before (change tracking via revision strings, item import/export
as string) in a single interface; the description of the pure
virtual methods are duplicated so that developers can go through
this class and find everything they need to know to implement
it
The following classes contain the code that was previously
found in the EvolutionSyncSource base class. Implementors
can derive from them and call the init() methods to inherit
and activate the functionality:
- SyncSourceSession: binds Synthesis session callbacks to
virtual methods beginSync(), endSync()
- SyncSourceChanges: implements Synthesis item tracking callbacks
with set of LUIDs that the user of the class has to fill
- SyncSourceDelete: binds Synthesis delete callback to
virtual method
- SyncSourceRaw: read and write items in the backends format,
used for testing and backup/restore
- SyncSourceSerialize: exchanges items with Synthesis engine
using a string representation of the data; this is how
EvolutionSyncSource has traditionally worked, so much of the
same virtual methods are now in this class
- SyncSourceRevisions: utility class which does change tracking
via some kind of "revision" string which changes each time
an item is modified; this code was previously in the
TrackingSyncSource
2009-08-25 09:27:46 +02:00
const SourceRegistry & registry ( SyncSource : : getSourceRegistry ( ) ) ;
2018-01-16 10:58:04 +01:00
for ( const RegisterSyncSource * sourceInfos : registry ) {
2008-07-11 22:25:02 +02:00
copy ( sourceInfos - > m_typeValues . begin ( ) ,
sourceInfos - > m_typeValues . end ( ) ,
back_inserter ( res ) ) ;
2008-03-10 23:45:36 +01:00
}
return res ;
}
config: replaced overloaded "type" with "backend/databaseFormat/syncFormat/forceSyncFormat" (BMC #1023)
The meaning of "type" was horribly complex and had effects on the
backend and the peer. It was impossible to specify the sync format to
be used for a specific peer independently of the local backend and its
format, so adding a peer to a context broke the context configuration
(BMC #1023).
This is now fixed by splitting "type" into four independent properties:
- backend = plugin which interfaces with the data
- databaseFormat = data format used inside backend, only relevant for file backend
- syncFormat = data format preferred when talking to peer
- forceSyncFormat = disable format auto-negotiation, use preferred format
With that split, it is now possible to specify the format in which the
file backend stores items independently of the format in which they
are exchanged with the peer.
Old configurations with "type" can still be read. The values specified
inside it are transparently mapped to the new properties. Command line
and D-Bus API users will only see the new properties.
The command line tool still accepts "type" as an alias for the four new
properties. Using that has the same disadvantage as before: it will modify
the context even if only modifying the peer was intended.
The D-Bus API accepts only the new properties. Clients using "type"
must be adapted to the new property names. Clients not using that
continue to run unchanged.
Writing into the configuration requires a migration of the peer config
*and* the context in which it is defined. That is necessary because
the new semantic (independent database format) cannot be stored in the
old format. The migration is handled by rewriting first the context,
then all peers defined inside it.
Other user-visible changes:
- updated help texts
- the canonical "backend" value for the file backend is just "file"
instead of the long "Files in one directory", which is now an alias
(used to be the other way around); done because "type = file"
was expanded to the long name, which was a bit unexpected and showed
how unintuitive the long name is
Internal changes:
- getMimeVersion() is still present, although it hasn't been used
for a long time; FileSyncSource::getMimeVersion() now derives
the version from the supported Mime types, in case that the
function will be needed again in the future
- setSourceType() with string as argument was replaced with one
taking a SourceType instance; to emulate the old behavior if
desired, construct SourceType from an old-style string
- ConfigProperty methods need to be virtual so that derived classes
like SourceBackendConfigProperty can generate content at runtime
(a recent commit broke that feature)
- File templates were stripped down to the essential properties,
with "type" replaced by the per-peer "syncFormat". "type" would
still have been accepted (so it is not necessary to adapt
syncevo-phone-config right away), but has the original
disadvantage of modifying "backend" and "databaseFormat".
2011-02-03 12:17:24 +01:00
} sourcePropBackend ;
2008-03-06 23:23:13 +01:00
config: replaced overloaded "type" with "backend/databaseFormat/syncFormat/forceSyncFormat" (BMC #1023)
The meaning of "type" was horribly complex and had effects on the
backend and the peer. It was impossible to specify the sync format to
be used for a specific peer independently of the local backend and its
format, so adding a peer to a context broke the context configuration
(BMC #1023).
This is now fixed by splitting "type" into four independent properties:
- backend = plugin which interfaces with the data
- databaseFormat = data format used inside backend, only relevant for file backend
- syncFormat = data format preferred when talking to peer
- forceSyncFormat = disable format auto-negotiation, use preferred format
With that split, it is now possible to specify the format in which the
file backend stores items independently of the format in which they
are exchanged with the peer.
Old configurations with "type" can still be read. The values specified
inside it are transparently mapped to the new properties. Command line
and D-Bus API users will only see the new properties.
The command line tool still accepts "type" as an alias for the four new
properties. Using that has the same disadvantage as before: it will modify
the context even if only modifying the peer was intended.
The D-Bus API accepts only the new properties. Clients using "type"
must be adapted to the new property names. Clients not using that
continue to run unchanged.
Writing into the configuration requires a migration of the peer config
*and* the context in which it is defined. That is necessary because
the new semantic (independent database format) cannot be stored in the
old format. The migration is handled by rewriting first the context,
then all peers defined inside it.
Other user-visible changes:
- updated help texts
- the canonical "backend" value for the file backend is just "file"
instead of the long "Files in one directory", which is now an alias
(used to be the other way around); done because "type = file"
was expanded to the long name, which was a bit unexpected and showed
how unintuitive the long name is
Internal changes:
- getMimeVersion() is still present, although it hasn't been used
for a long time; FileSyncSource::getMimeVersion() now derives
the version from the supported Mime types, in case that the
function will be needed again in the future
- setSourceType() with string as argument was replaced with one
taking a SourceType instance; to emulate the old behavior if
desired, construct SourceType from an old-style string
- ConfigProperty methods need to be virtual so that derived classes
like SourceBackendConfigProperty can generate content at runtime
(a recent commit broke that feature)
- File templates were stripped down to the essential properties,
with "type" replaced by the per-peer "syncFormat". "type" would
still have been accepted (so it is not necessary to adapt
syncevo-phone-config right away), but has the original
disadvantage of modifying "backend" and "databaseFormat".
2011-02-03 12:17:24 +01:00
StringConfigProperty sourcePropSyncFormat ( " syncFormat " ,
" When there are alternative formats for the same data, \n "
" each side of a sync offers all that it supports and marks one as \n "
" preferred. If set, this property overrides the format \n "
" that would normally be marked as preferred by a backend. \n "
" \n "
" Valid values depend on the backend. Here are some examples: \n "
" contacts - text/vcard = vCard 3.0 format \n "
" text/x-vcard = legacy vCard 2.1 format \n "
" calendar - text/calendar = iCalendar 2.0 format \n "
" text/x-vcalendar = legacy vCalendar 1.0 format \n "
" \n "
" Errors while starting to sync and parsing and/or storing \n "
" items on either client or server can be caused by a mismatch between \n "
" the sync format and uri at the peer. \n " ) ;
static BoolConfigProperty sourcePropForceSyncFormat ( " forceSyncFormat " ,
" Some peers get confused when offered multiple choices \n "
" for the sync format or pick the less optimal one. \n "
" In such a case, setting this property enforces that the \n "
" preferred format specified with 'syncFormat' is \n "
" really used. " ,
2011-10-19 17:15:50 +02:00
" FALSE " ) ;
config: replaced overloaded "type" with "backend/databaseFormat/syncFormat/forceSyncFormat" (BMC #1023)
The meaning of "type" was horribly complex and had effects on the
backend and the peer. It was impossible to specify the sync format to
be used for a specific peer independently of the local backend and its
format, so adding a peer to a context broke the context configuration
(BMC #1023).
This is now fixed by splitting "type" into four independent properties:
- backend = plugin which interfaces with the data
- databaseFormat = data format used inside backend, only relevant for file backend
- syncFormat = data format preferred when talking to peer
- forceSyncFormat = disable format auto-negotiation, use preferred format
With that split, it is now possible to specify the format in which the
file backend stores items independently of the format in which they
are exchanged with the peer.
Old configurations with "type" can still be read. The values specified
inside it are transparently mapped to the new properties. Command line
and D-Bus API users will only see the new properties.
The command line tool still accepts "type" as an alias for the four new
properties. Using that has the same disadvantage as before: it will modify
the context even if only modifying the peer was intended.
The D-Bus API accepts only the new properties. Clients using "type"
must be adapted to the new property names. Clients not using that
continue to run unchanged.
Writing into the configuration requires a migration of the peer config
*and* the context in which it is defined. That is necessary because
the new semantic (independent database format) cannot be stored in the
old format. The migration is handled by rewriting first the context,
then all peers defined inside it.
Other user-visible changes:
- updated help texts
- the canonical "backend" value for the file backend is just "file"
instead of the long "Files in one directory", which is now an alias
(used to be the other way around); done because "type = file"
was expanded to the long name, which was a bit unexpected and showed
how unintuitive the long name is
Internal changes:
- getMimeVersion() is still present, although it hasn't been used
for a long time; FileSyncSource::getMimeVersion() now derives
the version from the supported Mime types, in case that the
function will be needed again in the future
- setSourceType() with string as argument was replaced with one
taking a SourceType instance; to emulate the old behavior if
desired, construct SourceType from an old-style string
- ConfigProperty methods need to be virtual so that derived classes
like SourceBackendConfigProperty can generate content at runtime
(a recent commit broke that feature)
- File templates were stripped down to the essential properties,
with "type" replaced by the per-peer "syncFormat". "type" would
still have been accepted (so it is not necessary to adapt
syncevo-phone-config right away), but has the original
disadvantage of modifying "backend" and "databaseFormat".
2011-02-03 12:17:24 +01:00
2011-01-18 15:33:07 +01:00
static ConfigProperty sourcePropDatabaseID ( Aliases ( " database " ) + " evolutionsource " ,
2011-10-19 17:15:50 +02:00
" Picks one of the backend's databases: \n "
" depending on the backend, one can set the name \n "
" and/or a unique identifier. \n \n "
" Most backends have a default database, \n "
2008-03-30 21:08:19 +02:00
" like for example the system address book. \n "
" Not setting this property selects that default \n "
2011-10-19 17:15:50 +02:00
" database. \n \n "
2014-07-28 15:29:41 +02:00
" If the backend is a virtual data datastore, \n "
2009-11-23 02:43:56 +01:00
" this field must contain comma seperated list of \n "
" sub datasources actually used to store data. \n "
" If your sub datastore has a comma in name, you \n "
" must prevent taht comma from being mistaken as the \n "
" separator by preceding it with a backslash, like this: \n "
2011-10-19 17:15:50 +02:00
" ``database=Source1PartA \\ ,PartB,Source2 \\ \\ Backslash`` \n "
2008-03-06 23:23:13 +01:00
" \n "
2011-10-19 17:15:50 +02:00
" To get a full list of available databases, \n "
" run ``syncevolution --print-databases``. The name \n "
2008-03-06 23:23:13 +01:00
" is printed in front of the colon, followed by \n "
2011-10-19 17:15:50 +02:00
" an identifier in brackets. Usually the name is unique and can be \n "
2014-07-28 15:29:41 +02:00
" used to reference the data datastore. The default \n "
" data datastore is marked with <default> at the end \n "
2011-10-19 17:15:50 +02:00
" of the line, if there is a default. \n " ) ;
config: replaced overloaded "type" with "backend/databaseFormat/syncFormat/forceSyncFormat" (BMC #1023)
The meaning of "type" was horribly complex and had effects on the
backend and the peer. It was impossible to specify the sync format to
be used for a specific peer independently of the local backend and its
format, so adding a peer to a context broke the context configuration
(BMC #1023).
This is now fixed by splitting "type" into four independent properties:
- backend = plugin which interfaces with the data
- databaseFormat = data format used inside backend, only relevant for file backend
- syncFormat = data format preferred when talking to peer
- forceSyncFormat = disable format auto-negotiation, use preferred format
With that split, it is now possible to specify the format in which the
file backend stores items independently of the format in which they
are exchanged with the peer.
Old configurations with "type" can still be read. The values specified
inside it are transparently mapped to the new properties. Command line
and D-Bus API users will only see the new properties.
The command line tool still accepts "type" as an alias for the four new
properties. Using that has the same disadvantage as before: it will modify
the context even if only modifying the peer was intended.
The D-Bus API accepts only the new properties. Clients using "type"
must be adapted to the new property names. Clients not using that
continue to run unchanged.
Writing into the configuration requires a migration of the peer config
*and* the context in which it is defined. That is necessary because
the new semantic (independent database format) cannot be stored in the
old format. The migration is handled by rewriting first the context,
then all peers defined inside it.
Other user-visible changes:
- updated help texts
- the canonical "backend" value for the file backend is just "file"
instead of the long "Files in one directory", which is now an alias
(used to be the other way around); done because "type = file"
was expanded to the long name, which was a bit unexpected and showed
how unintuitive the long name is
Internal changes:
- getMimeVersion() is still present, although it hasn't been used
for a long time; FileSyncSource::getMimeVersion() now derives
the version from the supported Mime types, in case that the
function will be needed again in the future
- setSourceType() with string as argument was replaced with one
taking a SourceType instance; to emulate the old behavior if
desired, construct SourceType from an old-style string
- ConfigProperty methods need to be virtual so that derived classes
like SourceBackendConfigProperty can generate content at runtime
(a recent commit broke that feature)
- File templates were stripped down to the essential properties,
with "type" replaced by the per-peer "syncFormat". "type" would
still have been accepted (so it is not necessary to adapt
syncevo-phone-config right away), but has the original
disadvantage of modifying "backend" and "databaseFormat".
2011-02-03 12:17:24 +01:00
static StringConfigProperty sourcePropDatabaseFormat ( " databaseFormat " ,
" Defines the data format to be used by the backend for its \n "
" own storage. Typically backends only support one format \n "
" and ignore this property, but for example the file backend \n "
" uses it. See the 'backend' property for more information. \n " ) ;
2008-03-06 23:23:13 +01:00
static ConfigProperty sourcePropURI ( " uri " ,
" this is appended to the server's URL to identify the \n "
2014-07-28 15:29:41 +02:00
" server's database; if unset, the datastore name is used as \n "
2011-04-21 12:20:00 +02:00
" fallback " ) ;
2009-04-07 20:33:18 +02:00
2011-01-18 15:33:07 +01:00
static ConfigProperty sourcePropUser ( Aliases ( " databaseUser " ) + " evolutionuser " ,
2014-07-28 15:29:41 +02:00
" authentication for backend data datastore; password can be specified \n "
2008-04-03 22:01:56 +02:00
" in multiple ways, see SyncML server password for details \n "
2008-03-06 23:23:13 +01:00
" \n "
2011-01-18 15:33:07 +01:00
" Warning: setting database user/password in cases where it is not \n "
2008-03-30 20:39:15 +02:00
" needed, as for example with local Evolution calendars and addressbooks, \n "
" can cause the Evolution backend to hang. " ) ;
2013-07-26 10:22:11 +02:00
static class DatabasePasswordConfigProperty : public PasswordConfigProperty {
public :
DatabasePasswordConfigProperty ( ) :
PasswordConfigProperty ( Aliases ( " databasePassword " ) + " evolutionpassword " , " " , " " , " backend " )
{ }
virtual void checkPassword ( UserInterface & ui ,
2013-07-26 11:56:18 +02:00
SyncConfig & config ,
2013-07-29 13:57:46 +02:00
int flags ,
2013-07-26 11:56:18 +02:00
const std : : string & sourceName ) const {
2013-07-29 13:57:46 +02:00
PasswordConfigProperty : : checkPassword ( ui , config , flags , sourcePropUser , sourceName ) ;
2013-07-26 10:22:11 +02:00
}
2013-07-26 16:19:40 +02:00
virtual void savePassword ( UserInterface & ui ,
SyncConfig & config ,
const std : : string & sourceName ) const {
PasswordConfigProperty : : savePassword ( ui , config , sourcePropUser , sourceName ) ;
}
2013-07-26 10:22:11 +02:00
virtual ConfigPasswordKey getPasswordKey ( const std : : string & descr ,
const std : : string & serverName ,
FilterConfigNode & globalConfigNode ,
const std : : string & sourceName = std : : string ( ) ,
2018-01-16 17:17:34 +01:00
const std : : shared_ptr < FilterConfigNode > & sourceConfigNode = std : : shared_ptr < FilterConfigNode > ( ) ) const {
2013-07-26 10:22:11 +02:00
ConfigPasswordKey key ;
key . user = getUsername ( sourcePropUser , * sourceConfigNode ) ;
std : : string configName = SyncConfig : : normalizeConfigString ( serverName , SyncConfig : : NORMALIZE_LONG_FORMAT ) ;
std : : string peer , context ;
SyncConfig : : splitConfigString ( configName , peer , context ) ;
key . object = " @ " ;
key . object + = context ;
key . object + = " " ;
key . object + = sourceName ;
key . object + = " backend " ;
2014-07-28 15:29:41 +02:00
key . description = StringPrintf ( " databasePassword for %s in datastore %s " ,
2013-08-09 18:16:55 +02:00
descr . c_str ( ) , sourceName . c_str ( ) ) ;
2013-07-26 10:22:11 +02:00
return key ;
}
virtual const std : : string getDescr ( const std : : string & serverName ,
FilterConfigNode & globalConfigNode ,
const std : : string & sourceName ,
2018-01-16 17:17:34 +01:00
const std : : shared_ptr < FilterConfigNode > & sourceConfigNode ) const {
2013-07-26 10:22:11 +02:00
std : : string descr = sourceName ;
descr + = " " ;
descr + = ConfigProperty : : getDescr ( ) ;
return descr ;
}
} sourcePropPassword ;
2008-03-09 20:08:34 +01:00
2009-11-12 21:19:03 +01:00
static ConfigProperty sourcePropAdminData ( SourceAdminDataName ,
" used by the Synthesis library internally; do not modify " ) ;
2009-10-25 22:46:09 +01:00
2010-02-15 16:50:06 +01:00
static IntConfigProperty sourcePropSynthesisID ( " synthesisID " , " unique integer ID, necessary for libsynthesis " , " 0 " ) ;
2011-07-11 11:37:09 +02:00
/**
* Same as RegisterSyncConfigProperties , only for SyncSource properties .
*/
static class RegisterSyncSourceConfigProperties
2008-03-06 23:23:13 +01:00
{
2011-07-11 11:37:09 +02:00
public :
RegisterSyncSourceConfigProperties ( )
{
ConfigPropertyRegistry & registry = SyncSourceConfig : : getRegistry ( ) ;
2011-08-12 21:03:34 +02:00
// temporarily move existing properties away so that the important
// standard properties come first when using the traditional
// push_back() way of adding them
ConfigPropertyRegistry tmp ;
std : : swap ( registry , tmp ) ;
redesigned SyncSource base class + API
The main motivation for this change is that it allows the implementor
of a backend to choose the implementations for the different aspects
of a datasource (change tracking, item import/export, logging, ...)
independently of each other. For example, change tracking via revision
strings can now be combined with exchanging data with the Synthesis
engine via a single string (the traditional method in SyncEvolution)
and with direct access to the Synthesis field list (now possible for
the first time).
The new backend API is based on the concept of providing
implementations for certain functionality via function objects instead
of implementing certain virtual methods. The advantage is that
implementors can define their own, custom interfaces and mix and match
implementations of the different groups of functionality.
Logging (see SyncSourceLogging in a later commit) can be done by
wrapping some arbitrary other item import/export function objects
(decorator design pattern).
The class hierarchy is now this:
- SyncSourceBase: interface for common utility code, all other
classes are derived from it and thus can use that code
- SyncSource: base class which implements SyncSourceBase and
hooks a datasource into the SyncEvolution core;
its "struct Operations" holds the function objects which
can be implemented in different ways
- TestingSyncSource: combines some of the following classes
into an interface that is expected by the client-test
program; backends only have to derive from (and implement this)
if they want to use the automated testing
- TrackingSyncSource: provides the same functionality as
before (change tracking via revision strings, item import/export
as string) in a single interface; the description of the pure
virtual methods are duplicated so that developers can go through
this class and find everything they need to know to implement
it
The following classes contain the code that was previously
found in the EvolutionSyncSource base class. Implementors
can derive from them and call the init() methods to inherit
and activate the functionality:
- SyncSourceSession: binds Synthesis session callbacks to
virtual methods beginSync(), endSync()
- SyncSourceChanges: implements Synthesis item tracking callbacks
with set of LUIDs that the user of the class has to fill
- SyncSourceDelete: binds Synthesis delete callback to
virtual method
- SyncSourceRaw: read and write items in the backends format,
used for testing and backup/restore
- SyncSourceSerialize: exchanges items with Synthesis engine
using a string representation of the data; this is how
EvolutionSyncSource has traditionally worked, so much of the
same virtual methods are now in this class
- SyncSourceRevisions: utility class which does change tracking
via some kind of "revision" string which changes each time
an item is modified; this code was previously in the
TrackingSyncSource
2009-08-25 09:27:46 +02:00
registry . push_back ( & SyncSourceConfig : : m_sourcePropSync ) ;
2008-03-06 23:23:13 +01:00
registry . push_back ( & sourcePropURI ) ;
config: replaced overloaded "type" with "backend/databaseFormat/syncFormat/forceSyncFormat" (BMC #1023)
The meaning of "type" was horribly complex and had effects on the
backend and the peer. It was impossible to specify the sync format to
be used for a specific peer independently of the local backend and its
format, so adding a peer to a context broke the context configuration
(BMC #1023).
This is now fixed by splitting "type" into four independent properties:
- backend = plugin which interfaces with the data
- databaseFormat = data format used inside backend, only relevant for file backend
- syncFormat = data format preferred when talking to peer
- forceSyncFormat = disable format auto-negotiation, use preferred format
With that split, it is now possible to specify the format in which the
file backend stores items independently of the format in which they
are exchanged with the peer.
Old configurations with "type" can still be read. The values specified
inside it are transparently mapped to the new properties. Command line
and D-Bus API users will only see the new properties.
The command line tool still accepts "type" as an alias for the four new
properties. Using that has the same disadvantage as before: it will modify
the context even if only modifying the peer was intended.
The D-Bus API accepts only the new properties. Clients using "type"
must be adapted to the new property names. Clients not using that
continue to run unchanged.
Writing into the configuration requires a migration of the peer config
*and* the context in which it is defined. That is necessary because
the new semantic (independent database format) cannot be stored in the
old format. The migration is handled by rewriting first the context,
then all peers defined inside it.
Other user-visible changes:
- updated help texts
- the canonical "backend" value for the file backend is just "file"
instead of the long "Files in one directory", which is now an alias
(used to be the other way around); done because "type = file"
was expanded to the long name, which was a bit unexpected and showed
how unintuitive the long name is
Internal changes:
- getMimeVersion() is still present, although it hasn't been used
for a long time; FileSyncSource::getMimeVersion() now derives
the version from the supported Mime types, in case that the
function will be needed again in the future
- setSourceType() with string as argument was replaced with one
taking a SourceType instance; to emulate the old behavior if
desired, construct SourceType from an old-style string
- ConfigProperty methods need to be virtual so that derived classes
like SourceBackendConfigProperty can generate content at runtime
(a recent commit broke that feature)
- File templates were stripped down to the essential properties,
with "type" replaced by the per-peer "syncFormat". "type" would
still have been accepted (so it is not necessary to adapt
syncevo-phone-config right away), but has the original
disadvantage of modifying "backend" and "databaseFormat".
2011-02-03 12:17:24 +01:00
registry . push_back ( & sourcePropBackend ) ;
registry . push_back ( & sourcePropSyncFormat ) ;
registry . push_back ( & sourcePropForceSyncFormat ) ;
registry . push_back ( & sourcePropDatabaseID ) ;
registry . push_back ( & sourcePropDatabaseFormat ) ;
2008-03-06 23:23:13 +01:00
registry . push_back ( & sourcePropUser ) ;
registry . push_back ( & sourcePropPassword ) ;
2009-11-12 21:19:03 +01:00
registry . push_back ( & sourcePropAdminData ) ;
2010-02-15 16:50:06 +01:00
registry . push_back ( & sourcePropSynthesisID ) ;
2009-11-13 14:52:00 +01:00
2018-01-16 10:58:04 +01:00
for ( const ConfigProperty * prop : tmp ) {
2011-08-12 21:03:34 +02:00
registry . push_back ( prop ) ;
}
2009-11-13 14:52:00 +01:00
// obligatory source properties
SyncSourceConfig : : m_sourcePropSync . setObligatory ( true ) ;
// hidden source properties - only possible for
// non-shared properties (other hidden nodes don't
// exist at the moment)
2009-11-12 21:19:03 +01:00
sourcePropAdminData . setHidden ( true ) ;
2010-02-15 16:50:06 +01:00
sourcePropSynthesisID . setHidden ( true ) ;
2009-11-13 14:52:00 +01:00
// No global source properties. Does not make sense
// conceptually.
// peer independent source properties
config: replaced overloaded "type" with "backend/databaseFormat/syncFormat/forceSyncFormat" (BMC #1023)
The meaning of "type" was horribly complex and had effects on the
backend and the peer. It was impossible to specify the sync format to
be used for a specific peer independently of the local backend and its
format, so adding a peer to a context broke the context configuration
(BMC #1023).
This is now fixed by splitting "type" into four independent properties:
- backend = plugin which interfaces with the data
- databaseFormat = data format used inside backend, only relevant for file backend
- syncFormat = data format preferred when talking to peer
- forceSyncFormat = disable format auto-negotiation, use preferred format
With that split, it is now possible to specify the format in which the
file backend stores items independently of the format in which they
are exchanged with the peer.
Old configurations with "type" can still be read. The values specified
inside it are transparently mapped to the new properties. Command line
and D-Bus API users will only see the new properties.
The command line tool still accepts "type" as an alias for the four new
properties. Using that has the same disadvantage as before: it will modify
the context even if only modifying the peer was intended.
The D-Bus API accepts only the new properties. Clients using "type"
must be adapted to the new property names. Clients not using that
continue to run unchanged.
Writing into the configuration requires a migration of the peer config
*and* the context in which it is defined. That is necessary because
the new semantic (independent database format) cannot be stored in the
old format. The migration is handled by rewriting first the context,
then all peers defined inside it.
Other user-visible changes:
- updated help texts
- the canonical "backend" value for the file backend is just "file"
instead of the long "Files in one directory", which is now an alias
(used to be the other way around); done because "type = file"
was expanded to the long name, which was a bit unexpected and showed
how unintuitive the long name is
Internal changes:
- getMimeVersion() is still present, although it hasn't been used
for a long time; FileSyncSource::getMimeVersion() now derives
the version from the supported Mime types, in case that the
function will be needed again in the future
- setSourceType() with string as argument was replaced with one
taking a SourceType instance; to emulate the old behavior if
desired, construct SourceType from an old-style string
- ConfigProperty methods need to be virtual so that derived classes
like SourceBackendConfigProperty can generate content at runtime
(a recent commit broke that feature)
- File templates were stripped down to the essential properties,
with "type" replaced by the per-peer "syncFormat". "type" would
still have been accepted (so it is not necessary to adapt
syncevo-phone-config right away), but has the original
disadvantage of modifying "backend" and "databaseFormat".
2011-02-03 12:17:24 +01:00
sourcePropBackend . setSharing ( ConfigProperty : : SOURCE_SET_SHARING ) ;
2009-11-13 14:52:00 +01:00
sourcePropDatabaseID . setSharing ( ConfigProperty : : SOURCE_SET_SHARING ) ;
config: replaced overloaded "type" with "backend/databaseFormat/syncFormat/forceSyncFormat" (BMC #1023)
The meaning of "type" was horribly complex and had effects on the
backend and the peer. It was impossible to specify the sync format to
be used for a specific peer independently of the local backend and its
format, so adding a peer to a context broke the context configuration
(BMC #1023).
This is now fixed by splitting "type" into four independent properties:
- backend = plugin which interfaces with the data
- databaseFormat = data format used inside backend, only relevant for file backend
- syncFormat = data format preferred when talking to peer
- forceSyncFormat = disable format auto-negotiation, use preferred format
With that split, it is now possible to specify the format in which the
file backend stores items independently of the format in which they
are exchanged with the peer.
Old configurations with "type" can still be read. The values specified
inside it are transparently mapped to the new properties. Command line
and D-Bus API users will only see the new properties.
The command line tool still accepts "type" as an alias for the four new
properties. Using that has the same disadvantage as before: it will modify
the context even if only modifying the peer was intended.
The D-Bus API accepts only the new properties. Clients using "type"
must be adapted to the new property names. Clients not using that
continue to run unchanged.
Writing into the configuration requires a migration of the peer config
*and* the context in which it is defined. That is necessary because
the new semantic (independent database format) cannot be stored in the
old format. The migration is handled by rewriting first the context,
then all peers defined inside it.
Other user-visible changes:
- updated help texts
- the canonical "backend" value for the file backend is just "file"
instead of the long "Files in one directory", which is now an alias
(used to be the other way around); done because "type = file"
was expanded to the long name, which was a bit unexpected and showed
how unintuitive the long name is
Internal changes:
- getMimeVersion() is still present, although it hasn't been used
for a long time; FileSyncSource::getMimeVersion() now derives
the version from the supported Mime types, in case that the
function will be needed again in the future
- setSourceType() with string as argument was replaced with one
taking a SourceType instance; to emulate the old behavior if
desired, construct SourceType from an old-style string
- ConfigProperty methods need to be virtual so that derived classes
like SourceBackendConfigProperty can generate content at runtime
(a recent commit broke that feature)
- File templates were stripped down to the essential properties,
with "type" replaced by the per-peer "syncFormat". "type" would
still have been accepted (so it is not necessary to adapt
syncevo-phone-config right away), but has the original
disadvantage of modifying "backend" and "databaseFormat".
2011-02-03 12:17:24 +01:00
sourcePropDatabaseFormat . setSharing ( ConfigProperty : : SOURCE_SET_SHARING ) ;
2009-11-13 14:52:00 +01:00
sourcePropUser . setSharing ( ConfigProperty : : SOURCE_SET_SHARING ) ;
sourcePropPassword . setSharing ( ConfigProperty : : SOURCE_SET_SHARING ) ;
2008-03-06 23:23:13 +01:00
}
2011-07-11 11:37:09 +02:00
} RegisterSyncSourceConfigProperties ;
2008-03-06 23:23:13 +01:00
2011-07-11 11:37:09 +02:00
ConfigPropertyRegistry & SyncSourceConfig : : getRegistry ( )
{
static ConfigPropertyRegistry registry ;
2008-03-06 23:23:13 +01:00
return registry ;
}
2010-03-02 16:30:10 +01:00
SyncSourceNodes : : SyncSourceNodes ( bool havePeerNode ,
2018-01-16 17:17:34 +01:00
const std : : shared_ptr < FilterConfigNode > & sharedNode ,
const std : : shared_ptr < FilterConfigNode > & peerNode ,
const std : : shared_ptr < ConfigNode > & hiddenPeerNode ,
const std : : shared_ptr < ConfigNode > & trackingNode ,
const std : : shared_ptr < ConfigNode > & serverNode ,
2010-03-04 17:50:01 +01:00
const string & cacheDir ) :
2010-06-16 13:50:41 +02:00
m_havePeerNode ( havePeerNode ) ,
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
m_sharedNode ( sharedNode ) ,
m_peerNode ( peerNode ) ,
m_hiddenPeerNode ( hiddenPeerNode ) ,
m_trackingNode ( trackingNode ) ,
2010-03-04 17:50:01 +01:00
m_serverNode ( serverNode ) ,
m_cacheDir ( cacheDir )
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
{
2018-01-16 17:17:34 +01:00
std : : shared_ptr < MultiplexConfigNode > mnode ;
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
mnode . reset ( new MultiplexConfigNode ( m_peerNode - > getName ( ) ,
SyncSourceConfig : : getRegistry ( ) ,
false ) ) ;
2010-03-02 16:30:10 +01:00
mnode - > setHavePeerNodes ( havePeerNode ) ;
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
m_props [ false ] = mnode ;
mnode - > setNode ( false , ConfigProperty : : SOURCE_SET_SHARING ,
m_sharedNode ) ;
mnode - > setNode ( false , ConfigProperty : : NO_SHARING ,
m_peerNode ) ;
// no multiplexing necessary for hidden peer properties yet
m_props [ true ] . reset ( new FilterConfigNode ( m_hiddenPeerNode ) ) ;
}
2018-01-16 17:17:34 +01:00
std : : shared_ptr < FilterConfigNode >
2009-11-13 14:52:00 +01:00
SyncSourceNodes : : getNode ( const ConfigProperty & prop ) const
{
switch ( prop . getSharing ( ) ) {
case ConfigProperty : : GLOBAL_SHARING :
2018-01-16 17:17:34 +01:00
return std : : make_shared < FilterConfigNode > ( std : : static_pointer_cast < ConfigNode > ( std : : make_shared < DevNullConfigNode > ( " no global datastore properties " ) ) ) ;
2009-11-13 14:52:00 +01:00
break ;
case ConfigProperty : : SOURCE_SET_SHARING :
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
if ( prop . isHidden ( ) ) {
2018-01-16 17:17:34 +01:00
return std : : make_shared < FilterConfigNode > ( std : : static_pointer_cast < ConfigNode > ( std : : make_shared < DevNullConfigNode > ( " no hidden datastore set properties " ) ) ) ;
config: share properties between peers, configuration view without peer
This patch makes the configuration layout with per-source and per-peer
properties the default for new configurations. Migrating old
configurations is not implemented. The command line has not
been updated at all (MB #8048). The D-Bus API is fairly complete,
only listing sessions independently of a peer is missing (MB #8049).
The key concept of this patch is that a pseudo-node implemented by
MultiplexConfigNode provides a view on all user-visible or hidden
properties. Based on the property name, it looks up the property
definition, picks one of the underlying nodes based on the property
visibility and sharing attributes, then reads and writes the property
via that node. Clearing properties is not needed and not implemented,
because of the uncertain semantic (really remove shared properties?!).
The "sync" property must be available both in the per-source config
(to pick a backend independently of a specific peer) and in the
per-peer configuration (to select a specific data format). This is
solved by making the property special (SHARED_AND_UNSHARED flag) and
then writing it into two nodes. Reading is done from the more specific
per-peer node, with the other node acting as fallback.
The MultiplexConfigNode has to implement the FilterConfigNode API
because it is used as one by the code which sets passwords in the
filter. For this to work, the base FilterConfigNode implementation must
use virtual method calls.
The TestDBusSessionConfig.testUpdateConfigError checks that the error
generated for an incorrect "sync" property contains the path of the
config.ini file. The meaning of the error message in this case is that
the wrong value is *for* that file, not that the property is already
wrong *in* the file, but that's okay.
The MultiplexConfigNode::getName() can only return a fixed name. To
satisfy the test and because it is the right choice at the moment for
all properties which might trigger such an error, it now is configured
so that it returns the most specific path of the non-shared
properties.
"syncevolution --print-config" shows errors that are in files. Wrong
command line parameters are rejected with a message that refers to the
command line parameter ("--source-property sync=foo").
A future enhancement would be to make the name depend on the
property (MB#8037).
Because an empty string is now a valid configuration name (referencing
the source properties without the per-peer properties) several checks
for such empty strings were removed. The corresponding tests were
updated resp. removed. Instead of talking about "server not found",
the more neutral name "configuration" is used. The new
TestMultipleConfigs.testSharing() covers the semantic of sharing
properties between multiple configs.
Access to non-existant nodes is routed into the new
DevNullConfigNode. It always returns an empty string when reading and
throws an error when trying to write into it. Unintentionally writing
into a config.ini file therefore became harder, compared with the
previous instantiation of SyncContext() with empty config name.
The parsing of incoming messages uses a SyncContext which is bound to
a VolatileConfigNode. This allows reading and writing of properties
without any risk of touching files on disk.
The patch which introduced the new config nodes was not complete yet
with regards to the new layout. Removing nodes and trees used the
wrong root path: getRootPath() refers to the most specific peer
config, m_root to the part without the peer path. SyncConfig must
distinguish between a view with peer-specific properties and one
without, which is done by setting the m_peerPath only if a peer was
selected. Copying properties must know whether writing per-specific
properties ("unshared") is wanted, because trying to do it for a view
without those properties would trigger the DevNullConfigNode
exception.
SyncConfig::removeSyncSource() removes source properties both in the
shared part of the config and in *all* peers. This is used by
Session.SetConfig() for the case that the caller is a) setting instead
of updating the config and b) not providing any properties for the
source. This is clearly a risky operation which should not be done
when there are other peers which still use the source. We might have a
problem in our D-Bus API definition for "removing a peer
configuration" (MB #8059) because it always has an effect on other
peers.
The property registries were initialized implicitly before. With the
recent changes it happened that SyncContext was initialized to analyze
a SyncML message without initializing the registry, which caused
getRemoteDevID() to use a property where the hidden flag had not been
set yet.
Moving all of these additional flags into the property constructors is
awkward (which is why they are in the getRegistry() methods), so this
was fixed by initializing the properties in the SyncConfig
constructors by asking for the registries. Because there is no way to
access them except via the registry and SyncConfig instances (*), this
should ensure that the properties are valid when used.
(*) Exception are some properties which are declared publicly to have access
to their name. Nobody's perfect...
2009-11-13 20:02:44 +01:00
} else {
return m_sharedNode ;
}
2009-11-13 14:52:00 +01:00
break ;
case ConfigProperty : : NO_SHARING :
2011-02-03 13:00:22 +01:00
if ( prop . isHidden ( ) ) {
2018-01-16 17:17:34 +01:00
return std : : make_shared < FilterConfigNode > ( m_hiddenPeerNode ) ;
2009-11-13 14:52:00 +01:00
} else {
2011-02-03 13:00:22 +01:00
return m_peerNode ;
2009-11-13 14:52:00 +01:00
}
2011-02-03 13:00:22 +01:00
break ;
2009-11-13 14:52:00 +01:00
}
2018-01-16 17:17:34 +01:00
return { } ;
2009-11-13 14:52:00 +01:00
}
2011-11-21 16:37:53 +01:00
InitStateString SyncSourceConfig : : getDatabaseID ( ) const { return sourcePropDatabaseID . getProperty ( * getNode ( sourcePropDatabaseID ) ) ; }
2009-11-13 14:52:00 +01:00
void SyncSourceConfig : : setDatabaseID ( const string & value , bool temporarily ) { sourcePropDatabaseID . setProperty ( * getNode ( sourcePropDatabaseID ) , value , temporarily ) ; }
2013-07-26 10:22:11 +02:00
UserIdentity SyncSourceConfig : : getUser ( ) const {
InitStateString user = sourcePropUser . getProperty ( * getNode ( sourcePropUser ) ) ;
UserIdentity id ( UserIdentity : : fromString ( user ) ) ;
return id ;
}
void SyncSourceConfig : : setUsername ( const string & value , bool temporarily ) { sourcePropUser . setProperty ( * getNode ( sourcePropUser ) , value , temporarily ) ; }
2011-11-21 16:37:53 +01:00
InitStateString SyncSourceConfig : : getPassword ( ) const {
2013-07-25 17:23:34 +02:00
return sourcePropPassword . getProperty ( * getNode ( sourcePropPassword ) ) ;
2013-08-02 22:02:03 +02:00
}
2013-07-25 17:23:34 +02:00
void SyncSourceConfig : : setPassword ( const string & value , bool temporarily ) { sourcePropPassword . setProperty ( * getNode ( sourcePropPassword ) , value , temporarily ) ; }
2011-11-21 16:37:53 +01:00
InitStateString SyncSourceConfig : : getURI ( ) const { return sourcePropURI . getProperty ( * getNode ( sourcePropURI ) ) ; }
InitStateString SyncSourceConfig : : getURINonEmpty ( ) const {
InitStateString uri = sourcePropURI . getProperty ( * getNode ( sourcePropURI ) ) ;
2011-04-21 12:20:00 +02:00
if ( uri . empty ( ) ) {
2011-11-21 16:37:53 +01:00
uri = InitStateString ( m_name , false ) ;
2011-04-21 12:20:00 +02:00
}
return uri ;
}
2009-11-13 14:52:00 +01:00
void SyncSourceConfig : : setURI ( const string & value , bool temporarily ) { sourcePropURI . setProperty ( * getNode ( sourcePropURI ) , value , temporarily ) ; }
2011-11-21 16:37:53 +01:00
InitStateString SyncSourceConfig : : getSync ( ) const { return m_sourcePropSync . getProperty ( * getNode ( m_sourcePropSync ) ) ; }
2009-11-13 14:52:00 +01:00
void SyncSourceConfig : : setSync ( const string & value , bool temporarily ) { m_sourcePropSync . setProperty ( * getNode ( m_sourcePropSync ) , value , temporarily ) ; }
2011-02-02 10:05:42 +01:00
SourceType : : SourceType ( const string & type )
{
m_forceFormat = false ;
2008-03-10 23:45:36 +01:00
size_t colon = type . find ( ' : ' ) ;
if ( colon ! = type . npos ) {
config: replaced overloaded "type" with "backend/databaseFormat/syncFormat/forceSyncFormat" (BMC #1023)
The meaning of "type" was horribly complex and had effects on the
backend and the peer. It was impossible to specify the sync format to
be used for a specific peer independently of the local backend and its
format, so adding a peer to a context broke the context configuration
(BMC #1023).
This is now fixed by splitting "type" into four independent properties:
- backend = plugin which interfaces with the data
- databaseFormat = data format used inside backend, only relevant for file backend
- syncFormat = data format preferred when talking to peer
- forceSyncFormat = disable format auto-negotiation, use preferred format
With that split, it is now possible to specify the format in which the
file backend stores items independently of the format in which they
are exchanged with the peer.
Old configurations with "type" can still be read. The values specified
inside it are transparently mapped to the new properties. Command line
and D-Bus API users will only see the new properties.
The command line tool still accepts "type" as an alias for the four new
properties. Using that has the same disadvantage as before: it will modify
the context even if only modifying the peer was intended.
The D-Bus API accepts only the new properties. Clients using "type"
must be adapted to the new property names. Clients not using that
continue to run unchanged.
Writing into the configuration requires a migration of the peer config
*and* the context in which it is defined. That is necessary because
the new semantic (independent database format) cannot be stored in the
old format. The migration is handled by rewriting first the context,
then all peers defined inside it.
Other user-visible changes:
- updated help texts
- the canonical "backend" value for the file backend is just "file"
instead of the long "Files in one directory", which is now an alias
(used to be the other way around); done because "type = file"
was expanded to the long name, which was a bit unexpected and showed
how unintuitive the long name is
Internal changes:
- getMimeVersion() is still present, although it hasn't been used
for a long time; FileSyncSource::getMimeVersion() now derives
the version from the supported Mime types, in case that the
function will be needed again in the future
- setSourceType() with string as argument was replaced with one
taking a SourceType instance; to emulate the old behavior if
desired, construct SourceType from an old-style string
- ConfigProperty methods need to be virtual so that derived classes
like SourceBackendConfigProperty can generate content at runtime
(a recent commit broke that feature)
- File templates were stripped down to the essential properties,
with "type" replaced by the per-peer "syncFormat". "type" would
still have been accepted (so it is not necessary to adapt
syncevo-phone-config right away), but has the original
disadvantage of modifying "backend" and "databaseFormat".
2011-02-03 12:17:24 +01:00
m_backend = type . substr ( 0 , colon ) ;
sourcePropBackend . normalizeValue ( m_backend ) ;
2008-03-10 23:45:36 +01:00
string format = type . substr ( colon + 1 ) ;
config: replaced overloaded "type" with "backend/databaseFormat/syncFormat/forceSyncFormat" (BMC #1023)
The meaning of "type" was horribly complex and had effects on the
backend and the peer. It was impossible to specify the sync format to
be used for a specific peer independently of the local backend and its
format, so adding a peer to a context broke the context configuration
(BMC #1023).
This is now fixed by splitting "type" into four independent properties:
- backend = plugin which interfaces with the data
- databaseFormat = data format used inside backend, only relevant for file backend
- syncFormat = data format preferred when talking to peer
- forceSyncFormat = disable format auto-negotiation, use preferred format
With that split, it is now possible to specify the format in which the
file backend stores items independently of the format in which they
are exchanged with the peer.
Old configurations with "type" can still be read. The values specified
inside it are transparently mapped to the new properties. Command line
and D-Bus API users will only see the new properties.
The command line tool still accepts "type" as an alias for the four new
properties. Using that has the same disadvantage as before: it will modify
the context even if only modifying the peer was intended.
The D-Bus API accepts only the new properties. Clients using "type"
must be adapted to the new property names. Clients not using that
continue to run unchanged.
Writing into the configuration requires a migration of the peer config
*and* the context in which it is defined. That is necessary because
the new semantic (independent database format) cannot be stored in the
old format. The migration is handled by rewriting first the context,
then all peers defined inside it.
Other user-visible changes:
- updated help texts
- the canonical "backend" value for the file backend is just "file"
instead of the long "Files in one directory", which is now an alias
(used to be the other way around); done because "type = file"
was expanded to the long name, which was a bit unexpected and showed
how unintuitive the long name is
Internal changes:
- getMimeVersion() is still present, although it hasn't been used
for a long time; FileSyncSource::getMimeVersion() now derives
the version from the supported Mime types, in case that the
function will be needed again in the future
- setSourceType() with string as argument was replaced with one
taking a SourceType instance; to emulate the old behavior if
desired, construct SourceType from an old-style string
- ConfigProperty methods need to be virtual so that derived classes
like SourceBackendConfigProperty can generate content at runtime
(a recent commit broke that feature)
- File templates were stripped down to the essential properties,
with "type" replaced by the per-peer "syncFormat". "type" would
still have been accepted (so it is not necessary to adapt
syncevo-phone-config right away), but has the original
disadvantage of modifying "backend" and "databaseFormat".
2011-02-03 12:17:24 +01:00
if ( boost : : ends_with ( format , " ! " ) ) {
2011-02-02 10:05:42 +01:00
m_forceFormat = true ;
config: replaced overloaded "type" with "backend/databaseFormat/syncFormat/forceSyncFormat" (BMC #1023)
The meaning of "type" was horribly complex and had effects on the
backend and the peer. It was impossible to specify the sync format to
be used for a specific peer independently of the local backend and its
format, so adding a peer to a context broke the context configuration
(BMC #1023).
This is now fixed by splitting "type" into four independent properties:
- backend = plugin which interfaces with the data
- databaseFormat = data format used inside backend, only relevant for file backend
- syncFormat = data format preferred when talking to peer
- forceSyncFormat = disable format auto-negotiation, use preferred format
With that split, it is now possible to specify the format in which the
file backend stores items independently of the format in which they
are exchanged with the peer.
Old configurations with "type" can still be read. The values specified
inside it are transparently mapped to the new properties. Command line
and D-Bus API users will only see the new properties.
The command line tool still accepts "type" as an alias for the four new
properties. Using that has the same disadvantage as before: it will modify
the context even if only modifying the peer was intended.
The D-Bus API accepts only the new properties. Clients using "type"
must be adapted to the new property names. Clients not using that
continue to run unchanged.
Writing into the configuration requires a migration of the peer config
*and* the context in which it is defined. That is necessary because
the new semantic (independent database format) cannot be stored in the
old format. The migration is handled by rewriting first the context,
then all peers defined inside it.
Other user-visible changes:
- updated help texts
- the canonical "backend" value for the file backend is just "file"
instead of the long "Files in one directory", which is now an alias
(used to be the other way around); done because "type = file"
was expanded to the long name, which was a bit unexpected and showed
how unintuitive the long name is
Internal changes:
- getMimeVersion() is still present, although it hasn't been used
for a long time; FileSyncSource::getMimeVersion() now derives
the version from the supported Mime types, in case that the
function will be needed again in the future
- setSourceType() with string as argument was replaced with one
taking a SourceType instance; to emulate the old behavior if
desired, construct SourceType from an old-style string
- ConfigProperty methods need to be virtual so that derived classes
like SourceBackendConfigProperty can generate content at runtime
(a recent commit broke that feature)
- File templates were stripped down to the essential properties,
with "type" replaced by the per-peer "syncFormat". "type" would
still have been accepted (so it is not necessary to adapt
syncevo-phone-config right away), but has the original
disadvantage of modifying "backend" and "databaseFormat".
2011-02-03 12:17:24 +01:00
format . resize ( format . size ( ) - 1 ) ;
}
colon = format . find ( ' : ' ) ;
if ( colon ! = format . npos ) {
// ignore obsolete Mime version
m_format = format . substr ( 0 , colon ) ;
} else {
m_format = format ;
2009-07-07 03:44:45 +02:00
}
config: replaced overloaded "type" with "backend/databaseFormat/syncFormat/forceSyncFormat" (BMC #1023)
The meaning of "type" was horribly complex and had effects on the
backend and the peer. It was impossible to specify the sync format to
be used for a specific peer independently of the local backend and its
format, so adding a peer to a context broke the context configuration
(BMC #1023).
This is now fixed by splitting "type" into four independent properties:
- backend = plugin which interfaces with the data
- databaseFormat = data format used inside backend, only relevant for file backend
- syncFormat = data format preferred when talking to peer
- forceSyncFormat = disable format auto-negotiation, use preferred format
With that split, it is now possible to specify the format in which the
file backend stores items independently of the format in which they
are exchanged with the peer.
Old configurations with "type" can still be read. The values specified
inside it are transparently mapped to the new properties. Command line
and D-Bus API users will only see the new properties.
The command line tool still accepts "type" as an alias for the four new
properties. Using that has the same disadvantage as before: it will modify
the context even if only modifying the peer was intended.
The D-Bus API accepts only the new properties. Clients using "type"
must be adapted to the new property names. Clients not using that
continue to run unchanged.
Writing into the configuration requires a migration of the peer config
*and* the context in which it is defined. That is necessary because
the new semantic (independent database format) cannot be stored in the
old format. The migration is handled by rewriting first the context,
then all peers defined inside it.
Other user-visible changes:
- updated help texts
- the canonical "backend" value for the file backend is just "file"
instead of the long "Files in one directory", which is now an alias
(used to be the other way around); done because "type = file"
was expanded to the long name, which was a bit unexpected and showed
how unintuitive the long name is
Internal changes:
- getMimeVersion() is still present, although it hasn't been used
for a long time; FileSyncSource::getMimeVersion() now derives
the version from the supported Mime types, in case that the
function will be needed again in the future
- setSourceType() with string as argument was replaced with one
taking a SourceType instance; to emulate the old behavior if
desired, construct SourceType from an old-style string
- ConfigProperty methods need to be virtual so that derived classes
like SourceBackendConfigProperty can generate content at runtime
(a recent commit broke that feature)
- File templates were stripped down to the essential properties,
with "type" replaced by the per-peer "syncFormat". "type" would
still have been accepted (so it is not necessary to adapt
syncevo-phone-config right away), but has the original
disadvantage of modifying "backend" and "databaseFormat".
2011-02-03 12:17:24 +01:00
// no difference between remote and local format
m_localFormat = m_format ;
2008-03-10 23:45:36 +01:00
} else {
2011-02-02 10:05:42 +01:00
m_backend = type ;
}
}
string SourceType : : toString ( ) const
{
string type = m_backend ;
if ( ! m_format . empty ( ) ) {
type + = " : " ;
type + = m_format ;
if ( m_forceFormat ) {
type + = " ! " ;
}
2008-03-10 23:45:36 +01:00
}
2011-02-02 10:05:42 +01:00
return type ;
}
2012-09-13 16:59:24 +02:00
InitState < SourceType > SyncSourceConfig : : getSourceType ( const SyncSourceNodes & nodes )
config: replaced overloaded "type" with "backend/databaseFormat/syncFormat/forceSyncFormat" (BMC #1023)
The meaning of "type" was horribly complex and had effects on the
backend and the peer. It was impossible to specify the sync format to
be used for a specific peer independently of the local backend and its
format, so adding a peer to a context broke the context configuration
(BMC #1023).
This is now fixed by splitting "type" into four independent properties:
- backend = plugin which interfaces with the data
- databaseFormat = data format used inside backend, only relevant for file backend
- syncFormat = data format preferred when talking to peer
- forceSyncFormat = disable format auto-negotiation, use preferred format
With that split, it is now possible to specify the format in which the
file backend stores items independently of the format in which they
are exchanged with the peer.
Old configurations with "type" can still be read. The values specified
inside it are transparently mapped to the new properties. Command line
and D-Bus API users will only see the new properties.
The command line tool still accepts "type" as an alias for the four new
properties. Using that has the same disadvantage as before: it will modify
the context even if only modifying the peer was intended.
The D-Bus API accepts only the new properties. Clients using "type"
must be adapted to the new property names. Clients not using that
continue to run unchanged.
Writing into the configuration requires a migration of the peer config
*and* the context in which it is defined. That is necessary because
the new semantic (independent database format) cannot be stored in the
old format. The migration is handled by rewriting first the context,
then all peers defined inside it.
Other user-visible changes:
- updated help texts
- the canonical "backend" value for the file backend is just "file"
instead of the long "Files in one directory", which is now an alias
(used to be the other way around); done because "type = file"
was expanded to the long name, which was a bit unexpected and showed
how unintuitive the long name is
Internal changes:
- getMimeVersion() is still present, although it hasn't been used
for a long time; FileSyncSource::getMimeVersion() now derives
the version from the supported Mime types, in case that the
function will be needed again in the future
- setSourceType() with string as argument was replaced with one
taking a SourceType instance; to emulate the old behavior if
desired, construct SourceType from an old-style string
- ConfigProperty methods need to be virtual so that derived classes
like SourceBackendConfigProperty can generate content at runtime
(a recent commit broke that feature)
- File templates were stripped down to the essential properties,
with "type" replaced by the per-peer "syncFormat". "type" would
still have been accepted (so it is not necessary to adapt
syncevo-phone-config right away), but has the original
disadvantage of modifying "backend" and "databaseFormat".
2011-02-03 12:17:24 +01:00
{
// legacy "type" property is tried if the backend property is not set
2011-11-21 16:37:53 +01:00
InitStateString backend = sourcePropBackend . getProperty ( * nodes . getNode ( sourcePropBackend ) ) ;
if ( ! backend . wasSet ( ) ) {
config: replaced overloaded "type" with "backend/databaseFormat/syncFormat/forceSyncFormat" (BMC #1023)
The meaning of "type" was horribly complex and had effects on the
backend and the peer. It was impossible to specify the sync format to
be used for a specific peer independently of the local backend and its
format, so adding a peer to a context broke the context configuration
(BMC #1023).
This is now fixed by splitting "type" into four independent properties:
- backend = plugin which interfaces with the data
- databaseFormat = data format used inside backend, only relevant for file backend
- syncFormat = data format preferred when talking to peer
- forceSyncFormat = disable format auto-negotiation, use preferred format
With that split, it is now possible to specify the format in which the
file backend stores items independently of the format in which they
are exchanged with the peer.
Old configurations with "type" can still be read. The values specified
inside it are transparently mapped to the new properties. Command line
and D-Bus API users will only see the new properties.
The command line tool still accepts "type" as an alias for the four new
properties. Using that has the same disadvantage as before: it will modify
the context even if only modifying the peer was intended.
The D-Bus API accepts only the new properties. Clients using "type"
must be adapted to the new property names. Clients not using that
continue to run unchanged.
Writing into the configuration requires a migration of the peer config
*and* the context in which it is defined. That is necessary because
the new semantic (independent database format) cannot be stored in the
old format. The migration is handled by rewriting first the context,
then all peers defined inside it.
Other user-visible changes:
- updated help texts
- the canonical "backend" value for the file backend is just "file"
instead of the long "Files in one directory", which is now an alias
(used to be the other way around); done because "type = file"
was expanded to the long name, which was a bit unexpected and showed
how unintuitive the long name is
Internal changes:
- getMimeVersion() is still present, although it hasn't been used
for a long time; FileSyncSource::getMimeVersion() now derives
the version from the supported Mime types, in case that the
function will be needed again in the future
- setSourceType() with string as argument was replaced with one
taking a SourceType instance; to emulate the old behavior if
desired, construct SourceType from an old-style string
- ConfigProperty methods need to be virtual so that derived classes
like SourceBackendConfigProperty can generate content at runtime
(a recent commit broke that feature)
- File templates were stripped down to the essential properties,
with "type" replaced by the per-peer "syncFormat". "type" would
still have been accepted (so it is not necessary to adapt
syncevo-phone-config right away), but has the original
disadvantage of modifying "backend" and "databaseFormat".
2011-02-03 12:17:24 +01:00
string type ;
if ( nodes . getNode ( sourcePropBackend ) - > getProperty ( " type " , type ) ) {
2012-09-13 16:59:24 +02:00
return InitState < SourceType > ( SourceType ( type ) , true ) ;
config: replaced overloaded "type" with "backend/databaseFormat/syncFormat/forceSyncFormat" (BMC #1023)
The meaning of "type" was horribly complex and had effects on the
backend and the peer. It was impossible to specify the sync format to
be used for a specific peer independently of the local backend and its
format, so adding a peer to a context broke the context configuration
(BMC #1023).
This is now fixed by splitting "type" into four independent properties:
- backend = plugin which interfaces with the data
- databaseFormat = data format used inside backend, only relevant for file backend
- syncFormat = data format preferred when talking to peer
- forceSyncFormat = disable format auto-negotiation, use preferred format
With that split, it is now possible to specify the format in which the
file backend stores items independently of the format in which they
are exchanged with the peer.
Old configurations with "type" can still be read. The values specified
inside it are transparently mapped to the new properties. Command line
and D-Bus API users will only see the new properties.
The command line tool still accepts "type" as an alias for the four new
properties. Using that has the same disadvantage as before: it will modify
the context even if only modifying the peer was intended.
The D-Bus API accepts only the new properties. Clients using "type"
must be adapted to the new property names. Clients not using that
continue to run unchanged.
Writing into the configuration requires a migration of the peer config
*and* the context in which it is defined. That is necessary because
the new semantic (independent database format) cannot be stored in the
old format. The migration is handled by rewriting first the context,
then all peers defined inside it.
Other user-visible changes:
- updated help texts
- the canonical "backend" value for the file backend is just "file"
instead of the long "Files in one directory", which is now an alias
(used to be the other way around); done because "type = file"
was expanded to the long name, which was a bit unexpected and showed
how unintuitive the long name is
Internal changes:
- getMimeVersion() is still present, although it hasn't been used
for a long time; FileSyncSource::getMimeVersion() now derives
the version from the supported Mime types, in case that the
function will be needed again in the future
- setSourceType() with string as argument was replaced with one
taking a SourceType instance; to emulate the old behavior if
desired, construct SourceType from an old-style string
- ConfigProperty methods need to be virtual so that derived classes
like SourceBackendConfigProperty can generate content at runtime
(a recent commit broke that feature)
- File templates were stripped down to the essential properties,
with "type" replaced by the per-peer "syncFormat". "type" would
still have been accepted (so it is not necessary to adapt
syncevo-phone-config right away), but has the original
disadvantage of modifying "backend" and "databaseFormat".
2011-02-03 12:17:24 +01:00
}
}
SourceType sourceType ;
sourceType . m_backend = backend ;
sourceType . m_localFormat = sourcePropDatabaseFormat . getProperty ( * nodes . getNode ( sourcePropDatabaseFormat ) ) ;
sourceType . m_format = sourcePropSyncFormat . getProperty ( * nodes . getNode ( sourcePropSyncFormat ) ) ;
sourceType . m_forceFormat = sourcePropForceSyncFormat . getPropertyValue ( * nodes . getNode ( sourcePropForceSyncFormat ) ) ;
2012-09-13 16:59:24 +02:00
return InitState < SourceType > ( sourceType , backend . wasSet ( ) ) ;
2008-03-10 23:45:36 +01:00
}
2012-09-13 16:59:24 +02:00
InitState < SourceType > SyncSourceConfig : : getSourceType ( ) const { return getSourceType ( m_nodes ) ; }
2011-02-02 10:05:42 +01:00
void SyncSourceConfig : : setSourceType ( const SourceType & type , bool temporarily )
{
config: replaced overloaded "type" with "backend/databaseFormat/syncFormat/forceSyncFormat" (BMC #1023)
The meaning of "type" was horribly complex and had effects on the
backend and the peer. It was impossible to specify the sync format to
be used for a specific peer independently of the local backend and its
format, so adding a peer to a context broke the context configuration
(BMC #1023).
This is now fixed by splitting "type" into four independent properties:
- backend = plugin which interfaces with the data
- databaseFormat = data format used inside backend, only relevant for file backend
- syncFormat = data format preferred when talking to peer
- forceSyncFormat = disable format auto-negotiation, use preferred format
With that split, it is now possible to specify the format in which the
file backend stores items independently of the format in which they
are exchanged with the peer.
Old configurations with "type" can still be read. The values specified
inside it are transparently mapped to the new properties. Command line
and D-Bus API users will only see the new properties.
The command line tool still accepts "type" as an alias for the four new
properties. Using that has the same disadvantage as before: it will modify
the context even if only modifying the peer was intended.
The D-Bus API accepts only the new properties. Clients using "type"
must be adapted to the new property names. Clients not using that
continue to run unchanged.
Writing into the configuration requires a migration of the peer config
*and* the context in which it is defined. That is necessary because
the new semantic (independent database format) cannot be stored in the
old format. The migration is handled by rewriting first the context,
then all peers defined inside it.
Other user-visible changes:
- updated help texts
- the canonical "backend" value for the file backend is just "file"
instead of the long "Files in one directory", which is now an alias
(used to be the other way around); done because "type = file"
was expanded to the long name, which was a bit unexpected and showed
how unintuitive the long name is
Internal changes:
- getMimeVersion() is still present, although it hasn't been used
for a long time; FileSyncSource::getMimeVersion() now derives
the version from the supported Mime types, in case that the
function will be needed again in the future
- setSourceType() with string as argument was replaced with one
taking a SourceType instance; to emulate the old behavior if
desired, construct SourceType from an old-style string
- ConfigProperty methods need to be virtual so that derived classes
like SourceBackendConfigProperty can generate content at runtime
(a recent commit broke that feature)
- File templates were stripped down to the essential properties,
with "type" replaced by the per-peer "syncFormat". "type" would
still have been accepted (so it is not necessary to adapt
syncevo-phone-config right away), but has the original
disadvantage of modifying "backend" and "databaseFormat".
2011-02-03 12:17:24 +01:00
// writing always uses the new properties: the config must have
// been converted to the new format before writing is allowed
setBackend ( type . m_backend , temporarily ) ;
setDatabaseFormat ( type . m_localFormat , temporarily ) ;
2012-06-05 12:57:33 +02:00
setSyncFormat ( InitStateString ( type . m_format , ! type . m_format . empty ( ) ) , temporarily ) ;
config: replaced overloaded "type" with "backend/databaseFormat/syncFormat/forceSyncFormat" (BMC #1023)
The meaning of "type" was horribly complex and had effects on the
backend and the peer. It was impossible to specify the sync format to
be used for a specific peer independently of the local backend and its
format, so adding a peer to a context broke the context configuration
(BMC #1023).
This is now fixed by splitting "type" into four independent properties:
- backend = plugin which interfaces with the data
- databaseFormat = data format used inside backend, only relevant for file backend
- syncFormat = data format preferred when talking to peer
- forceSyncFormat = disable format auto-negotiation, use preferred format
With that split, it is now possible to specify the format in which the
file backend stores items independently of the format in which they
are exchanged with the peer.
Old configurations with "type" can still be read. The values specified
inside it are transparently mapped to the new properties. Command line
and D-Bus API users will only see the new properties.
The command line tool still accepts "type" as an alias for the four new
properties. Using that has the same disadvantage as before: it will modify
the context even if only modifying the peer was intended.
The D-Bus API accepts only the new properties. Clients using "type"
must be adapted to the new property names. Clients not using that
continue to run unchanged.
Writing into the configuration requires a migration of the peer config
*and* the context in which it is defined. That is necessary because
the new semantic (independent database format) cannot be stored in the
old format. The migration is handled by rewriting first the context,
then all peers defined inside it.
Other user-visible changes:
- updated help texts
- the canonical "backend" value for the file backend is just "file"
instead of the long "Files in one directory", which is now an alias
(used to be the other way around); done because "type = file"
was expanded to the long name, which was a bit unexpected and showed
how unintuitive the long name is
Internal changes:
- getMimeVersion() is still present, although it hasn't been used
for a long time; FileSyncSource::getMimeVersion() now derives
the version from the supported Mime types, in case that the
function will be needed again in the future
- setSourceType() with string as argument was replaced with one
taking a SourceType instance; to emulate the old behavior if
desired, construct SourceType from an old-style string
- ConfigProperty methods need to be virtual so that derived classes
like SourceBackendConfigProperty can generate content at runtime
(a recent commit broke that feature)
- File templates were stripped down to the essential properties,
with "type" replaced by the per-peer "syncFormat". "type" would
still have been accepted (so it is not necessary to adapt
syncevo-phone-config right away), but has the original
disadvantage of modifying "backend" and "databaseFormat".
2011-02-03 12:17:24 +01:00
setForceSyncFormat ( type . m_forceFormat , temporarily ) ;
}
void SyncSourceConfig : : setBackend ( const std : : string & value , bool temporarily )
{
sourcePropBackend . setProperty ( * getNode ( sourcePropBackend ) ,
value ,
temporarily ) ;
}
2011-11-21 16:37:53 +01:00
InitStateString SyncSourceConfig : : getBackend ( ) const
config: replaced overloaded "type" with "backend/databaseFormat/syncFormat/forceSyncFormat" (BMC #1023)
The meaning of "type" was horribly complex and had effects on the
backend and the peer. It was impossible to specify the sync format to
be used for a specific peer independently of the local backend and its
format, so adding a peer to a context broke the context configuration
(BMC #1023).
This is now fixed by splitting "type" into four independent properties:
- backend = plugin which interfaces with the data
- databaseFormat = data format used inside backend, only relevant for file backend
- syncFormat = data format preferred when talking to peer
- forceSyncFormat = disable format auto-negotiation, use preferred format
With that split, it is now possible to specify the format in which the
file backend stores items independently of the format in which they
are exchanged with the peer.
Old configurations with "type" can still be read. The values specified
inside it are transparently mapped to the new properties. Command line
and D-Bus API users will only see the new properties.
The command line tool still accepts "type" as an alias for the four new
properties. Using that has the same disadvantage as before: it will modify
the context even if only modifying the peer was intended.
The D-Bus API accepts only the new properties. Clients using "type"
must be adapted to the new property names. Clients not using that
continue to run unchanged.
Writing into the configuration requires a migration of the peer config
*and* the context in which it is defined. That is necessary because
the new semantic (independent database format) cannot be stored in the
old format. The migration is handled by rewriting first the context,
then all peers defined inside it.
Other user-visible changes:
- updated help texts
- the canonical "backend" value for the file backend is just "file"
instead of the long "Files in one directory", which is now an alias
(used to be the other way around); done because "type = file"
was expanded to the long name, which was a bit unexpected and showed
how unintuitive the long name is
Internal changes:
- getMimeVersion() is still present, although it hasn't been used
for a long time; FileSyncSource::getMimeVersion() now derives
the version from the supported Mime types, in case that the
function will be needed again in the future
- setSourceType() with string as argument was replaced with one
taking a SourceType instance; to emulate the old behavior if
desired, construct SourceType from an old-style string
- ConfigProperty methods need to be virtual so that derived classes
like SourceBackendConfigProperty can generate content at runtime
(a recent commit broke that feature)
- File templates were stripped down to the essential properties,
with "type" replaced by the per-peer "syncFormat". "type" would
still have been accepted (so it is not necessary to adapt
syncevo-phone-config right away), but has the original
disadvantage of modifying "backend" and "databaseFormat".
2011-02-03 12:17:24 +01:00
{
return sourcePropBackend . getProperty ( * getNode ( sourcePropBackend ) ) ;
}
void SyncSourceConfig : : setDatabaseFormat ( const std : : string & value , bool temporarily )
{
sourcePropDatabaseFormat . setProperty ( * getNode ( sourcePropDatabaseFormat ) ,
value ,
temporarily ) ;
}
2011-11-21 16:37:53 +01:00
InitStateString SyncSourceConfig : : getDatabaseFormat ( ) const
config: replaced overloaded "type" with "backend/databaseFormat/syncFormat/forceSyncFormat" (BMC #1023)
The meaning of "type" was horribly complex and had effects on the
backend and the peer. It was impossible to specify the sync format to
be used for a specific peer independently of the local backend and its
format, so adding a peer to a context broke the context configuration
(BMC #1023).
This is now fixed by splitting "type" into four independent properties:
- backend = plugin which interfaces with the data
- databaseFormat = data format used inside backend, only relevant for file backend
- syncFormat = data format preferred when talking to peer
- forceSyncFormat = disable format auto-negotiation, use preferred format
With that split, it is now possible to specify the format in which the
file backend stores items independently of the format in which they
are exchanged with the peer.
Old configurations with "type" can still be read. The values specified
inside it are transparently mapped to the new properties. Command line
and D-Bus API users will only see the new properties.
The command line tool still accepts "type" as an alias for the four new
properties. Using that has the same disadvantage as before: it will modify
the context even if only modifying the peer was intended.
The D-Bus API accepts only the new properties. Clients using "type"
must be adapted to the new property names. Clients not using that
continue to run unchanged.
Writing into the configuration requires a migration of the peer config
*and* the context in which it is defined. That is necessary because
the new semantic (independent database format) cannot be stored in the
old format. The migration is handled by rewriting first the context,
then all peers defined inside it.
Other user-visible changes:
- updated help texts
- the canonical "backend" value for the file backend is just "file"
instead of the long "Files in one directory", which is now an alias
(used to be the other way around); done because "type = file"
was expanded to the long name, which was a bit unexpected and showed
how unintuitive the long name is
Internal changes:
- getMimeVersion() is still present, although it hasn't been used
for a long time; FileSyncSource::getMimeVersion() now derives
the version from the supported Mime types, in case that the
function will be needed again in the future
- setSourceType() with string as argument was replaced with one
taking a SourceType instance; to emulate the old behavior if
desired, construct SourceType from an old-style string
- ConfigProperty methods need to be virtual so that derived classes
like SourceBackendConfigProperty can generate content at runtime
(a recent commit broke that feature)
- File templates were stripped down to the essential properties,
with "type" replaced by the per-peer "syncFormat". "type" would
still have been accepted (so it is not necessary to adapt
syncevo-phone-config right away), but has the original
disadvantage of modifying "backend" and "databaseFormat".
2011-02-03 12:17:24 +01:00
{
return sourcePropDatabaseFormat . getProperty ( * getNode ( sourcePropDatabaseFormat ) ) ;
}
2012-06-05 12:57:33 +02:00
void SyncSourceConfig : : setSyncFormat ( const InitStateString & value , bool temporarily )
config: replaced overloaded "type" with "backend/databaseFormat/syncFormat/forceSyncFormat" (BMC #1023)
The meaning of "type" was horribly complex and had effects on the
backend and the peer. It was impossible to specify the sync format to
be used for a specific peer independently of the local backend and its
format, so adding a peer to a context broke the context configuration
(BMC #1023).
This is now fixed by splitting "type" into four independent properties:
- backend = plugin which interfaces with the data
- databaseFormat = data format used inside backend, only relevant for file backend
- syncFormat = data format preferred when talking to peer
- forceSyncFormat = disable format auto-negotiation, use preferred format
With that split, it is now possible to specify the format in which the
file backend stores items independently of the format in which they
are exchanged with the peer.
Old configurations with "type" can still be read. The values specified
inside it are transparently mapped to the new properties. Command line
and D-Bus API users will only see the new properties.
The command line tool still accepts "type" as an alias for the four new
properties. Using that has the same disadvantage as before: it will modify
the context even if only modifying the peer was intended.
The D-Bus API accepts only the new properties. Clients using "type"
must be adapted to the new property names. Clients not using that
continue to run unchanged.
Writing into the configuration requires a migration of the peer config
*and* the context in which it is defined. That is necessary because
the new semantic (independent database format) cannot be stored in the
old format. The migration is handled by rewriting first the context,
then all peers defined inside it.
Other user-visible changes:
- updated help texts
- the canonical "backend" value for the file backend is just "file"
instead of the long "Files in one directory", which is now an alias
(used to be the other way around); done because "type = file"
was expanded to the long name, which was a bit unexpected and showed
how unintuitive the long name is
Internal changes:
- getMimeVersion() is still present, although it hasn't been used
for a long time; FileSyncSource::getMimeVersion() now derives
the version from the supported Mime types, in case that the
function will be needed again in the future
- setSourceType() with string as argument was replaced with one
taking a SourceType instance; to emulate the old behavior if
desired, construct SourceType from an old-style string
- ConfigProperty methods need to be virtual so that derived classes
like SourceBackendConfigProperty can generate content at runtime
(a recent commit broke that feature)
- File templates were stripped down to the essential properties,
with "type" replaced by the per-peer "syncFormat". "type" would
still have been accepted (so it is not necessary to adapt
syncevo-phone-config right away), but has the original
disadvantage of modifying "backend" and "databaseFormat".
2011-02-03 12:17:24 +01:00
{
sourcePropSyncFormat . setProperty ( * getNode ( sourcePropSyncFormat ) ,
value ,
temporarily ) ;
}
2011-11-21 16:37:53 +01:00
InitStateString SyncSourceConfig : : getSyncFormat ( ) const
config: replaced overloaded "type" with "backend/databaseFormat/syncFormat/forceSyncFormat" (BMC #1023)
The meaning of "type" was horribly complex and had effects on the
backend and the peer. It was impossible to specify the sync format to
be used for a specific peer independently of the local backend and its
format, so adding a peer to a context broke the context configuration
(BMC #1023).
This is now fixed by splitting "type" into four independent properties:
- backend = plugin which interfaces with the data
- databaseFormat = data format used inside backend, only relevant for file backend
- syncFormat = data format preferred when talking to peer
- forceSyncFormat = disable format auto-negotiation, use preferred format
With that split, it is now possible to specify the format in which the
file backend stores items independently of the format in which they
are exchanged with the peer.
Old configurations with "type" can still be read. The values specified
inside it are transparently mapped to the new properties. Command line
and D-Bus API users will only see the new properties.
The command line tool still accepts "type" as an alias for the four new
properties. Using that has the same disadvantage as before: it will modify
the context even if only modifying the peer was intended.
The D-Bus API accepts only the new properties. Clients using "type"
must be adapted to the new property names. Clients not using that
continue to run unchanged.
Writing into the configuration requires a migration of the peer config
*and* the context in which it is defined. That is necessary because
the new semantic (independent database format) cannot be stored in the
old format. The migration is handled by rewriting first the context,
then all peers defined inside it.
Other user-visible changes:
- updated help texts
- the canonical "backend" value for the file backend is just "file"
instead of the long "Files in one directory", which is now an alias
(used to be the other way around); done because "type = file"
was expanded to the long name, which was a bit unexpected and showed
how unintuitive the long name is
Internal changes:
- getMimeVersion() is still present, although it hasn't been used
for a long time; FileSyncSource::getMimeVersion() now derives
the version from the supported Mime types, in case that the
function will be needed again in the future
- setSourceType() with string as argument was replaced with one
taking a SourceType instance; to emulate the old behavior if
desired, construct SourceType from an old-style string
- ConfigProperty methods need to be virtual so that derived classes
like SourceBackendConfigProperty can generate content at runtime
(a recent commit broke that feature)
- File templates were stripped down to the essential properties,
with "type" replaced by the per-peer "syncFormat". "type" would
still have been accepted (so it is not necessary to adapt
syncevo-phone-config right away), but has the original
disadvantage of modifying "backend" and "databaseFormat".
2011-02-03 12:17:24 +01:00
{
return sourcePropSyncFormat . getProperty ( * getNode ( sourcePropSyncFormat ) ) ;
}
void SyncSourceConfig : : setForceSyncFormat ( bool value , bool temporarily )
{
sourcePropForceSyncFormat . setProperty ( * getNode ( sourcePropForceSyncFormat ) ,
value ,
temporarily ) ;
}
2011-11-21 16:37:53 +01:00
InitState < bool > SyncSourceConfig : : getForceSyncFormat ( ) const
config: replaced overloaded "type" with "backend/databaseFormat/syncFormat/forceSyncFormat" (BMC #1023)
The meaning of "type" was horribly complex and had effects on the
backend and the peer. It was impossible to specify the sync format to
be used for a specific peer independently of the local backend and its
format, so adding a peer to a context broke the context configuration
(BMC #1023).
This is now fixed by splitting "type" into four independent properties:
- backend = plugin which interfaces with the data
- databaseFormat = data format used inside backend, only relevant for file backend
- syncFormat = data format preferred when talking to peer
- forceSyncFormat = disable format auto-negotiation, use preferred format
With that split, it is now possible to specify the format in which the
file backend stores items independently of the format in which they
are exchanged with the peer.
Old configurations with "type" can still be read. The values specified
inside it are transparently mapped to the new properties. Command line
and D-Bus API users will only see the new properties.
The command line tool still accepts "type" as an alias for the four new
properties. Using that has the same disadvantage as before: it will modify
the context even if only modifying the peer was intended.
The D-Bus API accepts only the new properties. Clients using "type"
must be adapted to the new property names. Clients not using that
continue to run unchanged.
Writing into the configuration requires a migration of the peer config
*and* the context in which it is defined. That is necessary because
the new semantic (independent database format) cannot be stored in the
old format. The migration is handled by rewriting first the context,
then all peers defined inside it.
Other user-visible changes:
- updated help texts
- the canonical "backend" value for the file backend is just "file"
instead of the long "Files in one directory", which is now an alias
(used to be the other way around); done because "type = file"
was expanded to the long name, which was a bit unexpected and showed
how unintuitive the long name is
Internal changes:
- getMimeVersion() is still present, although it hasn't been used
for a long time; FileSyncSource::getMimeVersion() now derives
the version from the supported Mime types, in case that the
function will be needed again in the future
- setSourceType() with string as argument was replaced with one
taking a SourceType instance; to emulate the old behavior if
desired, construct SourceType from an old-style string
- ConfigProperty methods need to be virtual so that derived classes
like SourceBackendConfigProperty can generate content at runtime
(a recent commit broke that feature)
- File templates were stripped down to the essential properties,
with "type" replaced by the per-peer "syncFormat". "type" would
still have been accepted (so it is not necessary to adapt
syncevo-phone-config right away), but has the original
disadvantage of modifying "backend" and "databaseFormat".
2011-02-03 12:17:24 +01:00
{
return sourcePropForceSyncFormat . getPropertyValue ( * getNode ( sourcePropForceSyncFormat ) ) ;
2011-02-02 10:05:42 +01:00
}
2009-09-21 10:07:05 +02:00
2013-07-11 12:12:49 +02:00
InitState < int > SyncSourceConfig : : getSynthesisID ( ) const {
if ( ! m_synthesisID . wasSet ( ) ) {
const_cast < InitState < int > & > ( m_synthesisID ) = sourcePropSynthesisID . getPropertyValue ( * getNode ( sourcePropSynthesisID ) ) ;
}
return m_synthesisID ;
}
void SyncSourceConfig : : setSynthesisID ( int value , bool temporarily ) {
m_synthesisID = value ;
sourcePropSynthesisID . setProperty ( * getNode ( sourcePropSynthesisID ) , value , temporarily ) ;
}
2010-02-15 16:50:06 +01:00
2009-09-21 10:07:05 +02:00
Configuration templates matching: match templates based on metadata
Introduced TemplateConfig to abstracting the template configuration structure,
the template metadata used for matching is also parsed here.
The fields introduced in the metadata are:
PeerIsClient: identify whether this is a server side configuration or a client
side configuration.
Fingerprint: the matching string for this template, it is a comma separated string
with each string modeled as: "Manufacture_Model". The first substring is also
used as the name to identify this template so that user can select the template
by this name.
eg:
Nokia 7210c: Nokia_7210c
SyncEvolution server: SyncEvolutionServer, SyncEvolution
ScheduleWorld: ScheduleWorld,default
SyncEvolution client: SyncEvolutionClient, SyncEvolution
Description: this is a just a descriptive string not used for matching.
GetServerTemplates is changed to add another "devices" parameter to identify
it is asking for templates for a list of "devices". Each device is a tuple
<matchstring (devicename), matchMode (server/client/all)>.
TemplateList as the return type, which is a list of class TemplateDescription
so that we can also return enough information for corresponding templates. This
list is sorted by the 3-tuple <finger, rank, name>.
Add MatchServerTemplates method which will iterating all templates inside the
folder and match against the input parameter and finally return a sorted
list of matched templates.
The atcually fuzzy match algorithm is based on a LCS (added in the following
commit).
Cmdline interface is changed accordingly:
--template ? is changed to --template ?[string], so that user use the former
case to match all templates for a tradiontial SyncML client and the latter case
to match templates related to an input string.
SyncConfig API is also renamed (Server -> Peer) because both server/client
configuration/template are handled.
The original configuration template (Funambol and ScheduleWorld) has been moved
to the new template structure (under servers), they also have a .template.ini
file added so that they can be matched and picked up. All templates for
supported servers still have built-in template support in the code as before.
Templates for SyncEvolution based server is also added.
Server side templates are added (Nokia default, Nokia_7210c and SyncEvolutionServer).
Add unit test for the new template match use case.
2010-01-19 08:01:05 +01:00
// Used for built-in templates
SyncConfig : : TemplateDescription : : TemplateDescription ( const std : : string & name , const std : : string & description )
2010-03-25 04:26:13 +01:00
: m_templateId ( name ) , m_description ( description )
Configuration templates matching: match templates based on metadata
Introduced TemplateConfig to abstracting the template configuration structure,
the template metadata used for matching is also parsed here.
The fields introduced in the metadata are:
PeerIsClient: identify whether this is a server side configuration or a client
side configuration.
Fingerprint: the matching string for this template, it is a comma separated string
with each string modeled as: "Manufacture_Model". The first substring is also
used as the name to identify this template so that user can select the template
by this name.
eg:
Nokia 7210c: Nokia_7210c
SyncEvolution server: SyncEvolutionServer, SyncEvolution
ScheduleWorld: ScheduleWorld,default
SyncEvolution client: SyncEvolutionClient, SyncEvolution
Description: this is a just a descriptive string not used for matching.
GetServerTemplates is changed to add another "devices" parameter to identify
it is asking for templates for a list of "devices". Each device is a tuple
<matchstring (devicename), matchMode (server/client/all)>.
TemplateList as the return type, which is a list of class TemplateDescription
so that we can also return enough information for corresponding templates. This
list is sorted by the 3-tuple <finger, rank, name>.
Add MatchServerTemplates method which will iterating all templates inside the
folder and match against the input parameter and finally return a sorted
list of matched templates.
The atcually fuzzy match algorithm is based on a LCS (added in the following
commit).
Cmdline interface is changed accordingly:
--template ? is changed to --template ?[string], so that user use the former
case to match all templates for a tradiontial SyncML client and the latter case
to match templates related to an input string.
SyncConfig API is also renamed (Server -> Peer) because both server/client
configuration/template are handled.
The original configuration template (Funambol and ScheduleWorld) has been moved
to the new template structure (under servers), they also have a .template.ini
file added so that they can be matched and picked up. All templates for
supported servers still have built-in template support in the code as before.
Templates for SyncEvolution based server is also added.
Server side templates are added (Nokia default, Nokia_7210c and SyncEvolutionServer).
Add unit test for the new template match use case.
2010-01-19 08:01:05 +01:00
{
m_rank = TemplateConfig : : LEVEL3_MATCH ;
2011-08-29 16:12:46 +02:00
m_deviceName = " " ;
Configuration templates matching: match templates based on metadata
Introduced TemplateConfig to abstracting the template configuration structure,
the template metadata used for matching is also parsed here.
The fields introduced in the metadata are:
PeerIsClient: identify whether this is a server side configuration or a client
side configuration.
Fingerprint: the matching string for this template, it is a comma separated string
with each string modeled as: "Manufacture_Model". The first substring is also
used as the name to identify this template so that user can select the template
by this name.
eg:
Nokia 7210c: Nokia_7210c
SyncEvolution server: SyncEvolutionServer, SyncEvolution
ScheduleWorld: ScheduleWorld,default
SyncEvolution client: SyncEvolutionClient, SyncEvolution
Description: this is a just a descriptive string not used for matching.
GetServerTemplates is changed to add another "devices" parameter to identify
it is asking for templates for a list of "devices". Each device is a tuple
<matchstring (devicename), matchMode (server/client/all)>.
TemplateList as the return type, which is a list of class TemplateDescription
so that we can also return enough information for corresponding templates. This
list is sorted by the 3-tuple <finger, rank, name>.
Add MatchServerTemplates method which will iterating all templates inside the
folder and match against the input parameter and finally return a sorted
list of matched templates.
The atcually fuzzy match algorithm is based on a LCS (added in the following
commit).
Cmdline interface is changed accordingly:
--template ? is changed to --template ?[string], so that user use the former
case to match all templates for a tradiontial SyncML client and the latter case
to match templates related to an input string.
SyncConfig API is also renamed (Server -> Peer) because both server/client
configuration/template are handled.
The original configuration template (Funambol and ScheduleWorld) has been moved
to the new template structure (under servers), they also have a .template.ini
file added so that they can be matched and picked up. All templates for
supported servers still have built-in template support in the code as before.
Templates for SyncEvolution based server is also added.
Server side templates are added (Nokia default, Nokia_7210c and SyncEvolutionServer).
Add unit test for the new template match use case.
2010-01-19 08:01:05 +01:00
m_path = " " ;
m_matchedModel = name ;
}
/* Ranking of template description is controled by the rank field, larger the
* better
*/
2018-01-16 17:17:34 +01:00
bool SyncConfig : : TemplateDescription : : compare_op ( std : : shared_ptr < SyncConfig : : TemplateDescription > & left , std : : shared_ptr < SyncConfig : : TemplateDescription > & right )
Configuration templates matching: match templates based on metadata
Introduced TemplateConfig to abstracting the template configuration structure,
the template metadata used for matching is also parsed here.
The fields introduced in the metadata are:
PeerIsClient: identify whether this is a server side configuration or a client
side configuration.
Fingerprint: the matching string for this template, it is a comma separated string
with each string modeled as: "Manufacture_Model". The first substring is also
used as the name to identify this template so that user can select the template
by this name.
eg:
Nokia 7210c: Nokia_7210c
SyncEvolution server: SyncEvolutionServer, SyncEvolution
ScheduleWorld: ScheduleWorld,default
SyncEvolution client: SyncEvolutionClient, SyncEvolution
Description: this is a just a descriptive string not used for matching.
GetServerTemplates is changed to add another "devices" parameter to identify
it is asking for templates for a list of "devices". Each device is a tuple
<matchstring (devicename), matchMode (server/client/all)>.
TemplateList as the return type, which is a list of class TemplateDescription
so that we can also return enough information for corresponding templates. This
list is sorted by the 3-tuple <finger, rank, name>.
Add MatchServerTemplates method which will iterating all templates inside the
folder and match against the input parameter and finally return a sorted
list of matched templates.
The atcually fuzzy match algorithm is based on a LCS (added in the following
commit).
Cmdline interface is changed accordingly:
--template ? is changed to --template ?[string], so that user use the former
case to match all templates for a tradiontial SyncML client and the latter case
to match templates related to an input string.
SyncConfig API is also renamed (Server -> Peer) because both server/client
configuration/template are handled.
The original configuration template (Funambol and ScheduleWorld) has been moved
to the new template structure (under servers), they also have a .template.ini
file added so that they can be matched and picked up. All templates for
supported servers still have built-in template support in the code as before.
Templates for SyncEvolution based server is also added.
Server side templates are added (Nokia default, Nokia_7210c and SyncEvolutionServer).
Add unit test for the new template match use case.
2010-01-19 08:01:05 +01:00
{
//first sort against the fingerprint string
2011-08-29 16:12:46 +02:00
if ( left - > m_deviceName ! = right - > m_deviceName ) {
return ( left - > m_deviceName < right - > m_deviceName ) ;
Configuration templates matching: match templates based on metadata
Introduced TemplateConfig to abstracting the template configuration structure,
the template metadata used for matching is also parsed here.
The fields introduced in the metadata are:
PeerIsClient: identify whether this is a server side configuration or a client
side configuration.
Fingerprint: the matching string for this template, it is a comma separated string
with each string modeled as: "Manufacture_Model". The first substring is also
used as the name to identify this template so that user can select the template
by this name.
eg:
Nokia 7210c: Nokia_7210c
SyncEvolution server: SyncEvolutionServer, SyncEvolution
ScheduleWorld: ScheduleWorld,default
SyncEvolution client: SyncEvolutionClient, SyncEvolution
Description: this is a just a descriptive string not used for matching.
GetServerTemplates is changed to add another "devices" parameter to identify
it is asking for templates for a list of "devices". Each device is a tuple
<matchstring (devicename), matchMode (server/client/all)>.
TemplateList as the return type, which is a list of class TemplateDescription
so that we can also return enough information for corresponding templates. This
list is sorted by the 3-tuple <finger, rank, name>.
Add MatchServerTemplates method which will iterating all templates inside the
folder and match against the input parameter and finally return a sorted
list of matched templates.
The atcually fuzzy match algorithm is based on a LCS (added in the following
commit).
Cmdline interface is changed accordingly:
--template ? is changed to --template ?[string], so that user use the former
case to match all templates for a tradiontial SyncML client and the latter case
to match templates related to an input string.
SyncConfig API is also renamed (Server -> Peer) because both server/client
configuration/template are handled.
The original configuration template (Funambol and ScheduleWorld) has been moved
to the new template structure (under servers), they also have a .template.ini
file added so that they can be matched and picked up. All templates for
supported servers still have built-in template support in the code as before.
Templates for SyncEvolution based server is also added.
Server side templates are added (Nokia default, Nokia_7210c and SyncEvolutionServer).
Add unit test for the new template match use case.
2010-01-19 08:01:05 +01:00
}
// sort against the rank
if ( right - > m_rank ! = left - > m_rank ) {
return ( right - > m_rank < left - > m_rank ) ;
}
2011-04-15 08:15:19 +02:00
// sort against the template id, case-insensitive (for eGroupware < Funambol)
return boost : : ilexicographical_compare ( left - > m_templateId , right - > m_templateId ) ;
Configuration templates matching: match templates based on metadata
Introduced TemplateConfig to abstracting the template configuration structure,
the template metadata used for matching is also parsed here.
The fields introduced in the metadata are:
PeerIsClient: identify whether this is a server side configuration or a client
side configuration.
Fingerprint: the matching string for this template, it is a comma separated string
with each string modeled as: "Manufacture_Model". The first substring is also
used as the name to identify this template so that user can select the template
by this name.
eg:
Nokia 7210c: Nokia_7210c
SyncEvolution server: SyncEvolutionServer, SyncEvolution
ScheduleWorld: ScheduleWorld,default
SyncEvolution client: SyncEvolutionClient, SyncEvolution
Description: this is a just a descriptive string not used for matching.
GetServerTemplates is changed to add another "devices" parameter to identify
it is asking for templates for a list of "devices". Each device is a tuple
<matchstring (devicename), matchMode (server/client/all)>.
TemplateList as the return type, which is a list of class TemplateDescription
so that we can also return enough information for corresponding templates. This
list is sorted by the 3-tuple <finger, rank, name>.
Add MatchServerTemplates method which will iterating all templates inside the
folder and match against the input parameter and finally return a sorted
list of matched templates.
The atcually fuzzy match algorithm is based on a LCS (added in the following
commit).
Cmdline interface is changed accordingly:
--template ? is changed to --template ?[string], so that user use the former
case to match all templates for a tradiontial SyncML client and the latter case
to match templates related to an input string.
SyncConfig API is also renamed (Server -> Peer) because both server/client
configuration/template are handled.
The original configuration template (Funambol and ScheduleWorld) has been moved
to the new template structure (under servers), they also have a .template.ini
file added so that they can be matched and picked up. All templates for
supported servers still have built-in template support in the code as before.
Templates for SyncEvolution based server is also added.
Server side templates are added (Nokia default, Nokia_7210c and SyncEvolutionServer).
Add unit test for the new template match use case.
2010-01-19 08:01:05 +01:00
}
2010-05-03 17:47:18 +02:00
TemplateConfig : : TemplateConfig ( const string & path ) :
m_template ( new SingleFileConfigTree ( path ) )
Configuration templates matching: match templates based on metadata
Introduced TemplateConfig to abstracting the template configuration structure,
the template metadata used for matching is also parsed here.
The fields introduced in the metadata are:
PeerIsClient: identify whether this is a server side configuration or a client
side configuration.
Fingerprint: the matching string for this template, it is a comma separated string
with each string modeled as: "Manufacture_Model". The first substring is also
used as the name to identify this template so that user can select the template
by this name.
eg:
Nokia 7210c: Nokia_7210c
SyncEvolution server: SyncEvolutionServer, SyncEvolution
ScheduleWorld: ScheduleWorld,default
SyncEvolution client: SyncEvolutionClient, SyncEvolution
Description: this is a just a descriptive string not used for matching.
GetServerTemplates is changed to add another "devices" parameter to identify
it is asking for templates for a list of "devices". Each device is a tuple
<matchstring (devicename), matchMode (server/client/all)>.
TemplateList as the return type, which is a list of class TemplateDescription
so that we can also return enough information for corresponding templates. This
list is sorted by the 3-tuple <finger, rank, name>.
Add MatchServerTemplates method which will iterating all templates inside the
folder and match against the input parameter and finally return a sorted
list of matched templates.
The atcually fuzzy match algorithm is based on a LCS (added in the following
commit).
Cmdline interface is changed accordingly:
--template ? is changed to --template ?[string], so that user use the former
case to match all templates for a tradiontial SyncML client and the latter case
to match templates related to an input string.
SyncConfig API is also renamed (Server -> Peer) because both server/client
configuration/template are handled.
The original configuration template (Funambol and ScheduleWorld) has been moved
to the new template structure (under servers), they also have a .template.ini
file added so that they can be matched and picked up. All templates for
supported servers still have built-in template support in the code as before.
Templates for SyncEvolution based server is also added.
Server side templates are added (Nokia default, Nokia_7210c and SyncEvolutionServer).
Add unit test for the new template match use case.
2010-01-19 08:01:05 +01:00
{
2018-01-16 17:17:34 +01:00
std : : shared_ptr < ConfigNode > metaNode = m_template - > open ( " template.ini " ) ;
2010-05-03 17:47:18 +02:00
metaNode - > readProperties ( m_metaProps ) ;
Configuration templates matching: match templates based on metadata
Introduced TemplateConfig to abstracting the template configuration structure,
the template metadata used for matching is also parsed here.
The fields introduced in the metadata are:
PeerIsClient: identify whether this is a server side configuration or a client
side configuration.
Fingerprint: the matching string for this template, it is a comma separated string
with each string modeled as: "Manufacture_Model". The first substring is also
used as the name to identify this template so that user can select the template
by this name.
eg:
Nokia 7210c: Nokia_7210c
SyncEvolution server: SyncEvolutionServer, SyncEvolution
ScheduleWorld: ScheduleWorld,default
SyncEvolution client: SyncEvolutionClient, SyncEvolution
Description: this is a just a descriptive string not used for matching.
GetServerTemplates is changed to add another "devices" parameter to identify
it is asking for templates for a list of "devices". Each device is a tuple
<matchstring (devicename), matchMode (server/client/all)>.
TemplateList as the return type, which is a list of class TemplateDescription
so that we can also return enough information for corresponding templates. This
list is sorted by the 3-tuple <finger, rank, name>.
Add MatchServerTemplates method which will iterating all templates inside the
folder and match against the input parameter and finally return a sorted
list of matched templates.
The atcually fuzzy match algorithm is based on a LCS (added in the following
commit).
Cmdline interface is changed accordingly:
--template ? is changed to --template ?[string], so that user use the former
case to match all templates for a tradiontial SyncML client and the latter case
to match templates related to an input string.
SyncConfig API is also renamed (Server -> Peer) because both server/client
configuration/template are handled.
The original configuration template (Funambol and ScheduleWorld) has been moved
to the new template structure (under servers), they also have a .template.ini
file added so that they can be matched and picked up. All templates for
supported servers still have built-in template support in the code as before.
Templates for SyncEvolution based server is also added.
Server side templates are added (Nokia default, Nokia_7210c and SyncEvolutionServer).
Add unit test for the new template match use case.
2010-01-19 08:01:05 +01:00
}
2010-05-03 17:47:18 +02:00
bool TemplateConfig : : isTemplateConfig ( const string & path )
Configuration templates matching: match templates based on metadata
Introduced TemplateConfig to abstracting the template configuration structure,
the template metadata used for matching is also parsed here.
The fields introduced in the metadata are:
PeerIsClient: identify whether this is a server side configuration or a client
side configuration.
Fingerprint: the matching string for this template, it is a comma separated string
with each string modeled as: "Manufacture_Model". The first substring is also
used as the name to identify this template so that user can select the template
by this name.
eg:
Nokia 7210c: Nokia_7210c
SyncEvolution server: SyncEvolutionServer, SyncEvolution
ScheduleWorld: ScheduleWorld,default
SyncEvolution client: SyncEvolutionClient, SyncEvolution
Description: this is a just a descriptive string not used for matching.
GetServerTemplates is changed to add another "devices" parameter to identify
it is asking for templates for a list of "devices". Each device is a tuple
<matchstring (devicename), matchMode (server/client/all)>.
TemplateList as the return type, which is a list of class TemplateDescription
so that we can also return enough information for corresponding templates. This
list is sorted by the 3-tuple <finger, rank, name>.
Add MatchServerTemplates method which will iterating all templates inside the
folder and match against the input parameter and finally return a sorted
list of matched templates.
The atcually fuzzy match algorithm is based on a LCS (added in the following
commit).
Cmdline interface is changed accordingly:
--template ? is changed to --template ?[string], so that user use the former
case to match all templates for a tradiontial SyncML client and the latter case
to match templates related to an input string.
SyncConfig API is also renamed (Server -> Peer) because both server/client
configuration/template are handled.
The original configuration template (Funambol and ScheduleWorld) has been moved
to the new template structure (under servers), they also have a .template.ini
file added so that they can be matched and picked up. All templates for
supported servers still have built-in template support in the code as before.
Templates for SyncEvolution based server is also added.
Server side templates are added (Nokia default, Nokia_7210c and SyncEvolutionServer).
Add unit test for the new template match use case.
2010-01-19 08:01:05 +01:00
{
2010-05-03 17:47:18 +02:00
SingleFileConfigTree templ ( path ) ;
2018-01-16 17:17:34 +01:00
std : : shared_ptr < ConfigNode > metaNode = templ . open ( " template.ini " ) ;
2010-05-03 17:47:18 +02:00
if ( ! metaNode - > exists ( ) ) {
return false ;
}
ConfigProps props ;
metaNode - > readProperties ( props ) ;
return ! props . empty ( ) ;
Configuration templates matching: match templates based on metadata
Introduced TemplateConfig to abstracting the template configuration structure,
the template metadata used for matching is also parsed here.
The fields introduced in the metadata are:
PeerIsClient: identify whether this is a server side configuration or a client
side configuration.
Fingerprint: the matching string for this template, it is a comma separated string
with each string modeled as: "Manufacture_Model". The first substring is also
used as the name to identify this template so that user can select the template
by this name.
eg:
Nokia 7210c: Nokia_7210c
SyncEvolution server: SyncEvolutionServer, SyncEvolution
ScheduleWorld: ScheduleWorld,default
SyncEvolution client: SyncEvolutionClient, SyncEvolution
Description: this is a just a descriptive string not used for matching.
GetServerTemplates is changed to add another "devices" parameter to identify
it is asking for templates for a list of "devices". Each device is a tuple
<matchstring (devicename), matchMode (server/client/all)>.
TemplateList as the return type, which is a list of class TemplateDescription
so that we can also return enough information for corresponding templates. This
list is sorted by the 3-tuple <finger, rank, name>.
Add MatchServerTemplates method which will iterating all templates inside the
folder and match against the input parameter and finally return a sorted
list of matched templates.
The atcually fuzzy match algorithm is based on a LCS (added in the following
commit).
Cmdline interface is changed accordingly:
--template ? is changed to --template ?[string], so that user use the former
case to match all templates for a tradiontial SyncML client and the latter case
to match templates related to an input string.
SyncConfig API is also renamed (Server -> Peer) because both server/client
configuration/template are handled.
The original configuration template (Funambol and ScheduleWorld) has been moved
to the new template structure (under servers), they also have a .template.ini
file added so that they can be matched and picked up. All templates for
supported servers still have built-in template support in the code as before.
Templates for SyncEvolution based server is also added.
Server side templates are added (Nokia default, Nokia_7210c and SyncEvolutionServer).
Add unit test for the new template match use case.
2010-01-19 08:01:05 +01:00
}
2010-05-03 17:47:18 +02:00
bool TemplateConfig : : isTemplateConfig ( ) const
Configuration templates matching: match templates based on metadata
Introduced TemplateConfig to abstracting the template configuration structure,
the template metadata used for matching is also parsed here.
The fields introduced in the metadata are:
PeerIsClient: identify whether this is a server side configuration or a client
side configuration.
Fingerprint: the matching string for this template, it is a comma separated string
with each string modeled as: "Manufacture_Model". The first substring is also
used as the name to identify this template so that user can select the template
by this name.
eg:
Nokia 7210c: Nokia_7210c
SyncEvolution server: SyncEvolutionServer, SyncEvolution
ScheduleWorld: ScheduleWorld,default
SyncEvolution client: SyncEvolutionClient, SyncEvolution
Description: this is a just a descriptive string not used for matching.
GetServerTemplates is changed to add another "devices" parameter to identify
it is asking for templates for a list of "devices". Each device is a tuple
<matchstring (devicename), matchMode (server/client/all)>.
TemplateList as the return type, which is a list of class TemplateDescription
so that we can also return enough information for corresponding templates. This
list is sorted by the 3-tuple <finger, rank, name>.
Add MatchServerTemplates method which will iterating all templates inside the
folder and match against the input parameter and finally return a sorted
list of matched templates.
The atcually fuzzy match algorithm is based on a LCS (added in the following
commit).
Cmdline interface is changed accordingly:
--template ? is changed to --template ?[string], so that user use the former
case to match all templates for a tradiontial SyncML client and the latter case
to match templates related to an input string.
SyncConfig API is also renamed (Server -> Peer) because both server/client
configuration/template are handled.
The original configuration template (Funambol and ScheduleWorld) has been moved
to the new template structure (under servers), they also have a .template.ini
file added so that they can be matched and picked up. All templates for
supported servers still have built-in template support in the code as before.
Templates for SyncEvolution based server is also added.
Server side templates are added (Nokia default, Nokia_7210c and SyncEvolutionServer).
Add unit test for the new template match use case.
2010-01-19 08:01:05 +01:00
{
2010-05-03 17:47:18 +02:00
return ! m_metaProps . empty ( ) ;
}
2009-10-02 17:23:53 +02:00
2010-05-03 17:47:18 +02:00
int TemplateConfig : : serverModeMatch ( SyncConfig : : MatchMode mode )
{
2011-05-18 16:22:34 +02:00
if ( mode ! = SyncConfig : : MATCH_FOR_SERVER_MODE & &
mode ! = SyncConfig : : MATCH_FOR_CLIENT_MODE ) {
// no need to read config, peerIsClient doesn't matter
// => fall back to BEST_MATCH directly
return BEST_MATCH ;
}
2018-01-16 17:17:34 +01:00
std : : shared_ptr < ConfigNode > configNode = m_template - > open ( " config.ini " ) ;
2010-05-03 17:47:18 +02:00
std : : string peerIsClient = configNode - > readProperty ( " peerIsClient " ) ;
2010-03-18 03:23:27 +01:00
Configuration templates matching: match templates based on metadata
Introduced TemplateConfig to abstracting the template configuration structure,
the template metadata used for matching is also parsed here.
The fields introduced in the metadata are:
PeerIsClient: identify whether this is a server side configuration or a client
side configuration.
Fingerprint: the matching string for this template, it is a comma separated string
with each string modeled as: "Manufacture_Model". The first substring is also
used as the name to identify this template so that user can select the template
by this name.
eg:
Nokia 7210c: Nokia_7210c
SyncEvolution server: SyncEvolutionServer, SyncEvolution
ScheduleWorld: ScheduleWorld,default
SyncEvolution client: SyncEvolutionClient, SyncEvolution
Description: this is a just a descriptive string not used for matching.
GetServerTemplates is changed to add another "devices" parameter to identify
it is asking for templates for a list of "devices". Each device is a tuple
<matchstring (devicename), matchMode (server/client/all)>.
TemplateList as the return type, which is a list of class TemplateDescription
so that we can also return enough information for corresponding templates. This
list is sorted by the 3-tuple <finger, rank, name>.
Add MatchServerTemplates method which will iterating all templates inside the
folder and match against the input parameter and finally return a sorted
list of matched templates.
The atcually fuzzy match algorithm is based on a LCS (added in the following
commit).
Cmdline interface is changed accordingly:
--template ? is changed to --template ?[string], so that user use the former
case to match all templates for a tradiontial SyncML client and the latter case
to match templates related to an input string.
SyncConfig API is also renamed (Server -> Peer) because both server/client
configuration/template are handled.
The original configuration template (Funambol and ScheduleWorld) has been moved
to the new template structure (under servers), they also have a .template.ini
file added so that they can be matched and picked up. All templates for
supported servers still have built-in template support in the code as before.
Templates for SyncEvolution based server is also added.
Server side templates are added (Nokia default, Nokia_7210c and SyncEvolutionServer).
Add unit test for the new template match use case.
2010-01-19 08:01:05 +01:00
//not a match if serverMode does not match
if ( ( peerIsClient . empty ( ) | | peerIsClient = = " 0 " ) & & mode = = SyncConfig : : MATCH_FOR_SERVER_MODE ) {
return NO_MATCH ;
}
if ( peerIsClient = = " 1 " & & mode = = SyncConfig : : MATCH_FOR_CLIENT_MODE ) {
return NO_MATCH ;
}
return BEST_MATCH ;
}
/**
2011-04-20 18:50:25 +02:00
* The matching is based on Least common string algorithm ,
2011-05-19 11:59:02 +02:00
* with space , hyphen and underscore being treated as equal .
Configuration templates matching: match templates based on metadata
Introduced TemplateConfig to abstracting the template configuration structure,
the template metadata used for matching is also parsed here.
The fields introduced in the metadata are:
PeerIsClient: identify whether this is a server side configuration or a client
side configuration.
Fingerprint: the matching string for this template, it is a comma separated string
with each string modeled as: "Manufacture_Model". The first substring is also
used as the name to identify this template so that user can select the template
by this name.
eg:
Nokia 7210c: Nokia_7210c
SyncEvolution server: SyncEvolutionServer, SyncEvolution
ScheduleWorld: ScheduleWorld,default
SyncEvolution client: SyncEvolutionClient, SyncEvolution
Description: this is a just a descriptive string not used for matching.
GetServerTemplates is changed to add another "devices" parameter to identify
it is asking for templates for a list of "devices". Each device is a tuple
<matchstring (devicename), matchMode (server/client/all)>.
TemplateList as the return type, which is a list of class TemplateDescription
so that we can also return enough information for corresponding templates. This
list is sorted by the 3-tuple <finger, rank, name>.
Add MatchServerTemplates method which will iterating all templates inside the
folder and match against the input parameter and finally return a sorted
list of matched templates.
The atcually fuzzy match algorithm is based on a LCS (added in the following
commit).
Cmdline interface is changed accordingly:
--template ? is changed to --template ?[string], so that user use the former
case to match all templates for a tradiontial SyncML client and the latter case
to match templates related to an input string.
SyncConfig API is also renamed (Server -> Peer) because both server/client
configuration/template are handled.
The original configuration template (Funambol and ScheduleWorld) has been moved
to the new template structure (under servers), they also have a .template.ini
file added so that they can be matched and picked up. All templates for
supported servers still have built-in template support in the code as before.
Templates for SyncEvolution based server is also added.
Server side templates are added (Nokia default, Nokia_7210c and SyncEvolutionServer).
Add unit test for the new template match use case.
2010-01-19 08:01:05 +01:00
* */
int TemplateConfig : : fingerprintMatch ( const string & fingerprint )
{
//if input "", match all
if ( fingerprint . empty ( ) ) {
return LEVEL3_MATCH ;
}
std : : string fingerprintProp = m_metaProps [ " fingerprint " ] ;
std : : vector < string > subfingerprints = unescapeJoinedString ( fingerprintProp , ' , ' ) ;
std : : string input = fingerprint ;
boost : : to_lower ( input ) ;
2011-04-20 18:50:25 +02:00
boost : : replace_all ( input , " " , " _ " ) ;
2011-05-19 11:59:02 +02:00
boost : : replace_all ( input , " - " , " _ " ) ;
Configuration templates matching: match templates based on metadata
Introduced TemplateConfig to abstracting the template configuration structure,
the template metadata used for matching is also parsed here.
The fields introduced in the metadata are:
PeerIsClient: identify whether this is a server side configuration or a client
side configuration.
Fingerprint: the matching string for this template, it is a comma separated string
with each string modeled as: "Manufacture_Model". The first substring is also
used as the name to identify this template so that user can select the template
by this name.
eg:
Nokia 7210c: Nokia_7210c
SyncEvolution server: SyncEvolutionServer, SyncEvolution
ScheduleWorld: ScheduleWorld,default
SyncEvolution client: SyncEvolutionClient, SyncEvolution
Description: this is a just a descriptive string not used for matching.
GetServerTemplates is changed to add another "devices" parameter to identify
it is asking for templates for a list of "devices". Each device is a tuple
<matchstring (devicename), matchMode (server/client/all)>.
TemplateList as the return type, which is a list of class TemplateDescription
so that we can also return enough information for corresponding templates. This
list is sorted by the 3-tuple <finger, rank, name>.
Add MatchServerTemplates method which will iterating all templates inside the
folder and match against the input parameter and finally return a sorted
list of matched templates.
The atcually fuzzy match algorithm is based on a LCS (added in the following
commit).
Cmdline interface is changed accordingly:
--template ? is changed to --template ?[string], so that user use the former
case to match all templates for a tradiontial SyncML client and the latter case
to match templates related to an input string.
SyncConfig API is also renamed (Server -> Peer) because both server/client
configuration/template are handled.
The original configuration template (Funambol and ScheduleWorld) has been moved
to the new template structure (under servers), they also have a .template.ini
file added so that they can be matched and picked up. All templates for
supported servers still have built-in template support in the code as before.
Templates for SyncEvolution based server is also added.
Server side templates are added (Nokia default, Nokia_7210c and SyncEvolutionServer).
Add unit test for the new template match use case.
2010-01-19 08:01:05 +01:00
//return the largest match value
int max = NO_MATCH ;
2018-01-16 10:58:04 +01:00
for ( std : : string sub : subfingerprints ) {
Configuration templates matching: match templates based on metadata
Introduced TemplateConfig to abstracting the template configuration structure,
the template metadata used for matching is also parsed here.
The fields introduced in the metadata are:
PeerIsClient: identify whether this is a server side configuration or a client
side configuration.
Fingerprint: the matching string for this template, it is a comma separated string
with each string modeled as: "Manufacture_Model". The first substring is also
used as the name to identify this template so that user can select the template
by this name.
eg:
Nokia 7210c: Nokia_7210c
SyncEvolution server: SyncEvolutionServer, SyncEvolution
ScheduleWorld: ScheduleWorld,default
SyncEvolution client: SyncEvolutionClient, SyncEvolution
Description: this is a just a descriptive string not used for matching.
GetServerTemplates is changed to add another "devices" parameter to identify
it is asking for templates for a list of "devices". Each device is a tuple
<matchstring (devicename), matchMode (server/client/all)>.
TemplateList as the return type, which is a list of class TemplateDescription
so that we can also return enough information for corresponding templates. This
list is sorted by the 3-tuple <finger, rank, name>.
Add MatchServerTemplates method which will iterating all templates inside the
folder and match against the input parameter and finally return a sorted
list of matched templates.
The atcually fuzzy match algorithm is based on a LCS (added in the following
commit).
Cmdline interface is changed accordingly:
--template ? is changed to --template ?[string], so that user use the former
case to match all templates for a tradiontial SyncML client and the latter case
to match templates related to an input string.
SyncConfig API is also renamed (Server -> Peer) because both server/client
configuration/template are handled.
The original configuration template (Funambol and ScheduleWorld) has been moved
to the new template structure (under servers), they also have a .template.ini
file added so that they can be matched and picked up. All templates for
supported servers still have built-in template support in the code as before.
Templates for SyncEvolution based server is also added.
Server side templates are added (Nokia default, Nokia_7210c and SyncEvolutionServer).
Add unit test for the new template match use case.
2010-01-19 08:01:05 +01:00
std : : vector < LCS : : Entry < char > > result ;
std : : string match = sub ;
boost : : to_lower ( match ) ;
2011-04-20 18:50:25 +02:00
boost : : replace_all ( match , " " , " _ " ) ;
2011-05-19 11:59:02 +02:00
boost : : replace_all ( match , " - " , " _ " ) ;
Configuration templates matching: match templates based on metadata
Introduced TemplateConfig to abstracting the template configuration structure,
the template metadata used for matching is also parsed here.
The fields introduced in the metadata are:
PeerIsClient: identify whether this is a server side configuration or a client
side configuration.
Fingerprint: the matching string for this template, it is a comma separated string
with each string modeled as: "Manufacture_Model". The first substring is also
used as the name to identify this template so that user can select the template
by this name.
eg:
Nokia 7210c: Nokia_7210c
SyncEvolution server: SyncEvolutionServer, SyncEvolution
ScheduleWorld: ScheduleWorld,default
SyncEvolution client: SyncEvolutionClient, SyncEvolution
Description: this is a just a descriptive string not used for matching.
GetServerTemplates is changed to add another "devices" parameter to identify
it is asking for templates for a list of "devices". Each device is a tuple
<matchstring (devicename), matchMode (server/client/all)>.
TemplateList as the return type, which is a list of class TemplateDescription
so that we can also return enough information for corresponding templates. This
list is sorted by the 3-tuple <finger, rank, name>.
Add MatchServerTemplates method which will iterating all templates inside the
folder and match against the input parameter and finally return a sorted
list of matched templates.
The atcually fuzzy match algorithm is based on a LCS (added in the following
commit).
Cmdline interface is changed accordingly:
--template ? is changed to --template ?[string], so that user use the former
case to match all templates for a tradiontial SyncML client and the latter case
to match templates related to an input string.
SyncConfig API is also renamed (Server -> Peer) because both server/client
configuration/template are handled.
The original configuration template (Funambol and ScheduleWorld) has been moved
to the new template structure (under servers), they also have a .template.ini
file added so that they can be matched and picked up. All templates for
supported servers still have built-in template support in the code as before.
Templates for SyncEvolution based server is also added.
Server side templates are added (Nokia default, Nokia_7210c and SyncEvolutionServer).
Add unit test for the new template match use case.
2010-01-19 08:01:05 +01:00
LCS : : lcs ( match , input , std : : back_inserter ( result ) , LCS : : accessor_sequence < std : : string > ( ) ) ;
int score = result . size ( ) * 2 * BEST_MATCH / ( sub . size ( ) + fingerprint . size ( ) ) ;
if ( score > max ) {
max = score ;
}
}
return max ;
}
int TemplateConfig : : metaMatch ( const std : : string & fingerprint , SyncConfig : : MatchMode mode )
{
int serverMatch = serverModeMatch ( mode ) ;
if ( serverMatch = = NO_MATCH ) {
return NO_MATCH ;
}
int fMatch = fingerprintMatch ( fingerprint ) ;
return ( serverMatch * 1 + fMatch * 3 ) > > 2 ;
}
string TemplateConfig : : getDescription ( ) {
return m_metaProps [ " description " ] ;
}
string TemplateConfig : : getFingerprint ( ) {
return m_metaProps [ " fingerprint " ] ;
}
2010-03-25 04:26:13 +01:00
string TemplateConfig : : getTemplateName ( ) {
return m_metaProps [ " templateName " ] ;
}
/*
* A unique identifier for this template , it must be unique and retrieveable .
2011-04-20 18:15:07 +02:00
* We use the first entry in the " fingerprint " property for cmdline and
* replace spaces with underscores , to make it more command line friendly .
2010-03-25 04:26:13 +01:00
* */
string TemplateConfig : : getTemplateId ( ) {
if ( m_id . empty ( ) ) {
Configuration templates matching: match templates based on metadata
Introduced TemplateConfig to abstracting the template configuration structure,
the template metadata used for matching is also parsed here.
The fields introduced in the metadata are:
PeerIsClient: identify whether this is a server side configuration or a client
side configuration.
Fingerprint: the matching string for this template, it is a comma separated string
with each string modeled as: "Manufacture_Model". The first substring is also
used as the name to identify this template so that user can select the template
by this name.
eg:
Nokia 7210c: Nokia_7210c
SyncEvolution server: SyncEvolutionServer, SyncEvolution
ScheduleWorld: ScheduleWorld,default
SyncEvolution client: SyncEvolutionClient, SyncEvolution
Description: this is a just a descriptive string not used for matching.
GetServerTemplates is changed to add another "devices" parameter to identify
it is asking for templates for a list of "devices". Each device is a tuple
<matchstring (devicename), matchMode (server/client/all)>.
TemplateList as the return type, which is a list of class TemplateDescription
so that we can also return enough information for corresponding templates. This
list is sorted by the 3-tuple <finger, rank, name>.
Add MatchServerTemplates method which will iterating all templates inside the
folder and match against the input parameter and finally return a sorted
list of matched templates.
The atcually fuzzy match algorithm is based on a LCS (added in the following
commit).
Cmdline interface is changed accordingly:
--template ? is changed to --template ?[string], so that user use the former
case to match all templates for a tradiontial SyncML client and the latter case
to match templates related to an input string.
SyncConfig API is also renamed (Server -> Peer) because both server/client
configuration/template are handled.
The original configuration template (Funambol and ScheduleWorld) has been moved
to the new template structure (under servers), they also have a .template.ini
file added so that they can be matched and picked up. All templates for
supported servers still have built-in template support in the code as before.
Templates for SyncEvolution based server is also added.
Server side templates are added (Nokia default, Nokia_7210c and SyncEvolutionServer).
Add unit test for the new template match use case.
2010-01-19 08:01:05 +01:00
std : : string fingerprintProp = m_metaProps [ " fingerprint " ] ;
if ( ! fingerprintProp . empty ( ) ) {
std : : vector < std : : string > subfingerprints = unescapeJoinedString ( fingerprintProp , ' , ' ) ;
2010-03-25 04:26:13 +01:00
m_id = subfingerprints [ 0 ] ;
Configuration templates matching: match templates based on metadata
Introduced TemplateConfig to abstracting the template configuration structure,
the template metadata used for matching is also parsed here.
The fields introduced in the metadata are:
PeerIsClient: identify whether this is a server side configuration or a client
side configuration.
Fingerprint: the matching string for this template, it is a comma separated string
with each string modeled as: "Manufacture_Model". The first substring is also
used as the name to identify this template so that user can select the template
by this name.
eg:
Nokia 7210c: Nokia_7210c
SyncEvolution server: SyncEvolutionServer, SyncEvolution
ScheduleWorld: ScheduleWorld,default
SyncEvolution client: SyncEvolutionClient, SyncEvolution
Description: this is a just a descriptive string not used for matching.
GetServerTemplates is changed to add another "devices" parameter to identify
it is asking for templates for a list of "devices". Each device is a tuple
<matchstring (devicename), matchMode (server/client/all)>.
TemplateList as the return type, which is a list of class TemplateDescription
so that we can also return enough information for corresponding templates. This
list is sorted by the 3-tuple <finger, rank, name>.
Add MatchServerTemplates method which will iterating all templates inside the
folder and match against the input parameter and finally return a sorted
list of matched templates.
The atcually fuzzy match algorithm is based on a LCS (added in the following
commit).
Cmdline interface is changed accordingly:
--template ? is changed to --template ?[string], so that user use the former
case to match all templates for a tradiontial SyncML client and the latter case
to match templates related to an input string.
SyncConfig API is also renamed (Server -> Peer) because both server/client
configuration/template are handled.
The original configuration template (Funambol and ScheduleWorld) has been moved
to the new template structure (under servers), they also have a .template.ini
file added so that they can be matched and picked up. All templates for
supported servers still have built-in template support in the code as before.
Templates for SyncEvolution based server is also added.
Server side templates are added (Nokia default, Nokia_7210c and SyncEvolutionServer).
Add unit test for the new template match use case.
2010-01-19 08:01:05 +01:00
}
2011-04-20 18:15:07 +02:00
boost : : replace_all ( m_id , " " , " _ " ) ;
Configuration templates matching: match templates based on metadata
Introduced TemplateConfig to abstracting the template configuration structure,
the template metadata used for matching is also parsed here.
The fields introduced in the metadata are:
PeerIsClient: identify whether this is a server side configuration or a client
side configuration.
Fingerprint: the matching string for this template, it is a comma separated string
with each string modeled as: "Manufacture_Model". The first substring is also
used as the name to identify this template so that user can select the template
by this name.
eg:
Nokia 7210c: Nokia_7210c
SyncEvolution server: SyncEvolutionServer, SyncEvolution
ScheduleWorld: ScheduleWorld,default
SyncEvolution client: SyncEvolutionClient, SyncEvolution
Description: this is a just a descriptive string not used for matching.
GetServerTemplates is changed to add another "devices" parameter to identify
it is asking for templates for a list of "devices". Each device is a tuple
<matchstring (devicename), matchMode (server/client/all)>.
TemplateList as the return type, which is a list of class TemplateDescription
so that we can also return enough information for corresponding templates. This
list is sorted by the 3-tuple <finger, rank, name>.
Add MatchServerTemplates method which will iterating all templates inside the
folder and match against the input parameter and finally return a sorted
list of matched templates.
The atcually fuzzy match algorithm is based on a LCS (added in the following
commit).
Cmdline interface is changed accordingly:
--template ? is changed to --template ?[string], so that user use the former
case to match all templates for a tradiontial SyncML client and the latter case
to match templates related to an input string.
SyncConfig API is also renamed (Server -> Peer) because both server/client
configuration/template are handled.
The original configuration template (Funambol and ScheduleWorld) has been moved
to the new template structure (under servers), they also have a .template.ini
file added so that they can be matched and picked up. All templates for
supported servers still have built-in template support in the code as before.
Templates for SyncEvolution based server is also added.
Server side templates are added (Nokia default, Nokia_7210c and SyncEvolutionServer).
Add unit test for the new template match use case.
2010-01-19 08:01:05 +01:00
}
2010-03-25 04:26:13 +01:00
return m_id ;
Configuration templates matching: match templates based on metadata
Introduced TemplateConfig to abstracting the template configuration structure,
the template metadata used for matching is also parsed here.
The fields introduced in the metadata are:
PeerIsClient: identify whether this is a server side configuration or a client
side configuration.
Fingerprint: the matching string for this template, it is a comma separated string
with each string modeled as: "Manufacture_Model". The first substring is also
used as the name to identify this template so that user can select the template
by this name.
eg:
Nokia 7210c: Nokia_7210c
SyncEvolution server: SyncEvolutionServer, SyncEvolution
ScheduleWorld: ScheduleWorld,default
SyncEvolution client: SyncEvolutionClient, SyncEvolution
Description: this is a just a descriptive string not used for matching.
GetServerTemplates is changed to add another "devices" parameter to identify
it is asking for templates for a list of "devices". Each device is a tuple
<matchstring (devicename), matchMode (server/client/all)>.
TemplateList as the return type, which is a list of class TemplateDescription
so that we can also return enough information for corresponding templates. This
list is sorted by the 3-tuple <finger, rank, name>.
Add MatchServerTemplates method which will iterating all templates inside the
folder and match against the input parameter and finally return a sorted
list of matched templates.
The atcually fuzzy match algorithm is based on a LCS (added in the following
commit).
Cmdline interface is changed accordingly:
--template ? is changed to --template ?[string], so that user use the former
case to match all templates for a tradiontial SyncML client and the latter case
to match templates related to an input string.
SyncConfig API is also renamed (Server -> Peer) because both server/client
configuration/template are handled.
The original configuration template (Funambol and ScheduleWorld) has been moved
to the new template structure (under servers), they also have a .template.ini
file added so that they can be matched and picked up. All templates for
supported servers still have built-in template support in the code as before.
Templates for SyncEvolution based server is also added.
Server side templates are added (Nokia default, Nokia_7210c and SyncEvolutionServer).
Add unit test for the new template match use case.
2010-01-19 08:01:05 +01:00
}
2010-01-13 19:12:40 +01:00
2010-03-22 17:45:03 +01:00
bool SecondsConfigProperty : : checkValue ( const string & value , string & error ) const
{
unsigned int seconds ;
return parseDuration ( value , error , seconds ) ;
}
2011-11-21 16:37:53 +01:00
InitState < unsigned int > SecondsConfigProperty : : getPropertyValue ( const ConfigNode & node ) const
2010-03-22 17:45:03 +01:00
{
configuration: added possibility to define property name aliases
The goal is to allow multiple names for properties. This will be used
to replace legacy names like "evolutionsource", but it could also be
used to allow abbreviations on the command line.
First the patch replaces the single ConfigProperty::m_name with a list
of names, of which the first one is the current name of the
property.
The name that is to be used depends on the node which is to be
manipulated: if it already has a property under an alias, that alias
is read and also written, so existing configuration continue to use
the old config name (avoids the problem of having to remove the old
name and insert the new one at the same spot in a .ini file). Old
configs continue to parse okay. Writing into node which has none of
the names set, as in migrating into a fresh config, uses the new
names.
Most of the patch deals with the removal of a single, unique name,
either by picking the name so that it matches a node, using the
default name or simply hard-coding a property name ("sync").
The command line accepts all aliases, then uses the main name for
overriding configuration options.
2011-01-18 15:18:21 +01:00
string name = getName ( node ) ;
2011-11-21 16:37:53 +01:00
bool wasSet ;
std : : string value = node . readProperty ( name ) ;
2010-03-22 17:45:03 +01:00
if ( value . empty ( ) ) {
2011-11-21 16:37:53 +01:00
wasSet = false ;
2010-03-22 17:45:03 +01:00
value = getDefValue ( ) ;
2011-11-21 16:37:53 +01:00
} else {
wasSet = true ;
2010-03-22 17:45:03 +01:00
}
string error ;
unsigned int seconds ;
if ( ! parseDuration ( value , error , seconds ) ) {
throwValueError ( node , name , value , error ) ;
}
2011-11-21 16:37:53 +01:00
return InitState < unsigned int > ( seconds , wasSet ) ;
2010-03-22 17:45:03 +01:00
}
bool SecondsConfigProperty : : parseDuration ( const string & value , string & error , unsigned int & seconds )
{
seconds = 0 ;
if ( value . empty ( ) ) {
// ambiguous - zero seconds?!
error = " duration expected, empty string not valid " ;
return false ;
}
unsigned int current = 0 ;
2010-03-31 20:51:34 +02:00
bool haveDigit = false ;
2018-01-16 10:58:04 +01:00
for ( char c : value ) {
2010-03-22 17:45:03 +01:00
if ( isdigit ( c ) ) {
current = current * 10 + ( c - ' 0 ' ) ;
2010-03-31 20:51:34 +02:00
haveDigit = true ;
2010-03-22 17:45:03 +01:00
} else {
unsigned int multiplier = 1 ;
switch ( toupper ( c ) ) {
case ' Y ' :
multiplier = 365 * 24 * 60 * 60 ;
break ;
case ' D ' :
multiplier = 24 * 60 * 60 ;
break ;
case ' H ' :
multiplier = 60 * 60 ;
break ;
case ' M ' :
multiplier = 60 ;
break ;
case ' S ' :
break ;
case ' ' :
case ' \t ' :
continue ;
case ' + ' :
break ;
default :
error = StringPrintf ( " invalid character '%c' " , c ) ;
return false ;
}
2010-04-15 16:50:13 +02:00
if ( ! haveDigit & & c ! = ' + ' ) {
2010-03-31 20:51:34 +02:00
error = StringPrintf ( " unit character without preceeding number: %c " , c ) ;
return false ;
}
2010-03-22 17:45:03 +01:00
seconds + = current * multiplier ;
current = 0 ;
2010-03-31 20:51:34 +02:00
haveDigit = false ;
2010-03-22 17:45:03 +01:00
}
}
seconds + = current ;
return true ;
}
2010-01-13 19:12:40 +01:00
# ifdef ENABLE_UNIT_TESTS
class SyncConfigTest : public CppUnit : : TestFixture {
CPPUNIT_TEST_SUITE ( SyncConfigTest ) ;
CPPUNIT_TEST ( normalize ) ;
2010-03-22 17:45:03 +01:00
CPPUNIT_TEST ( parseDuration ) ;
2011-01-25 11:11:53 +01:00
CPPUNIT_TEST ( propertySpec ) ;
2010-01-13 19:12:40 +01:00
CPPUNIT_TEST_SUITE_END ( ) ;
private :
void normalize ( )
{
2011-01-25 11:11:53 +01:00
// use same dir as CmdlineTest...
ScopedEnvChange xdg ( " XDG_CONFIG_HOME " , " CmdlineTest " ) ;
ScopedEnvChange home ( " HOME " , " CmdlineTest " ) ;
rm_r ( " CmdlineTest " ) ;
2010-01-29 20:45:27 +01:00
2010-01-13 19:12:40 +01:00
CPPUNIT_ASSERT_EQUAL ( std : : string ( " @default " ) ,
SyncConfig : : normalizeConfigString ( " " ) ) ;
CPPUNIT_ASSERT_EQUAL ( std : : string ( " @default " ) ,
SyncConfig : : normalizeConfigString ( " @default " ) ) ;
CPPUNIT_ASSERT_EQUAL ( std : : string ( " @default " ) ,
SyncConfig : : normalizeConfigString ( " @DeFaULT " ) ) ;
CPPUNIT_ASSERT_EQUAL ( std : : string ( " foobar " ) ,
SyncConfig : : normalizeConfigString ( " FooBar " ) ) ;
CPPUNIT_ASSERT_EQUAL ( std : : string ( " foobar@something " ) ,
SyncConfig : : normalizeConfigString ( " FooBar@Something " ) ) ;
CPPUNIT_ASSERT_EQUAL ( std : : string ( " foo_bar_x_y_z " ) ,
SyncConfig : : normalizeConfigString ( " Foo/bar \\ x:y:z " ) ) ;
2011-01-25 11:11:53 +01:00
// keep @default if explicitly requested
CPPUNIT_ASSERT_EQUAL ( std : : string ( " foobar@default " ) ,
2011-03-02 11:20:27 +01:00
SyncConfig : : normalizeConfigString ( " FooBar " , SyncConfig : : NORMALIZE_LONG_FORMAT ) ) ;
2011-01-25 11:11:53 +01:00
2013-09-23 21:56:21 +02:00
// Test config lookup. We expect all of these to exist on disk, so
// set some property. Empty configs do not get written to disk.
// This allows testing for existance.
2011-01-25 11:11:53 +01:00
SyncConfig foo_default ( " foo " ) , foo_other ( " foo@other " ) , bar ( " bar@other " ) ;
2013-09-23 21:56:21 +02:00
foo_default . setLogLevel ( 10 ) ;
foo_other . setLogLevel ( 10 ) ;
bar . setLogLevel ( 10 ) ;
2011-01-25 11:11:53 +01:00
foo_default . flush ( ) ;
foo_other . flush ( ) ;
bar . flush ( ) ;
CPPUNIT_ASSERT_EQUAL ( std : : string ( " foo " ) ,
SyncConfig : : normalizeConfigString ( " foo " ) ) ;
CPPUNIT_ASSERT_EQUAL ( std : : string ( " foo " ) ,
SyncConfig : : normalizeConfigString ( " foo@default " ) ) ;
CPPUNIT_ASSERT_EQUAL ( std : : string ( " foo@default " ) ,
2011-03-02 11:20:27 +01:00
SyncConfig : : normalizeConfigString ( " foo " , SyncConfig : : NORMALIZE_LONG_FORMAT ) ) ;
2011-01-25 11:11:53 +01:00
CPPUNIT_ASSERT_EQUAL ( std : : string ( " foo@default " ) ,
2011-03-02 11:20:27 +01:00
SyncConfig : : normalizeConfigString ( " foo@default " , SyncConfig : : NORMALIZE_LONG_FORMAT ) ) ;
2011-01-25 11:11:53 +01:00
CPPUNIT_ASSERT_EQUAL ( std : : string ( " foo@other " ) ,
SyncConfig : : normalizeConfigString ( " foo@other " ) ) ;
foo_default . remove ( ) ;
CPPUNIT_ASSERT_EQUAL ( std : : string ( " foo@other " ) ,
SyncConfig : : normalizeConfigString ( " foo " ) ) ;
CPPUNIT_ASSERT_EQUAL ( std : : string ( " foo@other " ) ,
2011-03-02 11:20:27 +01:00
SyncConfig : : normalizeConfigString ( " foo " , SyncConfig : : NORMALIZE_LONG_FORMAT ) ) ;
2010-01-13 19:12:40 +01:00
}
2010-03-22 17:45:03 +01:00
void parseDuration ( )
{
string error ;
unsigned int seconds ;
unsigned int expected ;
CPPUNIT_ASSERT ( ! SecondsConfigProperty : : parseDuration ( " foo " , error , seconds ) ) ;
CPPUNIT_ASSERT_EQUAL ( error , string ( " invalid character 'f' " ) ) ;
CPPUNIT_ASSERT ( ! SecondsConfigProperty : : parseDuration ( " 1g " , error , seconds ) ) ;
CPPUNIT_ASSERT_EQUAL ( error , string ( " invalid character 'g' " ) ) ;
CPPUNIT_ASSERT ( ! SecondsConfigProperty : : parseDuration ( " " , error , seconds ) ) ;
CPPUNIT_ASSERT_EQUAL ( error , string ( " duration expected, empty string not valid " ) ) ;
expected = 5 ;
CPPUNIT_ASSERT ( SecondsConfigProperty : : parseDuration ( " 5 " , error , seconds ) ) ;
CPPUNIT_ASSERT_EQUAL ( expected , seconds ) ;
CPPUNIT_ASSERT ( SecondsConfigProperty : : parseDuration ( " 05 " , error , seconds ) ) ;
CPPUNIT_ASSERT_EQUAL ( expected , seconds ) ;
CPPUNIT_ASSERT ( SecondsConfigProperty : : parseDuration ( " 05s " , error , seconds ) ) ;
CPPUNIT_ASSERT_EQUAL ( expected , seconds ) ;
CPPUNIT_ASSERT ( SecondsConfigProperty : : parseDuration ( " 5s " , error , seconds ) ) ;
CPPUNIT_ASSERT_EQUAL ( expected , seconds ) ;
expected = ( ( ( 1 * 365 + 2 ) * 24 + 3 ) * 60 + 4 ) * 60 + 5 ;
CPPUNIT_ASSERT ( SecondsConfigProperty : : parseDuration ( " 1y2d3H4M5s " , error , seconds ) ) ;
CPPUNIT_ASSERT_EQUAL ( expected , seconds ) ;
CPPUNIT_ASSERT ( SecondsConfigProperty : : parseDuration ( " 5 + 1y+2d + 3 H4M " , error , seconds ) ) ;
CPPUNIT_ASSERT_EQUAL ( expected , seconds ) ;
2010-04-15 16:50:13 +02:00
CPPUNIT_ASSERT ( ! SecondsConfigProperty : : parseDuration ( " m " , error , seconds ) ) ;
2010-03-22 17:45:03 +01:00
}
2011-01-25 11:11:53 +01:00
void propertySpec ( )
{
ScopedEnvChange xdg ( " XDG_CONFIG_HOME " , " /dev/null " ) ;
ScopedEnvChange home ( " HOME " , " /dev/null " ) ;
PropertySpecifier spec ;
spec = PropertySpecifier : : StringToPropSpec ( " foo " ) ;
CPPUNIT_ASSERT_EQUAL ( string ( " " ) , spec . m_source ) ;
CPPUNIT_ASSERT_EQUAL ( string ( " foo " ) , spec . m_property ) ;
CPPUNIT_ASSERT_EQUAL ( string ( " " ) , spec . m_config ) ;
CPPUNIT_ASSERT_EQUAL ( string ( " foo " ) , spec . toString ( ) ) ;
spec = PropertySpecifier : : StringToPropSpec ( " source/foo@ContEXT " ) ;
CPPUNIT_ASSERT_EQUAL ( string ( " source " ) , spec . m_source ) ;
CPPUNIT_ASSERT_EQUAL ( string ( " foo " ) , spec . m_property ) ;
CPPUNIT_ASSERT_EQUAL ( string ( " @context " ) , spec . m_config ) ;
CPPUNIT_ASSERT_EQUAL ( string ( " source/foo@context " ) , spec . toString ( ) ) ;
spec = PropertySpecifier : : StringToPropSpec ( " source/foo@ContEXT " , PropertySpecifier : : NO_NORMALIZATION ) ;
CPPUNIT_ASSERT_EQUAL ( string ( " source " ) , spec . m_source ) ;
CPPUNIT_ASSERT_EQUAL ( string ( " foo " ) , spec . m_property ) ;
CPPUNIT_ASSERT_EQUAL ( string ( " @ContEXT " ) , spec . m_config ) ;
CPPUNIT_ASSERT_EQUAL ( string ( " source/foo@ContEXT " ) , spec . toString ( ) ) ;
spec = PropertySpecifier : : StringToPropSpec ( " foo@peer@context " ) ;
CPPUNIT_ASSERT_EQUAL ( string ( " " ) , spec . m_source ) ;
CPPUNIT_ASSERT_EQUAL ( string ( " foo " ) , spec . m_property ) ;
CPPUNIT_ASSERT_EQUAL ( string ( " peer@context " ) , spec . m_config ) ;
CPPUNIT_ASSERT_EQUAL ( string ( " foo@peer@context " ) , spec . toString ( ) ) ;
spec = PropertySpecifier : : StringToPropSpec ( " foo@context " ) ;
CPPUNIT_ASSERT_EQUAL ( string ( " " ) , spec . m_source ) ;
CPPUNIT_ASSERT_EQUAL ( string ( " foo " ) , spec . m_property ) ;
CPPUNIT_ASSERT_EQUAL ( string ( " @context " ) , spec . m_config ) ;
CPPUNIT_ASSERT_EQUAL ( string ( " foo@context " ) , spec . toString ( ) ) ;
spec = PropertySpecifier : : StringToPropSpec ( " source/foo " ) ;
CPPUNIT_ASSERT_EQUAL ( string ( " source " ) , spec . m_source ) ;
CPPUNIT_ASSERT_EQUAL ( string ( " foo " ) , spec . m_property ) ;
CPPUNIT_ASSERT_EQUAL ( string ( " " ) , spec . m_config ) ;
CPPUNIT_ASSERT_EQUAL ( string ( " source/foo " ) , spec . toString ( ) ) ;
spec = PropertySpecifier : : StringToPropSpec ( " " ) ;
CPPUNIT_ASSERT_EQUAL ( string ( " " ) , spec . m_source ) ;
CPPUNIT_ASSERT_EQUAL ( string ( " " ) , spec . m_property ) ;
CPPUNIT_ASSERT_EQUAL ( string ( " " ) , spec . m_config ) ;
CPPUNIT_ASSERT_EQUAL ( string ( " " ) , spec . toString ( ) ) ;
}
2010-01-13 19:12:40 +01:00
} ;
SYNCEVOLUTION_TEST_SUITE_REGISTRATION ( SyncConfigTest ) ;
# endif // ENABLE_UNIT_TESTS
2009-10-02 17:23:53 +02:00
SE_END_CXX