Loading...
Searching...
No Matches
UtilsXML.h
1/*
2
3MIT License
4
5Copyright (c) 2017 FMI Open Development / Markus Peura, first.last@fmi.fi
6
7Permission is hereby granted, free of charge, to any person obtaining a copy
8of this software and associated documentation files (the "Software"), to deal
9in the Software without restriction, including without limitation the rights
10to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11copies of the Software, and to permit persons to whom the Software is
12furnished to do so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in all
15copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24
25 */
26/*
27Part of Rack development has been done in the BALTRAD projects part-financed
28by the European Union (European Regional Development Fund and European
29Neighbourhood Partnership Instrument, Baltic Sea Region Programme 2007-2013)
30 */
31/*
32 * UtilsXML.h
33 *
34 * Author: mpeura
35 */
36
37#ifndef DRAIN_UTILS_XML
38#define DRAIN_UTILS_XML
39
40#include "XML.h"
41
42#include "SelectorXML.h" // Only for StyleUtils :-/
43
44
45namespace drain {
46
47
49class UtilsXML {
50
51public:
52
53
55
58 template <typename T>
59 static inline
60 T & assign(T & dst, const T & src){
61
62 if (&src != &dst){
63 dst.clear(); // clears children...
64 // ... but not copying src? (TreeUtils?)
65 // also dst->clear();
66 assignNode(dst.data, src); // removed - so is this polymorphic method ever used.
67 }
68
69 return dst;
70 }
71
73
76 template <typename TX>
77 static inline
78 TX & assign(TX & dst, const typename TX::xml_node_t & src){
79 assignNode(dst.data, src);
80 return dst;
81 }
82
83
85
88 template <typename T, typename V>
89 static inline
90 T & assign(T & tree, const V & arg){
91 tree->set(arg);
92 return tree;
93 }
94
96
99 template <typename T>
100 static
101 //T & assign(T & tree, std::initializer_list<std::pair<const char *,const char *> > l){
102 T & assign(T & tree, std::initializer_list<std::pair<const char *,const Variable> > l){
103
104 //switch (static_cast<intval_t>(tree->getType())){
105 switch (tree->getType()){
106 case XML::STYLE:
107 for (const auto & entry: l){
108 T & elem = tree[entry.first];
109 elem->setType(XML::STYLE_SELECT);
110 drain::MapTools::setValues(elem->getAttributes(), entry.second, ';', ':', std::string(" \t\n"));
111 }
112 break;
113 case XML::UNDEFINED:
114 tree->setType(XML::STYLE_SELECT);
115 // no break
116 case XML::STYLE_SELECT:
117 default:
118 tree->set(l);
119 break;
120 }
121
122 return tree;
123 };
124
125 // UNDER CONSTRUCTION!
127
132 template <typename TX>
133 static inline // NOT YET as template specification of assign(...)
134 TX & assignString(TX & tree, const std::string & s){
135 if (tree->isUndefined()){
136 tree->setType(XML::CTEXT);
137 }
138 tree->ctext = s;
139 return tree;
140 }
141
142 template <typename TX>
143 static inline // NOT YET as template specification of assign(...)
144 TX & appendString(TX & tree, const std::string & s){
145 if (tree->isCText()){
146 tree->ctext += s;
147 return tree;
148 }
149 else if (tree->isUndefined()){
150 tree->setType(XML::CTEXT);
151 // tree->setText(s);
152 tree->ctext += s;
153 return tree;
154 }
155 else {
156 // drain::Logger(__FILE__, __FUNCTION__).error("Assign string...");
157 TX & child = tree.addChild();
158 child->setType(XML::CTEXT);
159 child->setText(s);
160 return child;
161 }
162 }
163
164
166
170 template <typename TX>
171 static inline
172 TX & setType(TX & tree, const typename TX::node_data_t::xml_tag_t & type){
173 tree->setType(type);
174 return tree;
175 }
176
177
179
182 template <typename N>
183 static
184 typename N::xml_tag_t retrieveDefaultType(const N & parentNode){
185 typedef typename N::xml_default_elem_map_t map_t;
186 const typename map_t::const_iterator it = N::xml_default_elems.find(parentNode.getNativeType());
187 if (it != N::xml_default_elems.end()){
188 return (it->second);
189 }
190 else {
191 return static_cast<typename N::xml_tag_t>(0);
192 }
193 }
194
195 template <typename T>
196 static
197 bool initChildWithDefaultType(const T & tree, T & child){
198 typename T::node_data_t::xml_tag_t type = retrieveDefaultType(tree.data);
199 if (static_cast<int>(type) != 0){
200 child->setType(type);
201 return true;
202 }
203 else {
204 return false;
205 }
206 }
207
208 template <typename T>
209 static
210 T & getHeaderObject(T & root, typename T::node_data_t::xml_tag_t tag, const typename T::path_elem_t & key = typename T::path_elem_t()){
211
212 const typename T::path_elem_t & finalKey = !key.empty() ? key : Enum<typename T::node_data_t::xml_tag_t>::getKey(tag);
213
214 if (!root.hasChild(finalKey)){
215 T & child = root.prependChild(finalKey); // consider path type! getDefaultObject
216 child->setType(tag);
217 return child;
218 }
219 else {
220 return root[finalKey];
221 }
222 };
223
224 template <typename T>
225 static
226 T & ensureStyle(T & root, const SelectXML<typename T::node_data_t::xml_tag_t> & selector, const std::initializer_list<std::pair<const char *,const Variable> > & styleDef){
227
228 T & style = getHeaderObject(root, T::node_data_t::xml_tag_t::STYLE);
229
230 T & styleEntry = style[selector];
231 if (styleEntry.empty()){
232 styleEntry = styleDef;
233 // styleEntry->setStyle(styleDef); WRONG (did not work)
234 }
235 return styleEntry;
236 }
237
241 template <typename N, typename ...TT>
242 static
243 UnorderedMultiTree<N> & ensureJavaScriptFunction(UnorderedMultiTree<N> & root, const std::string & name, const TT & ...args){
244
245 typedef UnorderedMultiTree<N> T;
246 T & jsFunction = getHeaderObject(root, T::node_data_t::xml_tag_t::SCRIPT, name);
247
248 if (jsFunction.empty()){
249 jsFunction->setText("function ", name, '(', args..., ')');
250 }
251
252 return jsFunction; // [XML::JAVASCRIPT_SCOPE];
253 }
254
258 template <typename N>
259 static
260 UnorderedMultiTree<N> & ensureJavaScriptUrl(UnorderedMultiTree<N> & root, const std::string & url){
261
262 drain::Logger mout(__FILE__, __FUNCTION__);
263
264 typedef UnorderedMultiTree<N> T;
265
266 std::string id(url);
267 for (auto & c : id){
268 // drain::PathSeparatorPolicy
269 if (c == T::path_t::separator.character){
270 c = '|';
271 }
272 }
273 mout.note("mapped id:", id);
274
275 T & treeJS = getHeaderObject(root, T::node_data_t::xml_tag_t::SCRIPT, id);
276
277 treeJS->setUrl(url);
278
279 return treeJS; // [XML::JAVASCRIPT_SCOPE];
280 }
281
282
283};
284
285
286
287} // drain::
288
289#endif /* DRAIN_XML */
290
291/*
292template <typename T>
293static
294T & xmlGuessType(const typename T::node_data_t & parentNode, T & child){
295 typedef typename T::node_data_t::xml_default_elem_map_t map_t;
296 const typename map_t::const_iterator it = T::node_data_t::xml_default_elems.find(parentNode.getNativeType());
297 if (it != T::node_data_t::xml_default_elems.end()){
298 child->setType(it->second);
299 drain::Logger(__FILE__, __FUNCTION__).experimental<LOG_WARNING>("Default type set: ", child->getTag());
300 }
301 return child;
302}
303*/
304
306
338/*
339template <typename T>
340static
341T & addChild(T & tree){
342 typename T::node_data_t::xml_tag_t type = retrieveDefaultType(tree.data);
343 std::stringstream k; // ("elem");
344 k << "elem"; // number with 4 digits overwrites this?
345 k.width(3); // consider static member prefix
346 k.fill('0');
347 k << tree.getChildren().size();
348 return tree[k.str()](type);
349}
350
351template <typename T>
352static
353T & addChild(T & tree, const std::string & key){
354
355 if (!key.empty()){
356 typename T::node_data_t::xml_tag_t type = xmlRetrieveDefaultType(tree.data);
357 return tree[key](type);
358 }
359 else {
360 return addChild(tree);
361 }
362}
363*/
364
365
366// TX & xmlAppendString(TX & tree, const std::string & s){
367/*
368template <class V>
369static inline
370void attribToStream(std::ostream &ostr, const std::string & key, const V &value){
371 //StringTools::replace(XML::encodingMap, data.ctext, ostr);
372 //ostr << ' ' << key << '=' << '"' << value << '"'; // << ' ';
373
374 static const std::map<char,char> keyMap = {
375 {' ','_'},
376 {'"','_'},
377 {'=','_'},
378 };
379 ostr << ' ';
380 StringTools::replace(key, keyMap, ostr); // XML::encodingMap
381 //StringTools::replace(getEntityMap(), key, ostr); // XML::encodingMap
382
383 static const std::map<char,std::string> valueMap = {
384 {XML::entity_t::QUOTE, "'"},
385 {XML::entity_t::LESS_THAN,"(("},
386 {XML::entity_t::GREATER_THAN,"))"},
387 };
388 ostr << '=' << '"';
389 StringTools::replace(value, valueMap, ostr); // XML::encodingMap
390 //StringTools::replace(getEntityMap(), value, ostr); // XML::encodingMap
391 ostr << '"';
392 //<< key << '=' << '"' << value << '"'; // << ' ';
393}
394*/
395
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition Log.h:313
Logger & note(const TT &... args)
For top-level information.
Definition Log.h:490
static void setValues(M &dst, const std::map< std::string, S > &srcMap)
Definition MapTools.h:213
Base class for XML "nodes", to be data elements T for drain::Tree<T>
Definition UtilsXML.h:49
static T & assign(T &tree, std::initializer_list< std::pair< const char *, const Variable > > l)
Tree.
Definition UtilsXML.h:102
static T & assign(T &tree, const V &arg)
Assign property to a XML tree node.
Definition UtilsXML.h:90
static T & assign(T &dst, const T &src)
Assign another tree structure to another.
Definition UtilsXML.h:60
static N::xml_tag_t retrieveDefaultType(const N &parentNode)
Find node type (tag id) from a predefined list of default types for (some) parent types.
Definition UtilsXML.h:184
static TX & setType(TX &tree, const typename TX::node_data_t::xml_tag_t &type)
Definition UtilsXML.h:172
static TX & assign(TX &dst, const typename TX::xml_node_t &src)
Copy node data to tree.
Definition UtilsXML.h:78
static TX & assignString(TX &tree, const std::string &s)
When assigning a string, create new element unless the element itself is of type CTEXT.
Definition UtilsXML.h:134
static UnorderedMultiTree< N > & ensureJavaScriptUrl(UnorderedMultiTree< N > &root, const std::string &url)
Definition UtilsXML.h:260
Definition DataSelector.cpp:1277
static const std::string & getKey(const std::string &s, bool lenient=true)
Convenience for object.set(...) like commands.
Definition Enum.h:144