00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef INCL_SYNC_EVOLUTION_CONFIG
00020 # define INCL_SYNC_EVOLUTION_CONFIG
00021
00022 #include "FilterConfigNode.h"
00023
00024 #include "spds/AbstractSyncConfig.h"
00025 #include "spds/AbstractSyncSourceConfig.h"
00026 #include <boost/shared_ptr.hpp>
00027 #include <boost/algorithm/string/predicate.hpp>
00028 #include <boost/algorithm/string/trim.hpp>
00029 #include <boost/foreach.hpp>
00030 #include <list>
00031 #include <string>
00032 #include <sstream>
00033 #include <set>
00034 using namespace std;
00035
00036
00037
00038
00039
00040
00041 class EvolutionSyncSourceConfig;
00042 class PersistentEvolutionSyncSourceConfig;
00043 class ConfigTree;
00044 struct SyncSourceNodes;
00045 struct ConstSyncSourceNodes;
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 class ConfigProperty {
00061 public:
00062 ConfigProperty(const string &name, const string &comment, const string &def = string("")) :
00063 m_obligatory(false),
00064 m_hidden(false),
00065 m_name(name),
00066 m_comment(boost::trim_right_copy(comment)),
00067 m_defValue(def)
00068 {}
00069 virtual ~ConfigProperty() {}
00070
00071 virtual string getName() const { return m_name; }
00072 virtual string getComment() const { return m_comment; }
00073 virtual string getDefValue() const { return m_defValue; }
00074
00075
00076
00077
00078
00079
00080
00081 virtual bool checkValue(const string &value, string &error) const { return true; }
00082
00083
00084 static void splitComment(const string &comment, list<string> &commentLines);
00085
00086 bool isHidden() const { return m_hidden; }
00087 void setHidden(bool hidden) { m_hidden = hidden; }
00088
00089 bool isObligatory() const { return m_obligatory; }
00090 void setObligatory(bool obligatory) { m_obligatory = obligatory; }
00091
00092
00093 void setProperty(ConfigNode &node, const string &value) const { node.setProperty(getName(), value, getComment()); }
00094 void setProperty(FilterConfigNode &node, const string &value, bool temporarily = false) const {
00095 if (temporarily) {
00096 node.addFilter(m_name, value);
00097 } else {
00098 node.setProperty(m_name, value, getComment());
00099 }
00100 }
00101
00102
00103 void setDefaultProperty(ConfigNode &node, bool force) const {
00104 string defValue = getDefValue();
00105 node.setProperty(m_name, defValue, getComment(), force ? NULL : &defValue);
00106 }
00107
00108
00109
00110
00111
00112 virtual string getProperty(const ConfigNode &node, bool *isDefault = NULL) const {
00113 string name = getName();
00114 string value = node.readProperty(name);
00115 if (value.size()) {
00116 string error;
00117 if (!checkValue(value, error)) {
00118 throwValueError(node, name, value, error);
00119 }
00120 if (isDefault) {
00121 *isDefault = false;
00122 }
00123 return value;
00124 } else {
00125 if (isDefault) {
00126 *isDefault = true;
00127 }
00128 return getDefValue();
00129 }
00130 }
00131
00132 protected:
00133 void throwValueError(const ConfigNode &node, const string &name, const string &value, const string &error) const;
00134
00135 private:
00136 bool m_obligatory;
00137 bool m_hidden;
00138 const string m_name, m_comment, m_defValue;
00139 };
00140
00141 template<class T> class InitList : public list<T> {
00142 public:
00143 InitList() {}
00144 InitList(const T &initialValue) {
00145 push_back(initialValue);
00146 }
00147 InitList &operator + (const T &rhs) {
00148 push_back(rhs);
00149 return *this;
00150 }
00151 InitList &operator += (const T &rhs) {
00152 push_back(rhs);
00153 return *this;
00154 }
00155 };
00156 typedef InitList<string> Aliases;
00157 typedef InitList<Aliases> Values;
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169 class StringConfigProperty : public ConfigProperty {
00170 public:
00171 StringConfigProperty(const string &name, const string &comment,
00172 const string &def = string(""),
00173 const Values &values = Values()) :
00174 ConfigProperty(name, comment, def),
00175 m_values(values)
00176 {}
00177
00178
00179
00180
00181 bool normalizeValue(string &res) const {
00182 Values values = getValues();
00183 BOOST_FOREACH(const Values::value_type &value, values) {
00184 BOOST_FOREACH(const string &alias, value) {
00185 if (boost::iequals(res, alias)) {
00186 res = *value.begin();
00187 return true;
00188 }
00189 }
00190 }
00191 return values.empty();
00192 }
00193
00194
00195
00196
00197
00198 virtual bool checkValue(const string &propValue, string &error) const {
00199 Values values = getValues();
00200 if (values.empty()) {
00201 return true;
00202 }
00203
00204 ostringstream err;
00205 err << "not one of the valid values (";
00206 bool firstval = true;
00207 BOOST_FOREACH(const Values::value_type &value, values) {
00208 if (!firstval) {
00209 err << ", ";
00210 } else {
00211 firstval = false;
00212 }
00213 bool firstalias = true;
00214 BOOST_FOREACH(const string &alias, value) {
00215 if (!firstalias) {
00216 err << " = ";
00217 } else {
00218 firstalias = false;
00219 }
00220 if (alias.empty()) {
00221 err << "\"\"";
00222 } else {
00223 err << alias;
00224 }
00225
00226 if (boost::iequals(propValue, alias)) {
00227 return true;
00228 }
00229 }
00230 }
00231 err << ")";
00232 error = err.str();
00233 return false;
00234 }
00235
00236 virtual string getProperty(const ConfigNode &node, bool *isDefault = NULL) const {
00237 string res = ConfigProperty::getProperty(node, isDefault);
00238 normalizeValue(res);
00239 return res;
00240 }
00241
00242 protected:
00243 virtual Values getValues() const { return m_values; }
00244
00245 private:
00246 const Values m_values;
00247 };
00248
00249
00250
00251
00252
00253
00254 template<class T> class TypedConfigProperty : public ConfigProperty {
00255 public:
00256 TypedConfigProperty(const string &name, const string &comment, const string &defValue = string("0")) :
00257 ConfigProperty(name, comment, defValue)
00258 {}
00259
00260
00261
00262
00263
00264 virtual bool checkValue(const string &value, string &error) const {
00265 istringstream in(value);
00266 T res;
00267 if (in >> res) {
00268 return true;
00269 } else {
00270 error = "cannot parse value";
00271 return false;
00272 }
00273 }
00274
00275 void setProperty(ConfigNode &node, const T &value) const {
00276 ostringstream out;
00277
00278 out << value;
00279 node.setProperty(getName(), out.str(), getComment());
00280 }
00281 void setProperty(FilterConfigNode &node, const T &value, bool temporarily = false) const {
00282 ostringstream out;
00283
00284 out << value;
00285 if (temporarily) {
00286 node.addFilter(getName(), out.str());
00287 } else {
00288 node.setProperty(getName(), out.str(), getComment());
00289 }
00290 }
00291
00292 T getProperty(ConfigNode &node, bool *isDefault = NULL) {
00293 string name = getName();
00294 string value = node.readProperty(name);
00295 istringstream in(value);
00296 T res;
00297 if (value.empty()) {
00298 istringstream defStream(getDefValue());
00299 defStream >> res;
00300 if (isDefault) {
00301 *isDefault = true;
00302 }
00303 return res;
00304 } else {
00305 if (!(in >> res)) {
00306 throwValueError(node, name, value, "cannot parse value");
00307 }
00308 if (isDefault) {
00309 *isDefault = false;
00310 }
00311 return res;
00312 }
00313 }
00314 };
00315
00316 typedef TypedConfigProperty<int> IntConfigProperty;
00317 typedef TypedConfigProperty<unsigned int> UIntConfigProperty;
00318 typedef TypedConfigProperty<long> LongConfigProperty;
00319 typedef TypedConfigProperty<unsigned long> ULongConfigProperty;
00320
00321
00322
00323
00324
00325 class ConfigUserInterface {
00326 public:
00327 virtual ~ConfigUserInterface() {}
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339 virtual string askPassword(const string &descr) = 0;
00340 };
00341
00342 class PasswordConfigProperty : public ConfigProperty {
00343 public:
00344 PasswordConfigProperty(const string &name, const string &comment, const string &def = string("")) :
00345 ConfigProperty(name, comment, def)
00346 {}
00347
00348
00349
00350
00351 virtual void checkPassword(ConfigNode &node,
00352 ConfigUserInterface &ui,
00353 const string &descr,
00354 string &cachedPassword);
00355
00356
00357
00358
00359 virtual string getCachedProperty(ConfigNode &node,
00360 const string &cachedPassword);
00361 };
00362
00363
00364
00365
00366
00367 class BoolConfigProperty : public StringConfigProperty {
00368 public:
00369 BoolConfigProperty(const string &name, const string &comment, const string &defValue = string("F")) :
00370 StringConfigProperty(name, comment, defValue,
00371 Values() + (Aliases("1") + "T" + "TRUE") + (Aliases("0") + "F" + "FALSE"))
00372 {}
00373
00374 void setProperty(ConfigNode &node, bool value) {
00375 StringConfigProperty::setProperty(node, value ? "1" : "0");
00376 }
00377 void setProperty(FilterConfigNode &node, bool value, bool temporarily = false) {
00378 StringConfigProperty::setProperty(node, value ? "1" : "0", temporarily);
00379 }
00380 int getProperty(ConfigNode &node, bool *isDefault = NULL) {
00381 string res = ConfigProperty::getProperty(node, isDefault);
00382
00383 return boost::iequals(res, "T") ||
00384 boost::iequals(res, "TRUE") ||
00385 atoi(res.c_str()) != 0;
00386 }
00387 };
00388
00389
00390
00391
00392
00393 class ConfigPropertyRegistry : public list<const ConfigProperty *> {
00394 public:
00395
00396 const ConfigProperty *find(const string &propName) const {
00397 BOOST_FOREACH(const ConfigProperty *prop, *this) {
00398 if (boost::iequals(prop->getName(), propName)) {
00399 return prop;
00400 }
00401 }
00402 return NULL;
00403 }
00404 };
00405
00406
00407
00408
00409
00410
00411 class ConfigStringCache {
00412 public:
00413 const char *getProperty(const ConfigNode &node, const ConfigProperty &prop) {
00414 string value = prop.getProperty(node);
00415 return storeString(prop.getName(), value);
00416 }
00417
00418 const char *storeString(const string &key, const string &value) {
00419 const string &entry = m_cache[key] = value;
00420 return entry.c_str();
00421 }
00422
00423 private:
00424 map<string, string> m_cache;
00425 };
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464 class EvolutionSyncConfig : public AbstractSyncConfig {
00465 public:
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477 EvolutionSyncConfig(const string &server,
00478 boost::shared_ptr<ConfigTree> tree = boost::shared_ptr<ConfigTree>());
00479
00480
00481
00482
00483
00484 EvolutionSyncConfig();
00485
00486
00487 string getRootPath() const;
00488
00489 typedef list< pair<string, string> > ServerList;
00490
00491
00492
00493
00494
00495
00496 static ServerList getServers();
00497
00498
00499
00500
00501
00502 static ServerList getServerTemplates();
00503
00504
00505
00506
00507
00508
00509
00510
00511 static boost::shared_ptr<EvolutionSyncConfig> createServerTemplate(const string &server);
00512
00513
00514 bool exists() const;
00515
00516
00517 void flush();
00518
00519
00520
00521
00522 static ConfigPropertyRegistry &getRegistry();
00523
00524
00525
00526
00527
00528
00529 virtual void setConfigFilter(bool sync, const FilterConfigNode::ConfigFilter &filter) {
00530 if (sync) {
00531 m_configNode->setFilter(filter);
00532 } else {
00533 m_sourceFilter = filter;
00534 }
00535 }
00536
00537
00538
00539
00540
00541
00542
00543
00544 virtual boost::shared_ptr<FilterConfigNode> getProperties(bool hidden = false) {
00545 if (hidden) {
00546 return boost::shared_ptr<FilterConfigNode>(new FilterConfigNode(m_hiddenNode));
00547 } else {
00548 return m_configNode;
00549 }
00550 }
00551 virtual boost::shared_ptr<const FilterConfigNode> getProperties(bool hidden = false) const { return const_cast<EvolutionSyncConfig *>(this)->getProperties(hidden); }
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567 virtual boost::shared_ptr<PersistentEvolutionSyncSourceConfig> getSyncSourceConfig(const string &name);
00568 virtual boost::shared_ptr<const PersistentEvolutionSyncSourceConfig> getSyncSourceConfig(const string &name) const {
00569 return const_cast<EvolutionSyncConfig *>(this)->getSyncSourceConfig(name);
00570 }
00571
00572
00573
00574
00575 virtual list<string> getSyncSources() const;
00576
00577
00578
00579
00580
00581
00582
00583
00584 SyncSourceNodes getSyncSourceNodes(const string &name,
00585 const string &trackName = "");
00586 ConstSyncSourceNodes getSyncSourceNodes(const string &name,
00587 const string &trackName = "") const;
00588
00589
00590
00591
00592 void setDefaults();
00593
00594
00595
00596
00597 void setSourceDefaults(const string &name);
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613 void copy(const EvolutionSyncConfig &other,
00614 const set<string> *sourceFilter);
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625 virtual const char *getLogDir() const;
00626 virtual void setLogDir(const string &value, bool temporarily = false);
00627
00628 virtual int getMaxLogDirs() const;
00629 virtual void setMaxLogDirs(int value, bool temporarily = false);
00630
00631 virtual int getLogLevel() const;
00632 virtual void setLogLevel(int value, bool temporarily = false);
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645 virtual AbstractSyncSourceConfig* getAbstractSyncSourceConfig(const char* name) const { return NULL; }
00646 virtual AbstractSyncSourceConfig* getAbstractSyncSourceConfig(unsigned int i) const { return NULL; }
00647 virtual unsigned int getAbstractSyncSourceConfigsCount() const { return 0; }
00648
00649 virtual const char* getUsername() const;
00650 virtual void setUsername(const string &value, bool temporarily = false);
00651 virtual const char* getPassword() const;
00652 virtual void setPassword(const string &value, bool temporarily = false);
00653
00654
00655
00656
00657
00658
00659
00660 virtual void checkPassword(ConfigUserInterface &ui);
00661
00662 virtual bool getUseProxy() const;
00663 virtual void setUseProxy(bool value, bool temporarily = false);
00664 virtual const char* getProxyHost() const;
00665 virtual void setProxyHost(const string &value, bool temporarily = false);
00666 virtual int getProxyPort() const { return 0; }
00667 virtual const char* getProxyUsername() const;
00668 virtual void setProxyUsername(const string &value, bool temporarily = false);
00669 virtual const char* getProxyPassword() const;
00670 virtual void checkProxyPassword(ConfigUserInterface &ui);
00671 virtual void setProxyPassword(const string &value, bool temporarily = false);
00672 virtual const char* getSyncURL() const;
00673 virtual void setSyncURL(const string &value, bool temporarily = false);
00674 virtual const char* getClientAuthType() const;
00675 virtual void setClientAuthType(const string &value, bool temporarily = false);
00676 virtual bool getLoSupport() const;
00677 virtual void setLoSupport(bool value, bool temporarily = false);
00678 virtual unsigned long getMaxMsgSize() const;
00679 virtual void setMaxMsgSize(unsigned long value, bool temporarily = false);
00680 virtual unsigned int getMaxObjSize() const;
00681 virtual void setMaxObjSize(unsigned int value, bool temporarily = false);
00682 virtual unsigned long getReadBufferSize() const { return 0; }
00683 virtual const char* getSSLServerCertificates() const;
00684 virtual void setSSLServerCertificates(const string &value, bool temporarily = false);
00685 virtual bool getSSLVerifyServer() const;
00686 virtual void setSSLVerifyServer(bool value, bool temporarily = false);
00687 virtual bool getSSLVerifyHost() const;
00688 virtual void setSSLVerifyHost(bool value, bool temporarily = false);
00689 virtual bool getCompression() const;
00690 virtual void setCompression(bool value, bool temporarily = false);
00691 virtual unsigned int getResponseTimeout() const { return 0; }
00692 virtual const char* getDevID() const;
00693 virtual void setDevID(const string &value, bool temporarily = false);
00694
00695 virtual bool getServerAuthRequired() const { return false; }
00696 virtual const char* getServerAuthType() const { return ""; }
00697 virtual const char* getServerPWD() const { return ""; }
00698 virtual const char* getServerID() const { return ""; }
00699
00700 virtual const char* getUserAgent() const { return "SyncEvolution"; }
00701 virtual const char* getVerDTD() const { return "1.1"; }
00702 virtual const char* getMan() const { return "Patrick Ohly"; }
00703 virtual const char* getMod() const { return "SyncEvolution"; }
00704 virtual const char* getOem() const { return "Open Source"; }
00705 virtual const char* getFwv() const { return ""; }
00706 virtual const char* getHwv() const { return ""; }
00707 virtual const char* getDsV() const { return ""; }
00708 virtual const char* getSwv() const;
00709 virtual const char* getDevType() const;
00710
00711 virtual bool getUtc() const { return true; }
00712 virtual bool getNocSupport() const { return false; }
00713
00714 virtual const char* getServerNonce() const;
00715 virtual void setServerNonce(const char *value);
00716 virtual const char* getClientNonce() const;
00717 virtual void setClientNonce(const char *value);
00718 virtual const char* getDevInfHash() const;
00719 virtual void setDevInfHash(const char *value);
00720
00721
00722
00723 private:
00724 string m_server;
00725 bool m_oldLayout;
00726 string m_cachedPassword;
00727 string m_cachedProxyPassword;
00728
00729
00730 boost::shared_ptr<ConfigTree> m_tree;
00731
00732
00733 boost::shared_ptr<FilterConfigNode> m_configNode;
00734 boost::shared_ptr<ConfigNode> m_hiddenNode;
00735
00736
00737 FilterConfigNode::ConfigFilter m_sourceFilter;
00738
00739 mutable ConfigStringCache m_stringCache;
00740
00741 static string getHome() {
00742 const char *homestr = getenv("HOME");
00743 return homestr ? homestr : ".";
00744 }
00745
00746 static string getOldRoot() {
00747 return getHome() + "/.sync4j/evolution";
00748 }
00749
00750 static string getNewRoot() {
00751 const char *xdg_root_str = getenv("XDG_CONFIG_HOME");
00752 return xdg_root_str ? string(xdg_root_str) + "/syncevolution" :
00753 getHome() + "/.config/syncevolution";
00754 }
00755 };
00756
00757
00758
00759
00760
00761 struct SyncSourceNodes {
00762
00763
00764
00765
00766
00767
00768
00769 SyncSourceNodes(const boost::shared_ptr<FilterConfigNode> &configNode,
00770 const boost::shared_ptr<ConfigNode> &hiddenNode,
00771 const boost::shared_ptr<ConfigNode> &trackingNode) :
00772 m_configNode(configNode),
00773 m_hiddenNode(hiddenNode),
00774 m_trackingNode(trackingNode)
00775 {}
00776
00777 const boost::shared_ptr<FilterConfigNode> m_configNode;
00778 const boost::shared_ptr<ConfigNode> m_hiddenNode;
00779 const boost::shared_ptr<ConfigNode> m_trackingNode;
00780 };
00781
00782 struct ConstSyncSourceNodes {
00783 ConstSyncSourceNodes(const boost::shared_ptr<const FilterConfigNode> &configNode,
00784 const boost::shared_ptr<const ConfigNode> &hiddenNode,
00785 const boost::shared_ptr<const ConfigNode> &trackingNode) :
00786 m_configNode(configNode),
00787 m_hiddenNode(hiddenNode),
00788 m_trackingNode(trackingNode)
00789 {}
00790
00791 ConstSyncSourceNodes(const SyncSourceNodes &other) :
00792 m_configNode(other.m_configNode),
00793 m_hiddenNode(other.m_hiddenNode),
00794 m_trackingNode(other.m_trackingNode)
00795 {}
00796
00797 const boost::shared_ptr<const FilterConfigNode> m_configNode;
00798 const boost::shared_ptr<const ConfigNode> m_hiddenNode;
00799 const boost::shared_ptr<const ConfigNode> m_trackingNode;
00800 };
00801
00802
00803
00804
00805
00806
00807
00808 class EvolutionSyncSourceConfig : public AbstractSyncSourceConfig {
00809 public:
00810 EvolutionSyncSourceConfig(const string &name, const SyncSourceNodes &nodes);
00811
00812 static ConfigPropertyRegistry &getRegistry();
00813
00814
00815 static StringConfigProperty m_sourcePropSync;
00816
00817 bool exists() const { return m_nodes.m_configNode->exists(); }
00818
00819
00820
00821
00822
00823
00824 virtual const char *getUser() const;
00825 virtual void setUser(const string &value, bool temporarily = false);
00826
00827 const char *getPassword() const;
00828 virtual void setPassword(const string &value, bool temporarily = false);
00829
00830
00831 virtual void checkPassword(ConfigUserInterface &ui);
00832
00833 virtual const char *getDatabaseID() const;
00834 virtual void setDatabaseID(const string &value, bool temporarily = false);
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847 static pair<string, string> getSourceType(const SyncSourceNodes &nodes);
00848 static string getSourceTypeString(const SyncSourceNodes &nodes);
00849 virtual pair<string, string> getSourceType() const;
00850
00851
00852 virtual void setSourceType(const string &value, bool temporarily = false);
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866 virtual const char *getMimeType() const = 0;
00867
00868
00869
00870
00871
00872 virtual const char *getMimeVersion() const = 0;
00873
00874
00875
00876
00877
00878
00879
00880
00881 virtual const char* getSupportedTypes() const = 0;
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898 virtual const char* getURI() const;
00899 virtual void setURI(const string &value, bool temporarily = false);
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917 virtual const char* getSyncModes() const { return "slow,two-way,one-way-from-server,one-way-from-client,refresh-from-server,refresh-from-client"; }
00918
00919
00920
00921
00922 virtual const char* getSync() const;
00923 virtual void setSync(const string &value, bool temporarily = false);
00924
00925
00926
00927
00928
00929
00930
00931 virtual const char* getEncoding() const;
00932 virtual void setEncoding(const string &value, bool temporarily = false);
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945 virtual unsigned long getLast() const;
00946 virtual void setLast(unsigned long timestamp);
00947
00948
00949
00950
00951
00952
00953 virtual const char* getEncryption() const { return ""; }
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964 virtual const ArrayList& getCtCaps() const { static const ArrayList dummy; return dummy; }
00965
00966
00967
00968
00969
00970
00971
00972 virtual const char *getType() const { return getMimeType(); }
00973 virtual const char *getVersion() const { return getMimeVersion(); }
00974 virtual const char* getName() const { return m_name.c_str(); }
00975
00976
00977 private:
00978 string m_name;
00979 SyncSourceNodes m_nodes;
00980 mutable ConfigStringCache m_stringCache;
00981 string m_cachedPassword;
00982 };
00983
00984
00985
00986
00987
00988 class PersistentEvolutionSyncSourceConfig : public EvolutionSyncSourceConfig {
00989 public:
00990 PersistentEvolutionSyncSourceConfig(const string &name, const SyncSourceNodes &nodes) :
00991 EvolutionSyncSourceConfig(name, nodes) {}
00992
00993 virtual const char* getMimeType() const { return ""; }
00994 virtual const char* getMimeVersion() const { return ""; }
00995 virtual const char* getSupportedTypes() const { return ""; }
00996 };
00997
00998
00999
01000 #endif