2 * Copyright (C) 2008-2009 Patrick Ohly <patrick.ohly@gmx.de>
3 * Copyright (C) 2009 Intel Corporation
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) version 3.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 #include <syncevo/ConfigFilter.h>
24 #include <syncevo/SyncConfig.h>
30 void ConfigProps::add(const ConfigProps &other)
32 BOOST_FOREACH(const ConfigProps::value_type &entry, other) {
33 std::pair<iterator, bool> res = insert(entry);
35 res.first->second = entry.second;
40 InitStateString ConfigProps::get(const string &key, const string &def) const
42 const_iterator it = find(key);
44 return InitStateString(def, false);
50 ConfigProps::operator string () const
53 BOOST_FOREACH(const StringPair &filter, *this) {
54 res.push_back(filter.first + " = " + filter.second);
56 sort(res.begin(), res.end());
57 return boost::join(res, "\n");
60 ConfigProps SourceProps::createSourceFilter(const std::string &source) const
62 const_iterator it = find("");
67 if (!source.empty()) {
70 filter.add(it->second);
76 ConfigProps FullProps::createSyncFilter(const std::string &config) const
78 const_iterator it = find("");
81 // first unset context
82 filter = it->second.m_syncProps;
85 if (!config.empty()) {
86 std::string normal = SyncConfig::normalizeConfigString(config, SyncConfig::NORMALIZE_LONG_FORMAT);
87 std::string peer, context;
88 SyncConfig::splitConfigString(normal, peer, context);
89 // then overwrite with context config
90 it = find(std::string("@") + context);
92 filter.add(it->second.m_syncProps);
94 // finally peer config, if we have one
98 filter.add(it->second.m_syncProps);
105 ConfigProps FullProps::createSourceFilter(const std::string &config,
106 const std::string &source) const
108 const_iterator it = find("");
111 // first unset context
112 filter = it->second.m_sourceProps.createSourceFilter(source);
115 if (!config.empty()) {
116 std::string normal = SyncConfig::normalizeConfigString(config, SyncConfig::NORMALIZE_LONG_FORMAT);
117 std::string peer, context;
118 SyncConfig::splitConfigString(normal, peer, context);
119 // then overwrite with context config
120 it = find(std::string("@") + context);
122 filter.add(it->second.m_sourceProps.createSourceFilter(source));
124 // finally peer config, if we have one
128 filter.add(it->second.m_sourceProps.createSourceFilter(source));
135 bool FullProps::hasProperties(PropCheckMode mode) const
137 BOOST_FOREACH(const value_type &context, *this) {
138 if (mode == CHECK_ALL &&
139 !context.second.m_syncProps.empty()) {
142 if (mode == IGNORE_GLOBAL_PROPS) {
143 const ConfigPropertyRegistry ®istry = SyncConfig::getRegistry();
144 BOOST_FOREACH(const StringPair &entry, context.second.m_syncProps) {
145 const ConfigProperty *prop = registry.find(entry.first);
147 prop->getSharing() != ConfigProperty::GLOBAL_SHARING) {
152 BOOST_FOREACH(const SourceProps::value_type &source, context.second.m_sourceProps) {
153 if (!source.second.empty()) {
162 void FullProps::createFilters(const string &context,
163 const string &config,
164 const set<string> *sources,
165 ConfigProps &syncFilter,
166 SourceProps &sourceFilters)
168 boost::shared_ptr<SyncConfig> shared;
170 if (!context.empty()) {
171 // Read from context. If it does not exist, we simply set no properties
172 // as filter. Previously there was a check for existance, but that was
173 // flawed because it ignored the global property "defaultPeer".
174 shared.reset(new SyncConfig(context));
175 shared->getProperties()->readProperties(syncFilter);
178 // add command line filters for context or config?
179 if (!context.empty()) {
180 syncFilter.add(createSyncFilter(context));
181 // default for (so far) unknown sources which might be created
182 sourceFilters[""].add(createSourceFilter(context, ""));
184 if (!config.empty()) {
185 syncFilter.add(createSyncFilter(config));
186 sourceFilters[""].add(createSourceFilter(config, ""));
189 // build full set of all sources
190 set<string> allSources;
192 allSources = *sources;
195 std::list<std::string> tmp = shared->getSyncSources();
196 allSources.insert(tmp.begin(), tmp.end());
198 if (!config.empty()) {
199 std::list<std::string> tmp = SyncConfig(config).getSyncSources();
200 allSources.insert(tmp.begin(), tmp.end());
203 // explicit filter for all known sources
204 BOOST_FOREACH(std::string source, allSources) {
205 ConfigProps &props = sourceFilters[source];
207 // combine existing properties from context and command line
209 SyncSourceNodes nodes = shared->getSyncSourceNodes(source, "");
210 nodes.getProperties()->readProperties(props);
212 // Special case "type" property: the value in the context
213 // is not preserved. Every new peer must ensure that
214 // its own value is compatible (= same backend) with
218 props.add(createSourceFilter(context, source));
220 if (!config.empty()) {
221 props.add(createSourceFilter(config, source));